mirror of https://github.com/winsw/winsw
Fix the stop logic
parent
9d7adbf70e
commit
08c836ccc5
|
@ -117,9 +117,9 @@ namespace WinSW.Native
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <exception cref="CommandException" />
|
/// <exception cref="CommandException" />
|
||||||
internal Service OpenService(string serviceName)
|
internal Service OpenService(string serviceName, ServiceAccess access = ServiceAccess.ALL_ACCESS)
|
||||||
{
|
{
|
||||||
IntPtr serviceHandle = ServiceApis.OpenService(this.handle, serviceName, ServiceAccess.ALL_ACCESS);
|
IntPtr serviceHandle = ServiceApis.OpenService(this.handle, serviceName, access);
|
||||||
if (serviceHandle == IntPtr.Zero)
|
if (serviceHandle == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Throw.Command.Win32Exception("Failed to open the service.");
|
Throw.Command.Win32Exception("Failed to open the service.");
|
||||||
|
@ -171,6 +171,24 @@ namespace WinSW.Native
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <exception cref="CommandException" />
|
||||||
|
internal void SetStatus(IntPtr statusHandle, ServiceControllerStatus state)
|
||||||
|
{
|
||||||
|
if (!QueryServiceStatus(this.handle, out SERVICE_STATUS status))
|
||||||
|
{
|
||||||
|
Throw.Command.Win32Exception("Failed to query service status.");
|
||||||
|
}
|
||||||
|
|
||||||
|
status.CheckPoint = 0;
|
||||||
|
status.WaitHint = 0;
|
||||||
|
status.CurrentState = state;
|
||||||
|
|
||||||
|
if (!SetServiceStatus(statusHandle, status))
|
||||||
|
{
|
||||||
|
Throw.Command.Win32Exception("Failed to set service status.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <exception cref="CommandException" />
|
/// <exception cref="CommandException" />
|
||||||
internal void Delete()
|
internal void Delete()
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace WinSW.Native
|
||||||
[DllImport(Libraries.Advapi32, SetLastError = true)]
|
[DllImport(Libraries.Advapi32, SetLastError = true)]
|
||||||
internal static extern bool SetServiceObjectSecurity(IntPtr serviceHandle, SecurityInfos securityInformation, byte[] securityDescriptor);
|
internal static extern bool SetServiceObjectSecurity(IntPtr serviceHandle, SecurityInfos securityInformation, byte[] securityDescriptor);
|
||||||
|
|
||||||
[DllImport(Libraries.Advapi32)]
|
[DllImport(Libraries.Advapi32, SetLastError = true)]
|
||||||
internal static extern bool SetServiceStatus(IntPtr serviceStatusHandle, in SERVICE_STATUS serviceStatus);
|
internal static extern bool SetServiceStatus(IntPtr serviceStatusHandle, in SERVICE_STATUS serviceStatus);
|
||||||
|
|
||||||
// SERVICE_
|
// SERVICE_
|
||||||
|
@ -152,7 +152,7 @@ namespace WinSW.Native
|
||||||
|
|
||||||
internal struct SERVICE_STATUS
|
internal struct SERVICE_STATUS
|
||||||
{
|
{
|
||||||
public int ServiceType;
|
public ServiceType ServiceType;
|
||||||
public ServiceControllerStatus CurrentState;
|
public ServiceControllerStatus CurrentState;
|
||||||
public int ControlsAccepted;
|
public int ControlsAccepted;
|
||||||
public int Win32ExitCode;
|
public int Win32ExitCode;
|
||||||
|
|
|
@ -17,8 +17,6 @@ namespace WinSW
|
||||||
{
|
{
|
||||||
public class WrapperService : ServiceBase, IEventLogger
|
public class WrapperService : ServiceBase, IEventLogger
|
||||||
{
|
{
|
||||||
private ServiceApis.SERVICE_STATUS wrapperServiceStatus;
|
|
||||||
|
|
||||||
private readonly Process process = new Process();
|
private readonly Process process = new Process();
|
||||||
private readonly ServiceDescriptor descriptor;
|
private readonly ServiceDescriptor descriptor;
|
||||||
private Dictionary<string, string>? envs;
|
private Dictionary<string, string>? envs;
|
||||||
|
@ -415,13 +413,12 @@ namespace WinSW
|
||||||
this.RequestAdditionalTime(serviceWaitHint);
|
this.RequestAdditionalTime(serviceWaitHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SignalShutdownComplete()
|
private void SignalStopped()
|
||||||
{
|
{
|
||||||
IntPtr handle = this.ServiceHandle;
|
using ServiceManager scm = ServiceManager.Open();
|
||||||
this.wrapperServiceStatus.CheckPoint++;
|
using Service sc = scm.OpenService(this.ServiceName, ServiceApis.ServiceAccess.QUERY_STATUS);
|
||||||
// WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
|
|
||||||
this.wrapperServiceStatus.CurrentState = ServiceControllerStatus.Stopped;
|
sc.SetStatus(this.ServiceHandle, ServiceControllerStatus.Stopped);
|
||||||
ServiceApis.SetServiceStatus(handle, this.wrapperServiceStatus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartProcess(Process processToStart, string arguments, string executable, LogHandler? logHandler, bool redirectStdin)
|
private void StartProcess(Process processToStart, string arguments, string executable, LogHandler? logHandler, bool redirectStdin)
|
||||||
|
@ -442,12 +439,17 @@ namespace WinSW
|
||||||
// if we finished orderly, report that to SCM.
|
// if we finished orderly, report that to SCM.
|
||||||
// by not reporting unclean shutdown, we let Windows SCM to decide if it wants to
|
// by not reporting unclean shutdown, we let Windows SCM to decide if it wants to
|
||||||
// restart the service automatically
|
// restart the service automatically
|
||||||
if (process.ExitCode == 0)
|
try
|
||||||
{
|
{
|
||||||
this.SignalShutdownComplete();
|
if (process.ExitCode == 0)
|
||||||
|
{
|
||||||
|
this.SignalStopped();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Environment.Exit(process.ExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment.Exit(process.ExitCode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue