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