(1)WindowsService.h
#pragma once
class CWindowsService
{
public:
CWindowsService(void);
public:
~CWindowsService(void);
enum SEV_STATUS
{
SEV_ERROR = 0,
SEV_NO = 1,
SEV_HAVE = 2,
SEV_RUNING = 3,
SEV_STOPED = 4,
};
public:
BOOL AddService(const wchar_t* pSourceName, const wchar_t* pServiceName, const wchar_t* pDisName, const wchar_t* pPara);
BOOL RemoveService(const wchar_t* pServiceName);
BYTE CheckServiceStatus(const wchar_t* pServiceName);
BOOL StartSevice(const wchar_t* pServiceName);
BOOL StopSevice(const wchar_t* pServiceName);
BOOL GetSevicePath(const wchar_t* pServiceName, CString &strServicePath);
BOOL GetCurPath(CString &strCurPath);
bool EnableDebugPrivilege();
};
(2)WindowsService.cpp
#include "StdAfx.h"
#include "WindowsService.h"
#include "winsvc.h"
CWindowsService::CWindowsService(void)
{
}
CWindowsService::~CWindowsService(void)
{
}
BOOL CWindowsService::AddService(const wchar_t* pSourceName, const wchar_t* pServiceName, const wchar_t* pDisName, const wchar_t* pPara)
{
SC_HANDLE hSC = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (hSC == NULL)
{
return FALSE;
}
CString strBinnaryPathName;
//strBinnaryPathName.Format("%s%s%s %s", "/"",pSourceName," / "", pPara);
SC_HANDLE hSvc = CreateService(hSC,
pServiceName,
pDisName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
strBinnaryPathName,
NULL,
NULL,
NULL,
NULL,
NULL);
if (hSvc == NULL)
{
::CloseServiceHandle(hSC);
return FALSE;
}
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return TRUE;
}
BOOL CWindowsService::RemoveService(const wchar_t*pServiceName)
{
SC_HANDLE hSC = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSC == NULL)
{
return FALSE;
}
SC_HANDLE hSvc = ::OpenService(hSC, pServiceName, SERVICE_STOP | DELETE/*SERVICE_ALL_ACCESS*/);
if (hSvc == NULL)
{
::CloseServiceHandle(hSC);
return FALSE;
}
SERVICE_STATUS status;
::ControlService(hSvc, SERVICE_CONTROL_STOP, &status);
if (!::DeleteService(hSvc))
{
DWORD _error = GetLastError();
return FALSE;
}
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return TRUE;
}
BYTE CWindowsService::CheckServiceStatus(const wchar_t*pServiceName)
{
SC_HANDLE hSC = ::OpenSCManager(NULL, NULL, GENERIC_EXECUTE);
if (hSC == NULL)
{
return SEV_ERROR;
}
SC_HANDLE hSvc = ::OpenService(hSC, pServiceName, SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_STOP);
if (hSvc == NULL)
{
::CloseServiceHandle(hSC);
return SEV_NO;
}
SERVICE_STATUS status;
if (::QueryServiceStatus(hSvc, &status) == FALSE)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return SEV_ERROR;
}
if (status.dwCurrentState == SERVICE_RUNNING)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return SEV_RUNING;
}
else if (status.dwCurrentState == SERVICE_STOPPED)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return SEV_STOPED;
}
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return SEV_ERROR;
}
BOOL CWindowsService::StartSevice(const wchar_t* pServiceName)
{
EnableDebugPrivilege();
SC_HANDLE hSC = ::OpenSCManager(NULL, NULL, GENERIC_EXECUTE);
if (hSC == NULL)
{
int aaa = GetLastError();
return FALSE;
}
SC_HANDLE hSvc = ::OpenService(hSC, pServiceName, SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_STOP);
if (hSvc == NULL)
{
::CloseServiceHandle(hSC);
return FALSE;
}
SERVICE_STATUS status;
if (::QueryServiceStatus(hSvc, &status) == FALSE)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return FALSE;
}
if (status.dwCurrentState != SERVICE_RUNNING)
{
if (::StartService(hSvc, NULL, NULL) == FALSE)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return FALSE;
}
while (::QueryServiceStatus(hSvc, &status) == TRUE)
{
::Sleep(500);
QueryServiceStatus(hSvc, &status);
if (status.dwCurrentState == SERVICE_START_PENDING)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return TRUE;
}
::Sleep(status.dwWaitHint);
QueryServiceStatus(hSvc, &status);
if (status.dwCurrentState == SERVICE_RUNNING)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return TRUE;
}
else
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return FALSE;
}
}
}
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return TRUE;
}
BOOL CWindowsService::StopSevice(const wchar_t*pServiceName)
{
EnableDebugPrivilege();
SC_HANDLE hSC = ::OpenSCManager(NULL, NULL, GENERIC_EXECUTE);
if (hSC == NULL)
{
return FALSE;
}
SC_HANDLE hSvc = ::OpenService(hSC, pServiceName,
SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_STOP);
if (hSvc == NULL)
{
::CloseServiceHandle(hSC);
return FALSE;
}
SERVICE_STATUS status;
if (::QueryServiceStatus(hSvc, &status) == FALSE)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return FALSE;
}
if (status.dwCurrentState == SERVICE_RUNNING)
{
if (::ControlService(hSvc, SERVICE_CONTROL_STOP, &status) == FALSE)
{
//TRACE( "stop service error。");
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return FALSE;
}
while (::QueryServiceStatus(hSvc, &status) == TRUE)
{
::Sleep(1000);
QueryServiceStatus(hSvc, &status);
if (status.dwCurrentState == SERVICE_STOPPED)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return TRUE;
}
::Sleep(3000);
QueryServiceStatus(hSvc, &status);
if (status.dwCurrentState == SERVICE_STOPPED)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return TRUE;
}
::Sleep(status.dwWaitHint);
QueryServiceStatus(hSvc, &status);
if (status.dwCurrentState == SERVICE_STOPPED)
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return TRUE;
}
else
{
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return FALSE;
}
}
}
return TRUE;
}
BOOL CWindowsService::GetSevicePath(const wchar_t*pServiceName, CString & strServicePath)
{
SC_HANDLE hSC = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSC == NULL)
{
return FALSE;
}
SC_HANDLE hSvc = ::OpenService(hSC, pServiceName, SERVICE_ALL_ACCESS);
if (hSvc == NULL)
{
::CloseServiceHandle(hSC);
return FALSE;
}
LPQUERY_SERVICE_CONFIG pServiceConfig;
DWORD cbBufSize = 1024 * 8;
DWORD cbBytesNeeded;
CString strPath;
pServiceConfig = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LPTR, cbBufSize);
QueryServiceConfig(hSvc, pServiceConfig, cbBufSize, &cbBytesNeeded);
strPath = pServiceConfig->lpBinaryPathName;
strPath.Replace('"', ' ');
int iFind = strPath.Find(L"exe");
strPath = strPath.Left(iFind + 3);
strServicePath = strPath;
::LocalFree(pServiceConfig);
::CloseServiceHandle(hSvc);
::CloseServiceHandle(hSC);
return TRUE;
}
BOOL CWindowsService::GetCurPath(CString &strCurPath)
{
wchar_t szTemp[MAX_PATH] = { 0 };
::GetModuleFileName(NULL, szTemp, sizeof(szTemp) - 1);
int iLen = (int)lstrlenW(szTemp);
for (int i = iLen - 1; i >= 0; i--)
{
if (szTemp[i] == '//')
{
break;
}
else
{
szTemp[i] = 0;
}
}
strCurPath = szTemp;
return TRUE;
}
bool CWindowsService::EnableDebugPrivilege()
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return FALSE;
}
if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &sedebugnameValue))
{
CloseHandle(hToken);
return false;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
CloseHandle(hToken);
return false;
}
return true;
}