4

問題

Windows APIを使用してWindowsサービスを制御したいのですが、できません:(

= 私の「希望する解決策」の何が問題になっていますか?

現在のソリューション

私が使用する最も醜いが機能的な方法は次のとおりです(Stopコマンド用):

void StopService()
{
    ShellExecute(Application->Handle,
                 "open",
                 "stop.bat",
                 NULL,
                 ExtractFilePath(Application->ExeName).c_str(),
                 SW_SHOW);
}

stop.bat次のコマンドを含む Windows バッチ ファイルはどこにありますか。

::the command
sc stop "service name"
::a pause to see if something goes wrong
pause

起動した cmd ウィンドウを閉じなければならないのは非常に面倒です...

ソリューションを求める

以下の機能は問題ないようです。存在しないサービスを停止するコマンドを実行しようとすると、エラー メッセージが表示されます。しかし、既存のサービスに対して実行しようとすると、実行されますが、サービスには何も起こりません(停止するように指定しても、何もしません)...

void ControlService(AnsiString ServiceName, DWORD Order)
{
    SC_HANDLE Scm, Svc;
    SERVICE_STATUS Status;

    Scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

    if(Scm != 0)
    {
        Svc = OpenService(Scm, PChar(ServiceName.c_str()), SERVICE_ALL_ACCESS);

        if(Svc != 0)
        {
            ControlService(Svc, Order, &Status);

            // handle Status....
            CloseServiceHandle(Svc);
        }
        else
        {
            ShowLastError();
        }
        CloseServiceHandle(Scm);
    }
    else
    {
        ShowLastError();
    }
}

void ShowLastError()
{
    LPVOID lpMsgBuf;

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL
    );

    // Display the string.
    MessageBox(NULL, (char*)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION);

    // Free the buffer.
    LocalFree(lpMsgBuf);
}

どうしたの?????

4

1 に答える 1

4

次の 2 つの問題が発生する可能性があります。

  1. サービスの状態を確認するのが早すぎます。ServiceControl は、サービスが要求を完了するのを待たずに、すぐに戻ります。サービスが SERVICE_STOP_PENDING に移行する可能性があります。この場合、しばらく時間をおいてから再度確認する必要があります。
  2. 実行状態の依存サービスがあります。依存するサービスを列挙し、最初にそれらをシャットダウンしてから、サービスを停止する必要があります。

#2 については、MSDNのサンプル コードで適切な説明があります。以下は同ページからの引用です。

ただし、他の実行中のサービスが指定されたサービスに依存していると SCM が判断した場合、SCM は停止要求を転送しません。代わりに、ERROR_DEPENDENT_SERVICES_RUNNING を返します。したがって、このようなサービスをプログラムで停止するには、まず依存サービスを列挙して停止する必要があります。

于 2013-06-03T14:55:36.230 に答える