StartServiceCtrlDispatcher を調べてください。
Windows サービスとして実行するなら最低でもこの関数を利用する事が出来なければ、サービスとして実行させることはできません。
https://docs.microsoft.com/ja-jp/windows/win32/api/winsvc/nf-winsvc-startservicectrldispatchera
サービス実行部またはサービス停止部は、StartServiceCtrlDispatcher を処理していく過程で見えてきますのであえて説明しません。
【サービス作成サンプル : C++】
#include <Windows.h>
char ServiceName[] = "ServiceTestName";
SERVICE_STATUS g_serviceStatus = { 0 };
SERVICE_STATUS_HANDLE g_hServiceStatus = NULL;
//サービスイベントハンドラー
DWORD WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) {
switch (dwControl) {
case SERVICE_CONTROL_STOP: //サービス停止イベント
g_serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_serviceStatus.dwCheckPoint = 0;
g_serviceStatus.dwWaitHint = 50000;
SetServiceStatus(g_hServiceStatus, &g_serviceStatus);
break;
case SERVICE_CONTROL_INTERROGATE: //サービス問い合わせイベント
SetServiceStatus(g_hServiceStatus, &g_serviceStatus);
break;
default:
break;
}
return NO_ERROR;
}
//WinMain 関数
int WINAPI WinMain(_In_ HINSTANCE hinst, _In_opt_ HINSTANCE hinstPrev, _In_ LPSTR lpszCmdLine, _In_ int nCmdShow) {
SERVICE_TABLE_ENTRY serviceTable[] = {
{ ServiceName, ServiceMain }, { NULL, NULL }
};
UINT32 TimeBench;
//サービス状態の起動であるかチェックする
//(サービスではない場所からプログラムが起動された場合、関数はアクセス拒否になる)
if (StartServiceCtrlDispatcher(serviceTable) == FALSE) {
}
return 0;
}
//サービス登録及び実行・イベントハンドラー登録処理
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
//サービスイベントハンドラー登録
g_hServiceStatus = RegisterServiceCtrlHandlerEx(ServiceName, HandlerEx, NULL);
//サービス状況作成とサービスへ状態報告
g_serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_serviceStatus.dwCurrentState = SERVICE_START_PENDING;
g_serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_serviceStatus.dwWin32ExitCode = NO_ERROR;
g_serviceStatus.dwServiceSpecificExitCode = 0;
g_serviceStatus.dwCheckPoint = 1;
g_serviceStatus.dwWaitHint = 30000;
SetServiceStatus(g_hServiceStatus, &g_serviceStatus);
//サービス開始処理報告
g_serviceStatus.dwCurrentState = SERVICE_RUNNING;
g_serviceStatus.dwCheckPoint = 0;
g_serviceStatus.dwWaitHint = 0;
SetServiceStatus(g_hServiceStatus, &g_serviceStatus);
//ここからがサービス内プログラム
//ここまでがサービス内プログラム
//サービスの停止処理報告
g_serviceStatus.dwCurrentState = SERVICE_STOPPED;
g_serviceStatus.dwCheckPoint = 0;
g_serviceStatus.dwWaitHint = 0;
SetServiceStatus(g_hServiceStatus, &g_serviceStatus);
}