新建控制台程序,不需要界面
在stdafx.h中添加MFC支持:
#include <afx.h>
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
在主cpp文件中添加:
每个函数具体的含义可以去百度一下或者去MSDN查看函数原型。
LPCTSTR lpServiceName = _T("myservice");
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE hServiceStatus;
HANDLE g_hQuitEvent = NULL;
bool Install()
{
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
return false;
TCHAR szFilePath[MAX_PATH];
::GetModuleFileName(NULL, szFilePath, MAX_PATH);
SC_HANDLE hService = ::CreateService(hSCM, lpServiceName, lpServiceName, SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, _T(""), NULL, NULL);
if (hService == NULL)
{
::CloseServiceHandle(hSCM);
return false;
}
::CloseServiceHandle(hSCM);
::CloseServiceHandle(hService);
return true;
}
bool Uninstall()
{
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
return false;
SC_HANDLE hService = ::OpenService(hSCM, lpServiceName, SERVICE_STOP | DELETE);
if (hService == NULL)
{
::CloseServiceHandle(hSCM);
return false;
}
SERVICE_STATUS status;
::ControlService(hService, SERVICE_CONTROL_STOP, &status);
BOOL bDelete = ::DeleteService(hService);
::CloseServiceHandle(hSCM);
::CloseServiceHandle(hService);
if (bDelete)
return true;
return false;
}
// Control Handler
void ControlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
{
if (g_hQuitEvent != NULL)
{
::SetEvent(g_hQuitEvent);
}
Sleep(1000);
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hServiceStatus, &serviceStatus);
return;
}
break;
default:
break;
}
// Report current status
SetServiceStatus(hServiceStatus, &serviceStatus);
return;
}
void ServiceMain(DWORD dwNumServicesArgs,
LPWSTR *lpServiceArgVectors)
{
//Sleep(15000);
HANDLE hMutex = CreateMutex(NULL, FALSE, _T("myservice"));
if (GetLastError() == ERROR_ALREADY_EXISTS)
return;
serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwServiceSpecificExitCode = 0;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
hServiceStatus = RegisterServiceCtrlHandler(lpServiceName, (LPHANDLER_FUNCTION)ControlHandler);
if (hServiceStatus == (SERVICE_STATUS_HANDLE)0)
return;
g_hQuitEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_hQuitEvent == NULL)
{
serviceStatus.dwCurrentState = SERVICE_STOPPED;
serviceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hServiceStatus, &serviceStatus);
return;
}
// We report the running status to SCM.
serviceStatus.dwCurrentState = SERVICE_RUNNING;
//ServiceStatus.dwWaitHint = 20000;
SetServiceStatus(hServiceStatus, &serviceStatus);
while (serviceStatus.dwCurrentState == SERVICE_RUNNING)
{
if (WaitForSingleObject(g_hQuitEvent,0) == WAIT_OBJECT_0)
break;
::Sleep(1000);
}
return;
}
在_tmain入口函数中添加代码,效果如下:
int _tmain(int argc, _TCHAR* argv[])
{
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
USES_CONVERSION;
if (argc >= 2)
{
if (_stricmp(W2A(argv[1]), "/INSTALL") == 0)
{
Install();
printf("myservice install");
}
else if (_stricmp(W2A(argv[1]), "/UNINSTALL") == 0)
{
Uninstall();
printf("myservice uninstall");
}
}
else
{
//Sleep(10000);
SERVICE_TABLE_ENTRYW serviceTable[2];
serviceTable[0].lpServiceName = (LPTSTR)lpServiceName;
serviceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
serviceTable[1].lpServiceName = NULL;
serviceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(serviceTable);
TRACE(_T("StartServiceCtrlDispatcher \r\n"));
}
return 0;
}