0

Process Hacker が示すように、デフォルトは 180000 であるためQueryServiceStatus、現在のサービス ステータスを取得するために使用し、後で 0 に設定します。waitHintそして、私はのような他のものを変更したいと思いcontrolsAcceptedます。QueryServiceStatus正常に動作しますが、SetServiceStatusfalse を返し、Marshal.GetLastWin32Error役に立ちません。これは ERROR_ALREADY_EXISTS (そのファイルが既に存在する場合、ファイルを作成できません) である 183 を返します。これは、コンピューターで実行されている別のアプリケーションからのものであると想定しているためです。

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() : ""));

SetServiceStatusSERVICE_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失敗します。ドキュメントをもう一度見てください。あなたは a を渡すことになってSERVICE_STATUS_HANDLEいますが、 a を渡しますSC_HANDLE

SetServiceStatusQueryServiceStatusさまざまな種類のハンドルを受け取ります。そして、あなたは間違ったものを渡しています。のドキュメントにSetServiceStatusは、渡す必要があると書かれています:

現在のサービスのステータス情報構造へのハンドル。このハンドルは、RegisterServiceCtrlHandlerEx 関数によって返されます。

于 2013-06-06T15:57:17.370 に答える