这里贴上完整的main.cpp代码吧……
/*******************************************************************************
Written by: shiyang sun
First: you can used this code free,absolutely free!
Second:of course,you can remove this header unconstrained!
but this header might useful if you sometimes want to kick my ass or praise me.
Copyright:none
Get more message on:http://blog.sina.com.cn/lipfreedom
Address:sunshiyang shenzhen city guangdong province china
E-mail:zyy6569@163.com
Create date:2010/10/14
Modify by: Zheng Xu 2015-12-2
********************************************************************************/
#include "Windows.h"
#include <QtCore/QCoreApplication>
#include <QtConcurrent/QtConcurrent>
#include "Observer.h"
#define SERVICE_NAME "Algalon"
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hServiceStatusHandle;
void WINAPI service_main(int argc, char** argv);
void WINAPI ServiceHandler(DWORD fdwControl);
TCHAR szSvcName[80];
SC_HANDLE schSCManager;
SC_HANDLE schService;
int uaquit;
std::fstream g_log;
QCoreApplication *g_pApp = nullptr;
void WINAPI ServiceHandler(DWORD fdwControl)
{
switch (fdwControl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
uaquit = 1;
//add you quit code here
if (g_pApp != nullptr)
{
g_pApp->exit();
}
break;
default:
return;
};
if (!SetServiceStatus(hServiceStatusHandle, &ServiceStatus))
{
DWORD nError = GetLastError();
}
}
void WINAPI service_main(int argc, char** argv)
{
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hServiceStatusHandle = RegisterServiceCtrlHandler(TEXT(SERVICE_NAME), ServiceHandler);
if (hServiceStatusHandle == 0)
{
DWORD nError = GetLastError();
}
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 9000;
if (!SetServiceStatus(hServiceStatusHandle, &ServiceStatus))
{
DWORD nError = GetLastError();
}
}
//*********************************************************
//Functiopn: IsInstalled
//Description: 判断服务是否已经被安装
//Calls:
//Called By:
//Table Accessed:
//Table Updated:
//Input:
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
BOOL IsInstalled()
{
BOOL bResult = FALSE;
//打开服务控制管理器
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM != NULL)
{
//打开服务
SC_HANDLE hService = ::OpenService(hSCM, TEXT(SERVICE_NAME), SERVICE_QUERY_CONFIG);
if (hService != NULL)
{
bResult = TRUE;
::CloseServiceHandle(hService);
}
::CloseServiceHandle(hSCM);
}
return bResult;
}
//*********************************************************
//Functiopn: Install
//Description: 安装服务函数
//Calls:
//Called By:
//Table Accessed:
//Table Updated:
//Input:
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
BOOL Install()
{
if (IsInstalled())
return TRUE;
//打开服务控制管理器
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
MessageBox(NULL, TEXT("Couldn't open service manager"), TEXT(SERVICE_NAME), MB_OK);
return FALSE;
}
// Get the executable file path
TCHAR szFilePath[MAX_PATH];
::GetModuleFileName(NULL, szFilePath, MAX_PATH);
//创建服务
SC_HANDLE hService = ::CreateService(
hSCM, TEXT(SERVICE_NAME), TEXT(SERVICE_NAME),
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, TEXT(""), NULL, NULL);
if (hService == NULL)
{
::CloseServiceHandle(hSCM);
MessageBox(NULL, TEXT("Couldn't create service"), TEXT(SERVICE_NAME), MB_OK);
return FALSE;
}
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return TRUE;
}
//*********************************************************
//Functiopn: Uninstall
//Description: 删除服务函数
//Calls:
//Called By:
//Table Accessed:
//Table Updated:
//Input:
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
BOOL Uninstall()
{
if (!IsInstalled())
return TRUE;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
MessageBox(NULL, TEXT("Couldn't open service manager"), TEXT(SERVICE_NAME), MB_OK);
return FALSE;
}
SC_HANDLE hService = ::OpenService(hSCM, TEXT(SERVICE_NAME), SERVICE_STOP | DELETE);
if (hService == NULL)
{
::CloseServiceHandle(hSCM);
MessageBox(NULL, TEXT("Couldn't open service"), TEXT(SERVICE_NAME), MB_OK);
return FALSE;
}
SERVICE_STATUS status;
::ControlService(hService, SERVICE_CONTROL_STOP, &status);
//删除服务
BOOL bDelete = ::DeleteService(hService);
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
if (bDelete)
return TRUE;
return FALSE;
}
void startServiceCtrlDispatcher()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = TEXT(SERVICE_NAME);
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)service_main;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServiceTable);
}
//do not change main function
int main(int argc, char *argv[])
{
g_log.open("c:\\algalon.log", std::ios_base::app);
if (argc == 2)
{
if (strcmp(argv[1], "-i") == 0 ||
strcmp(argv[1], "--install") == 0)
{
Install();
return 0;
}
else if (strcmp(argv[1], "-u") == 0 ||
strcmp(argv[1], "--uninstall") == 0)
{
Uninstall();
return 0;
}
}
g_pApp = new QCoreApplication(argc, argv);
g_log << "QCoreApplication create\n";
g_log.flush();
// 在这里,你可以创建任意你需要的Qt类——不包括窗口类……
// 在另一个线程中启动服务的控制分派机线程
QtConcurrent::run(startServiceCtrlDispatcher);
g_log << "ServiceCtrlDispatcher start\n";
g_log.flush();
int _rt = g_pApp->exec();
g_log << "QCoreApplication exit\n";
g_log.flush();
delete g_pApp;
return _rt;
}