サービスプログラムの操作

サービスプログラムの停止や起動など、サービスプログラムをコントロールしたいケースがあって作ったサブルーチンを上げておきます。
クラス化はしておりません。ただのサブルーチンです。

strNAMEというAnsiStringの変数にサービス名が入っている場合、「subStartService?(strNAME.c_str(), NULL);」などと使ってください。
APIに「実行先マシン名」を指定するところがあったのでそのまま引数に取ってますが、リモートマシンのサービスコントロールを行った実績はありません。動くのかどうか不明です。(確かめるつもりも今のところないです。)

subSERVICE.h

//---------------------------------------------------------------------------
#ifndef subSERVICEH
#define subSERVICEH
//---------------------------------------------------------------------------
//      関数のプロトタイプ宣言
//---------------------------------------------------------------------------
char subStartService(char *chSVC,char *chMACHI);        //  サービスの起動
char subHaltService(char *chSVC,char *chMACHI);         //  サービスの停止
char subContinueService(char *chSVC,char *chMACHI);     //  サービスの続行
char subPauseService(char *chSVC,char *chMACHI);        //  サービスの一時停止
char subExchServiceNames(char *chSVC,char *chRSLT,char *chMACHI);   //  サービス名変換
char subGetServiceStatus(char *chSVC,char *chMACHI);    //  サービス状態取得
//---------------------------------------------------------------------------
#endif

subSERVICE.cpp

//---------------------------------------------------------------------------
//      サービスコントロールサブルーチン
//                  2001.5.7    by S.Wakimoto   Write Base Code
//                  2001.5.22   by S.Wakimoto   Add "subGetServiceStatus()"
//---------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>

#include "subSERVICE.h"
//---------------------------------------------------------------------------
#define     intTimeOut      60      //  60秒でタイムアウト
//---------------------------------------------------------------------------
char subStartService(char *chSVC,char *chMACHI)
{
    /*-----------------------------------------------------------------------
            指定名称のサービスを起動させる
                                                            by S.Wakimoto
      -----------------------------------------------------------------------
            *chSVC  :   サービス登録名称へのポインタ
            *chMACHI:   実行先マシン名へのポインタ
            戻り値  :   NULL    …  一時停止完了
                        NonNULL …  一時停止失敗
      -----------------------------------------------------------------------*/
    char ret = NULL;
    SC_HANDLE hSCM;                 //  SCMへのハンドル
    SC_HANDLE hSVC;                 //  サービスへのハンドル
    SERVICE_STATUS ssSTAT;          //  サービス状態構造体
    int cnt;

    //  ServiceControlManagerを起動する
    hSCM = ::OpenSCManager(chMACHI,NULL,SC_MANAGER_CREATE_SERVICE);

    if (hSCM == NULL)   {
        //  ServiceControlManagerの起動に失敗
        ret = -1;
    } else {
        //  サービスに接続する
        hSVC = ::OpenService(hSCM,chSVC,SERVICE_ALL_ACCESS);

        if (hSVC == NULL)   {
            //  サービスへの接続失敗
            ret = -1;
        } else {
            //  サービスを起動させる
            if (::StartService(hSVC,0,NULL))    {
                //  状態を監視する
                cnt = 0;
		        while(::QueryServiceStatus(hSVC,&ssSTAT))     {
			        if (ssSTAT.dwCurrentState == SERVICE_START_PENDING)  {
                        //  停止中の場合はしばらく待つ
				        ::Sleep(1000);
                        cnt++;
                        if (cnt > intTimeOut)   {
                            //  制限時間内に処理完了にならなければタイムアウト
                            break;
                        }
			        } else {
                        //  それ以外の場合はエラーとして処理
				        break;
			        }
		        }

                //  結果をチェックする
		        if(ssSTAT.dwCurrentState == SERVICE_RUNNING)    {
                    //  サービス停止
                    ret = NULL;
			    } else {
                    //  サービス停止失敗
                    ret = -1;
                }
            }
        }
    }

    //  SCMを閉じる
	::CloseServiceHandle(hSVC);
	::CloseServiceHandle(hSCM);

    return ret;
}
//---------------------------------------------------------------------------
char subHaltService(char *chSVC,char *chMACHI)
{
    /*-----------------------------------------------------------------------
            指定名称のサービスを停止させる
                                                            by S.Wakimoto
      -----------------------------------------------------------------------
            *chSVC  :   サービス登録名称へのポインタ
            *chMACHI:   実行先マシン名へのポインタ
            戻り値  :   NULL    …  一時停止失敗
                        NonNULL …  一時停止完了
      -----------------------------------------------------------------------*/
    char ret = NULL;
    SC_HANDLE hSCM;                 //  SCMへのハンドル
    SC_HANDLE hSVC;                 //  サービスへのハンドル
    SERVICE_STATUS ssSTAT;          //  サービス状態構造体
    int cnt;

    //  ServiceControlManagerを起動する
    hSCM = ::OpenSCManager(chMACHI,NULL,SC_MANAGER_CREATE_SERVICE);

    if (hSCM == NULL)   {
        //  ServiceControlManagerの起動に失敗
        ret = -1;
    } else {
        //  サービスに接続する
        hSVC = ::OpenService(hSCM,chSVC,SERVICE_ALL_ACCESS);

        if (hSVC == NULL)   {
            //  サービスへの接続失敗
            ret = -1;
        } else {
            //  サービスを停止させる
            if (::ControlService(hSVC,SERVICE_CONTROL_STOP,&ssSTAT))     {
                //  状態を監視する
                cnt = 0;
		        while(::QueryServiceStatus(hSVC,&ssSTAT))     {
			        if (ssSTAT.dwCurrentState == SERVICE_STOP_PENDING)  {
                        //  停止中の場合はしばらく待つ
				        ::Sleep(1000);
                        cnt++;
                        if (cnt > intTimeOut)   {
                            //  制限時間内に処理完了にならなければタイムアウト
                            break;
                        }
			        } else {
                        //  それ以外の場合はエラーとして処理
				        break;
			        }
		        }

                //  結果をチェックする
		        if(ssSTAT.dwCurrentState == SERVICE_STOPPED)    {
                    //  サービス停止
                    ret = NULL;
			    } else {
                    //  サービス停止失敗
                    ret = -1;
                }
            }
        }
    }

    //  SCMを閉じる
	::CloseServiceHandle(hSVC);
	::CloseServiceHandle(hSCM);

    return ret;
}
//---------------------------------------------------------------------------
char subContinueService(char *chSVC,char *chMACHI)
{
    /*-----------------------------------------------------------------------
            指定名称のサービスを続行させる
                                                            by S.Wakimoto
      -----------------------------------------------------------------------
            *chSVC  :   サービス登録名称へのポインタ
            *chMACHI:   実行先マシン名へのポインタ
            戻り値  :   NULL    …  一時停止失敗
                        NonNULL …  一時停止完了
      -----------------------------------------------------------------------*/
    char ret = NULL;
    SC_HANDLE hSCM;                 //  SCMへのハンドル
    SC_HANDLE hSVC;                 //  サービスへのハンドル
    SERVICE_STATUS ssSTAT;          //  サービス状態構造体
    int cnt;

    //  ServiceControlManagerを起動する
    hSCM = ::OpenSCManager(chMACHI,NULL,SC_MANAGER_CREATE_SERVICE);

    if (hSCM == NULL)   {
        //  ServiceControlManagerの起動に失敗
        ret = -1;
    } else {
        //  サービスに接続する
        hSVC = ::OpenService(hSCM,chSVC,SERVICE_ALL_ACCESS);

        if (hSVC == NULL)   {
            //  サービスへの接続失敗
            ret = -1;
        } else {
            //  サービスを続行させる
            if (::ControlService(hSVC,SERVICE_CONTROL_CONTINUE,&ssSTAT))     {
                //  状態を監視する
                cnt = 0;
		        while(::QueryServiceStatus(hSVC,&ssSTAT))     {
			        if (ssSTAT.dwCurrentState == SERVICE_CONTINUE_PENDING)  {
                        //  停止中の場合はしばらく待つ
				        ::Sleep(1000);
                        cnt++;
                        if (cnt > intTimeOut)   {
                            //  制限時間内に処理完了にならなければタイムアウト
                            break;
                        }
			        } else {
                        //  それ以外の場合はエラーとして処理
				        break;
			        }
		        }

                //  結果をチェックする
		        if(ssSTAT.dwCurrentState == SERVICE_RUNNING)    {
                    //  サービス停止
                    ret = NULL;
			    } else {
                    //  サービス停止失敗
                    ret = -1;
                }
            }
        }
    }

    //  SCMを閉じる
	::CloseServiceHandle(hSVC);
	::CloseServiceHandle(hSCM);

    return ret;
}
//---------------------------------------------------------------------------
char subPauseService(char *chSVC,char *chMACHI)
{
    /*-----------------------------------------------------------------------
            指定名称のサービスを一時停止させる
                                                            by S.Wakimoto
      -----------------------------------------------------------------------
            *chSVC  :   サービス登録名称へのポインタ
            *chMACHI:   実行先マシン名へのポインタ
            戻り値  :   NULL    …  一時停止失敗
                        NonNULL …  一時停止完了
      -----------------------------------------------------------------------*/
    char ret = NULL;
    SC_HANDLE hSCM;                 //  SCMへのハンドル
    SC_HANDLE hSVC;                 //  サービスへのハンドル
    SERVICE_STATUS ssSTAT;          //  サービス状態構造体
    int cnt;

    //  ServiceControlManagerを起動する
    hSCM = ::OpenSCManager(chMACHI,NULL,SC_MANAGER_CREATE_SERVICE);

    if (hSCM == NULL)   {
        //  ServiceControlManagerの起動に失敗
        ret = -1;
    } else {
        //  サービスに接続する
        hSVC = ::OpenService(hSCM,chSVC,SERVICE_ALL_ACCESS);

        if (hSVC == NULL)   {
            //  サービスへの接続失敗
            ret = -1;
        } else {
            //  サービスを一時停止させる
            if (::ControlService(hSVC,SERVICE_CONTROL_PAUSE,&ssSTAT)) {
                //  状態を監視する
                cnt = 0;
		        while(::QueryServiceStatus(hSVC,&ssSTAT))     {
			        if (ssSTAT.dwCurrentState == SERVICE_PAUSE_PENDING) {
                        //  一時停止中の場合はしばらく待つ
				        ::Sleep(1000);
                        cnt++;
                        if (cnt > intTimeOut)   {
                            //  制限時間内に処理完了にならなければタイムアウト
                            break;
                        }
			        } else {
                        //  それ以外の場合はエラーとして処理
				        break;
			        }
		        }

                //  結果をチェックする
		        if(ssSTAT.dwCurrentState == SERVICE_PAUSED) {
                    //  サービス停止
                    ret = NULL;
			    } else {
                    //  サービス停止失敗
                    ret = -1;
                }
            }
        }
    }

    //  SCMを閉じる
	::CloseServiceHandle(hSVC);
	::CloseServiceHandle(hSCM);

    return ret;
}
//---------------------------------------------------------------------------
char subExchServiceNames(char *chSVC,char *chRSLT,char *chMACHI)
{
    /*-----------------------------------------------------------------------
                サービス表示名を登録サービス名称に変換する
                                                            by S.Wakimoto
      -----------------------------------------------------------------------
                *chSVC  :   サービス表示名称へのポインタ
                *chRSLT :   変換結果(登録名称)格納先へのポインタ
                *chMACHI:   チェック先マシン名称
                戻り値  :   NULL    …  正常終了
                            NonNULL …  エラーあり
      -----------------------------------------------------------------------*/
    char ret = NULL;
    SC_HANDLE hSCM;                     //  SCMへのハンドル
    ENUM_SERVICE_STATUS ssENUM[4096];        //  列挙される情報取得用
    DWORD dwNEED,dwMANY,dwNEXT;
    DWORD i;

    //  ServiceControlManagerを起動する
    hSCM = ::OpenSCManager(chMACHI,NULL,SC_MANAGER_ENUMERATE_SERVICE);

    if (hSCM == NULL)   {
        //  ServiceControlManagerの起動に失敗
        ret = -1;
    } else {
        //  サービス名称のリストを取得する
        dwNEED = dwMANY = dwNEXT = 0;
        if (::EnumServicesStatus(hSCM,SERVICE_WIN32,SERVICE_ACTIVE | SERVICE_INACTIVE,
                  ssENUM,sizeof(ENUM_SERVICE_STATUS) * 4096,&dwNEED,&dwMANY,&dwNEXT))    {
            //  正常終了の場合はサービス名称から該当データを検索する
            for (i = 0;i < dwMANY;i++)  {
                if (strcmpi(ssENUM[i].lpDisplayName,chSVC) == 0)   {
                    //  該当のサービス名称
                    strcpy(chRSLT,ssENUM[i].lpServiceName);
                    break;
                }
            }
        } else {
            //  エラーの場合はメッセージを表示して
            printf("サービス情報取得中にエラーが発生しました\r\n");
            ret = -1;
        }
    }

    //  SCMを閉じる
	::CloseServiceHandle(hSCM);

    return ret;
}
//---------------------------------------------------------------------------
char subGetServiceStatus(char *chSVC,char *chMACHI)
{
    /*-----------------------------------------------------------------------
              現在の指定サービスの状態を返す
                                                            by S.Wakimoto
      -----------------------------------------------------------------------
            chSVC   :   サービス名(表示名)を示す文字列へのポインタ
            chMACHI :   対象マシン名を示す文字列へのポインタ
            戻り値  :   0…サービスが登録されていない
                        1…サービスは起動途中
                        2…サービスは起動している
                        3…サービスは停止途中
                        4…サービスは停止している
                        5…サービスは一時停止途中
                        6…サービスは一時停止している
                        7…サービスは続行途中
                        8…サービス状態不明
                        9…エラー終了
      -----------------------------------------------------------------------*/
    char ret;
    SC_HANDLE hSCM;                 //  SCMへのハンドル
    SC_HANDLE hSVC;                 //  サービスへのハンドル
    SERVICE_STATUS ssSTAT;          //  サービス状態構造体

    //  ServiceControlManagerを起動する
    hSCM = ::OpenSCManager(chMACHI,NULL,SC_MANAGER_CREATE_SERVICE);

    if (hSCM == NULL)   {
        //  ServiceControlManagerの起動に失敗
        ret = 9;
    } else {
        //  サービスに接続する
        hSVC = ::OpenService(hSCM,chSVC,SERVICE_ALL_ACCESS);

        if (hSVC == NULL)   {
            //  サービスへの接続失敗
            ret = 0;
        } else {
            //  状態を監視する
            ::QueryServiceStatus(hSVC,&ssSTAT);

            //  結果をチェックする
            if (ssSTAT.dwCurrentState == SERVICE_START_PENDING)     {
                //  起動途中
                ret = 1;
            } else if (ssSTAT.dwCurrentState == SERVICE_RUNNING)    {
                //  起動している
                ret = 2;
            } else if (ssSTAT.dwCurrentState == SERVICE_STOP_PENDING)   {
                //  停止途中
                ret = 3;
            } else if (ssSTAT.dwCurrentState == SERVICE_STOPPED)    {
                //  停止している
                ret = 4;
            } else if (ssSTAT.dwCurrentState == SERVICE_PAUSE_PENDING)  {
                //  一時停止途中
                ret = 5;
            } else if (ssSTAT.dwCurrentState == SERVICE_PAUSED)     {
                //  一時停止している
                ret = 6;
            } else if (ssSTAT.dwCurrentState == SERVICE_CONTINUE_PENDING)   {
                //  続行途中
                ret = 7;
            } else {
                //  不明
                ret = 8;
            }

            //  SVCを閉じる
  	        ::CloseServiceHandle(hSVC);
        }

        //  SCMを閉じる
        ::CloseServiceHandle(hSCM);
    }

    return ret;
}
//---------------------------------------------------------------------------

トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-12-09 (日) 22:30:50