使用VS2010创建Windows ATL Service

使用VS2010创建Windows ATL Service

使用VS2010创建一个ATL服务项目

第一步
这里写图片描述
第二步
这里写图片描述
第三步
这里写图片描述

编码

创建好之后, 重写父类的以下方法

1
2
3
4
5
6
7
8
9
10
HRESULT RegisterAppId(bool bService = false) throw ();
void ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv);
HRESULT PostMessageLoop();
void Handler(DWORD dwOpcode);
void OnStop();
void OnPause();
void OnContinue();
void OnInterrogate();
void OnShutdown();
HRESULT PreMessageLoop(int nShowCmd);

全部代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// MyService.cpp : WinMain 的实现


#include "stdafx.h"
#include "resource.h"
#include "MyService_i.h"


#include <stdio.h>

class CMyServiceModule : public ATL::CAtlServiceModuleT< CMyServiceModule, IDS_SERVICENAME >
{
public :
DECLARE_LIBID(LIBID_MyServiceLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MYSERVICE, "{38D52E46-9042-4AC9-9D57-4A13E350B4EF}")
HRESULT InitializeSecurity() throw()
{
// TODO : 调用 CoInitializeSecurity 并为服务提供适当的安全设置
// 建议 - PKT 级别的身份验证、
// RPC_C_IMP_LEVEL_IDENTIFY 的模拟级别
// 以及适当的非 null 安全说明符。

return S_OK;
}

HRESULT RegisterAppId(bool bService = false) throw ();
void ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv);
HRESULT PostMessageLoop();
void Handler(DWORD dwOpcode);
void OnStop();
void OnPause();
void OnContinue();
void OnInterrogate();
void OnShutdown();
HRESULT PreMessageLoop(int nShowCmd);


};

CMyServiceModule _AtlModule;


//
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
LPTSTR /*lpCmdLine*/, int nShowCmd)
{
return _AtlModule.WinMain(nShowCmd);
}


HRESULT CMyServiceModule::RegisterAppId(bool bService ) throw ()
{
HRESULT hr = S_OK;
BOOL res = __super ::RegisterAppId(bService);
if (bService)
{
if (IsInstalled())
{
SC_HANDLE hSCM = ::OpenSCManagerW(NULL, NULL, SERVICE_CHANGE_CONFIG);
SC_HANDLE hService = NULL;
if (hSCM == NULL)
{
hr = ATL::AtlHresultFromLastError();
}
else
{
hService = ::OpenService(hSCM, m_szServiceName, SERVICE_CHANGE_CONFIG);
if (hService != NULL)
{
::ChangeServiceConfig(hService, SERVICE_NO_CHANGE,
SERVICE_AUTO_START,// 修改服务为自动启动
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
m_szServiceName); // 通过修改资源IDS_SERVICENAME 修改服务的显示名字

SERVICE_DESCRIPTION Description;
TCHAR szDescription[1024];
ZeroMemory(szDescription, 1024);
ZeroMemory(&Description, sizeof (SERVICE_DESCRIPTION));
lstrcpy(szDescription, _T("测试服务描述信息" ));
Description.lpDescription = szDescription;
::ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &Description);
::CloseServiceHandle(hService);
}
else
{
hr = ATL::AtlHresultFromLastError();
}
::CloseServiceHandle(hSCM);
}
}
}
return hr;
}

void CMyServiceModule::ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
// TODO: 在此添加专用代码和/或调用基类

//log(_T("invoke methode ServcieMain\n"));
__super::ServiceMain(dwArgc,lpszArgv);
//CAtlServiceModuleT::ServiceMain(dwArgc, lpszArgv);
}


HRESULT CMyServiceModule::PostMessageLoop()
{
// TODO: 在此添加专用代码和/或调用基类
//log(_T("invoke methode POstMessageLoop\n"));
return CAtlServiceModuleT::PostMessageLoop();
}


void CMyServiceModule::Handler(DWORD dwOpcode)
{
// TODO: 在此添加专用代码和/或调用基类
//log(_T("invoke methode Handler with parameter\n"));
__super::Handler(dwOpcode);
}


void CMyServiceModule::OnStop() throw()
{
//log(_T("invoke OnStop\n"));
// m_serverListener.stopServer();
//log("停止服务监听");
__super::OnStop();
}

void CMyServiceModule::OnPause() throw()
{
//log(_T("invoke OnPause\n"));
__super::OnPause();
}

void CMyServiceModule::OnContinue() throw()
{
//log(_T("invoke OnContinue\n"));
__super::OnContinue();
}

void CMyServiceModule::OnInterrogate() throw()
{
//log(_T("invoke OnInterrogate\n"));
__super::OnInterrogate();

}

void CMyServiceModule::OnShutdown() throw()
{
//log(_T("invoke OnShutdown\n"));
__super::OnShutdown();
}


HRESULT CMyServiceModule::PreMessageLoop(int nShowCmd)
{
// TODO: 在此添加专用代码和/或调用基类
HRESULT res= CAtlServiceModuleT::PreMessageLoop(nShowCmd);
//log(_T("invoke method PreMessageLoop\n"));
if(SUCCEEDED(res)){

//SetServiceStatus(SERVICE_RUNNING);
//m_serverListener.startServer();
//log("启动服务监听");
}

return res;
}

安装

使用cmd切换到项目输出目录,使用程序名.exe /Service
这里写图片描述

然后打开服务管理页面,就可以看到我们刚才安装的服务了
这里写图片描述

启动服务会出现
这里写图片描述

这个错误已经有人解决了,我们安装这个方法修改后,重新编程程序,再次使用 程序名.exe /Service 命令安装服务,然后在服务管理器中启动服务,运行了比较久出现如下错误
这里写图片描述
这个问题有人解决了,参考修改后,重新编译下代码,就可以了
这里写图片描述

我花了半天时间才写出来。1053那个错误,值得注意