Windowsサービスに、独自のサービスコントロール(SC)を送る

もくじ
https://tera1707.com/entry/2022/02/06/144447

やりたいこと

以前の記事で、サービスを作ったのだが、 SERVICE_CONTROL_PAUSESERVICE_CONTROL_STOPなどの元からあるサービスコトロールではなく、 自分で定義した独自のSCを受け付けたい。

とりあえず、管理者コマンドプロンプトで 'sc control サービス名 SC番号' で独自のSCを送れるようなので、それを受け取れるようにしたい。

やったこと

サービス側のコードとしては、なんのことはない、以前のサービス実験コードのSCを受ける部分に、case文を一個追加するだけ。

以下、そこだけ抜粋

// ServiceControlがSCMから送られてくるたびに呼ばれる
DWORD WINAPI SvcCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
    switch (dwControl)
    {
    case SERVICE_CONTROL_STOP:
        ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
        // サービス停止シグナルを送る
        SetEvent(ghSvcStopEvent);
        // 停止を報告
        ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
        return NO_ERROR;

    case SERVICE_CONTROL_INTERROGATE:
        return NO_ERROR;

    case 200: // ★これがそう
        OutputLogToCChokka(L" 独自SC来ました");
        break;

    default:
        break;
    }

    return NO_ERROR;
}

今回追記したのは case 200: の部分だけ。これで受け取り部分は完成。

SCを送る側は、管理者でコマンドプロンプトを立ち上げて、 'sc control SvcName 200' と打ち込んで実行すれば、200番のSCが飛んでくれる。

ただ、今回、ここで大変苦労した。

独自SCは、128~255 の範囲でないといけないらしい。

なのに、最初 case 666: 、 'sc control SvcName 666' とか、100番など、範囲外の番号を使ってしまっていて、sc controlのコマンドが下記のようにエラーを出して困った。

範囲内の番号を使うことで、うまくSCを投げる/受け取ることができた。

参考

以前調べた、C++でのサービスの作り方

https://qiita.com/tera1707/items/dc24ac78ae76906abb83

SCは、128~255の範囲でしか使えないというのを知ったページ。

https://www.tokovalue.jp/function/ControlService.htm