0

QueryServiceStatus用来接收当前服务状态,后来将其设置waitHint为 0,因为 Process Hacker 显示默认值为 180000。我想改变其他的东西,比如controlsAccepted. QueryServiceStatus工作正常,但SetServiceStatus返回 false,并Marshal.GetLastWin32Error没有帮助。它返回 183,即 ERROR_ALREADY_EXISTS(当该文件已存在时无法创建文件。)因为我假设这是来自我计算机上运行的另一个应用程序。

IntPtr scm = WinAPI.Service.OpenSCManager(null, null, WinAPI.Service.SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
IntPtr service = WinAPI.Service.OpenService(scm, "mySvc", WinAPI.Service.SERVICE_ACCESS.SERVICE_ALL_ACCESS);
var lpServiceStatus = new WinAPI.Service.SERVICE_STATUS();
bool queryStatus = WinAPI.Service.QueryServiceStatus(service, ref lpServiceStatus);
Svc.debugWr("queryStatus: " + queryStatus + (!queryStatus ? "LastWin32Error: " + Marshal.GetLastWin32Error() : ""));
Svc.debugWr("checkPoint: " + lpServiceStatus.checkPoint);
Svc.debugWr("controlsAccepted: " + lpServiceStatus.controlsAccepted);
Svc.debugWr("currentState" + lpServiceStatus.currentState);
Svc.debugWr("exit code: " + lpServiceStatus.serviceSpecificExitCode);
Svc.debugWr("serviceType: " + lpServiceStatus.serviceType);
Svc.debugWr("Wait hint: " + lpServiceStatus.waitHint);
Svc.debugWr("Win32 exit code: " + lpServiceStatus.win32ExitCode);
lpServiceStatus.waitHint = 0;
Svc.debugWr("Wait hint: " + lpServiceStatus.waitHint);
bool setStatus = WinAPI.Service.SetServiceStatus(service, ref lpServiceStatus);
Svc.debugWr("setStatus: " + setStatus + (!setStatus ? "LastWin32Error: " + Marshal.GetLastWin32Error() : ""));

这是SetServiceStatus,SERVICE_STATUS和的声明QueryServiceStatus

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool SetServiceStatus(IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool QueryServiceStatus(IntPtr hService, ref SERVICE_STATUS dwServiceStatus);
[StructLayout(LayoutKind.Sequential)]
public struct SERVICE_STATUS {
    public int serviceType;
    public int currentState;
    public int controlsAccepted;
    public int win32ExitCode;
    public int serviceSpecificExitCode;
    public int checkPoint;
    public int waitHint;
}
4

1 回答 1

1

没有返回有意义的值的原因GetLastWin32Error()是您的 p/invoke 声明没有告诉框架记住最后一个错误代码。你需要这样的声明:

[DllImport("advapi32.dll", SetLastError=true)]
....

调用SetServiceStatus失败,因为您传入第​​一个参数的句柄确实无效。再次查看文档。你应该通过 aSERVICE_STATUS_HANDLE但你通过了 a SC_HANDLE

SetServiceStatusQueryServiceStatus接收不同类型的句柄。而你传递的是错误的。的文档SetServiceStatus说您需要通过:

当前服务的状态信息结构的句柄。此句柄由 RegisterServiceCtrlHandlerEx 函数返回。

于 2013-06-06T15:57:17.370 回答