1、安装服务
BOOL InstallService(LPSTR lpszModulePath)
{
SC_HANDLE schSCManager,schService;
schSCManager = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
return FALSE;
char szModulePath[_MAX_PATH + 1];
_snprintf_s(szModulePath, _MAX_PATH, "\"%s\"", lpszModulePath);
schService = ::CreateService(schSCManager,
"服务名称xxx",
"服务描述xxx",// service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS, // service type
//SERVICE_DEMAND_START, // start type
SERVICE_AUTO_START, //系统启动时自动启动
SERVICE_ERROR_NORMAL, // error control type
szModulePath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
if (schService == NULL)
return FALSE;
::CloseServiceHandle(schService);
::CloseServiceHandle(schSCManager);
return TRUE;
}
2、卸载服务
BOOL UnInstallService(LPSTR lpszSrvName)
{
SC_HANDLE schSCManager;
SC_HANDLE hService;
schSCManager = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
return FALSE;
hService = ::OpenService(schSCManager,lpszSrvName,SERVICE_ALL_ACCESS);
if (hService == NULL)
return FALSE;
if(::DeleteService(hService)==0)
return FALSE;
if(::CloseServiceHandle(hService)==0)
return FALSE;
if(::CloseServiceHandle(schSCManager)==0)
return FALSE;
else
return TRUE;
}
3、启动服务
BOOL StartService(LPSTR lpszSrvName)
{
// 启动服务
SC_HANDLE schSCManager;
SC_HANDLE schService;
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;
DWORD dwBytesNeeded;
schSCManager = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
return FALSE;
schService = ::OpenService(
schSCManager, // SCM database
lpszSrvName, // service name
SERVICE_ALL_ACCESS);
if (schService == NULL)
{
::CloseServiceHandle(schSCManager);
return FALSE;
}
if (!::QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(PBYTE)&ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded)) // if buffer too small
{
::CloseServiceHandle(schSCManager);
return FALSE;
}
if (ssStatus.dwCurrentState == SERVICE_RUNNING)
{
::CloseServiceHandle(schService);
::CloseServiceHandle(schSCManager);
return TRUE;
}
if (!::StartService(
schService, // handle to service
0, // number of arguments
NULL) ) // no arguments
{
::CloseServiceHandle(schSCManager);
return FALSE;
}
else
{
printf("Service start pending.\n");
}
// Check the status until the service is no longer start pending.
if (!::QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(PBYTE)&ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded)) // if buffer too small
{
::CloseServiceHandle(schSCManager);
return FALSE;
}
// Save the tick count and initial checkpoint.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
{
// Do not wait longer than the wait hint. A good interval is
// one tenth the wait hint, but no less than 1 second and no
// more than 10 seconds.
dwWaitTime = ssStatus.dwWaitHint / 10;
if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;
Sleep( dwWaitTime );
// Check the status again.
if (!::QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(PBYTE)&ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded)) // if buffer too small
break;
if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
{
// The service is making progress.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
{
// No progress made within the wait hint
break;
}
}
}
::CloseServiceHandle(schService);
::CloseServiceHandle(schSCManager);
if (ssStatus.dwCurrentState == SERVICE_RUNNING)
{
printf("StartService SUCCESS.\n");
return TRUE;
}
else
{
printf("\nService not started. \n");
printf(" Current State: %d\n", ssStatus.dwCurrentState);
printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode);
printf(" Service Specific Exit Code: %d\n", ssStatus.dwServiceSpecificExitCode);
printf(" Check Point: %d\n", ssStatus.dwCheckPoint);
printf(" Wait Hint: %d\n", ssStatus.dwWaitHint);
return FALSE;
}
}
4、停止服务
BOOL StopService(LPSTR lpszSrvName)
{
// 停止服务
SC_HANDLE schSCManager;
SC_HANDLE schService;
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;
DWORD dwBytesNeeded;
schSCManager = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
return FALSE;
schService = ::OpenService(
schSCManager, // SCM database
lpszSrvName, // service name
SERVICE_ALL_ACCESS);
if (schService == NULL)
{
::CloseServiceHandle(schSCManager);
return FALSE;
}
if (!::QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(PBYTE)&ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded)) // if buffer too small
{
::CloseServiceHandle(schSCManager);
return FALSE;
}
if (ssStatus.dwCurrentState == SERVICE_STOPPED)
{
::CloseServiceHandle(schService);
::CloseServiceHandle(schSCManager);
return TRUE;
}
else if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
{
goto StopPending;
}
SERVICE_STATUS ssService;
if (!::ControlService(
schService, // handle to service
SERVICE_CONTROL_STOP, // number of arguments
&ssService) ) // no arguments
{
::CloseServiceHandle(schSCManager);
return FALSE;
}
else
{
printf("Service stop pending.\n");
}
// Check the status until the service is no longer start pending.
if (!::QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(PBYTE)&ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded)) // if buffer too small
{
::CloseServiceHandle(schSCManager);
return FALSE;
}
StopPending:
// Save the tick count and initial checkpoint.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
{
// Do not wait longer than the wait hint. A good interval is
// one tenth the wait hint, but no less than 1 second and no
// more than 10 seconds.
dwWaitTime = ssStatus.dwWaitHint / 10;
if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;
Sleep( dwWaitTime );
// Check the status again.
if (!::QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(PBYTE)&ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded)) // if buffer too small
break;
if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
{
// The service is making progress.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
{
// No progress made within the wait hint
break;
}
}
}
::CloseServiceHandle(schService);
::CloseServiceHandle(schSCManager);
if (ssStatus.dwCurrentState == SERVICE_STOPPED)
{
printf("StartService SUCCESS.\n");
return TRUE;
}
else
{
printf("\nService not started. \n");
printf(" Current State: %d\n", ssStatus.dwCurrentState);
printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode);
printf(" Service Specific Exit Code: %d\n", ssStatus.dwServiceSpecificExitCode);
printf(" Check Point: %d\n", ssStatus.dwCheckPoint);
printf(" Wait Hint: %d\n", ssStatus.dwWaitHint);
return FALSE;
}
}