所謂服務程序,就像系統的一些服務一樣,能夠自動地啓動,並執行相應的操作;而且因爲服務程序的在層次上和一般的應用程序不同,其能夠在系統啓動時就自動地運行,而不像一般的應用程序那樣一定要在登陸後才能運行,這些就是服務的一些好處了,如果你也想你的程序具有這樣的功能,那麼你就可以建立一個服務應用程序了。下面就跟着我一步一步地教你怎麼去創建一個服務應用程序吧。
主要使用到的函數(詳情請看MSDN):
1.OpenSCManager:打開服務管理器
WINADVAPI
SC_HANDLE
WINAPI
OpenSCManager(
__in_opt LPCSTR lpMachineName,//計算機名,NULL表示本地計算機
__in_opt LPCSTR lpDatabaseName,//數據庫名,默認值是SERVICES_ACTIVE_DATABASE
__in DWORD dwDesiredAccess//訪問權限
);
參數dwDesiredAccess的取值有:
SC_MANAGER_CONNECT //可連接
SC_MANAGER_CREATE_SERVICE //能創建服務
SC_MANAGER_ENUMERATE_SERVICE
SC_MANAGER_LOCK
SC_MANAGER_QUERY_LOCK_STATUS
SC_MANAGER_MODIFY_BOOT_CONFIG
2.CreateService:創建服務
WINADVAPI
SC_HANDLE
WINAPI
CreateService(
__in SC_HANDLE hSCManager,//服務管理器
__in LPCSTR lpServiceName, //服務名
__in_opt LPCSTR lpDisplayName,//顯示名字
__in DWORD dwDesiredAccess,//訪問權限
__in DWORD dwServiceType,//服務類型,見MSDN
__in DWORD dwStartType,//怎麼啓動的?
__in DWORD dwErrorControl,
__in_opt LPCSTR lpBinaryPathName,//啓動路徑
__in_opt LPCSTR lpLoadOrderGroup,
__out_opt LPDWORD lpdwTagId,
__in_opt LPCSTR lpDependencies,
__in_opt LPCSTR lpServiceStartName,
__in_opt LPCSTR lpPassword
);
3.其他函數
OpenService:打開服務
ControlService:控制服務
DeleteService:刪除服務
RegisterServiceCtrlHandler:註冊服務控件句柄,返回的是服務狀態類型
SetServiceStatus 設置服務狀態信息
StartServiceCtrlDispatcher:在主線程裏面開始服務指派
下面通過實例說明一下:
》聲明成員變量:
SERVICE_STATUS_HANDLE m_hServiceStatus;
》創建服務
BOOL Install() //安裝服務
{
SC_HANDLE hSCM= OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (!hSCM)//打開服務管理器失敗
return FALSE;
//創建服務
SC_HANDLE hService = ::CreateService(
hSCM, szServiceName, szServiceName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, _T(""), NULL, NULL);
ChangeServiceConfig2(.............);//還可以配置服務的信息
//最後要關閉句柄
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
}
BOOL Uninstall()//卸載服務
{
..................
OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
//打開服務
OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
//停止服務
ControlService(hService, SERVICE_CONTROL_STOP, &status);
//刪除服務
DeleteService(hService);
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
}
<>添加服務主線程函數和控制函數。這裏調用 RegisterServiceCtrlHandler 來註冊服務的控制函數,這裏要設置status.dwControlsAccepted 爲 SERVICE_ACCEPT_STOP,否則你不能控制這個服務的狀態。
void WINAPI ServiceMain()
{
// Register the control request handler
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;//這個要使用,否則你不能控制
//註冊服務控制
hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
if (hServiceStatus == NULL)
{
LogEvent(_T("Handler not installed"));
return;
}
SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hServiceStatus, &status);
//模擬服務的運行,10後自動退出。應用時將主要任務放於此即可
int i = 0;
while (i < 10)
{
Sleep(1000);
i++;
}
//
status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hServiceStatus, &status);
LogEvent(_T("Service stopped"));
}
《》最後我們需要在主函數,或者應用程序的Main函數裏面註冊,安裝,卸載服務。。。
加入下面的代碼:
。。。。。。。。。。。。。。。。
ParseCommandLine(m_trCmdInfo);//得到命令參數lpCmdLine
SERVICE_TABLE_ENTRY st[] =
{
{ szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};
if (stricmp(lpCmdLine, "/install") == 0)
{
Install();
}
else if (stricmp(lpCmdLine, "/uninstall") == 0)
{
Uninstall();
}
else
{
StartServiceCtrlDispatcher(st);
}