Windows Service (ATL)

一、基本过程

1、创建

Visual Studio 2008 -> 新建项目 -> ATL -> 服务(EXE)

 

2、注册

(1)、服务的注册:命令行输入 MyService.EXE /Service   (或MyService /Service)

(2)、服务的删除:SC DELETE MyService   (服务名,非文件名)

 

(本地服务器注册:MyService /RegServer 或 MyService -RegServer;

注销:MyService /UnRegServer 或 MyService -UnRegServer

 

注:方便起见,一般用文件名进行注册和删除:

MyService /Service

MyService /UnRegServer

 

3、在stdafx.h中添加:#define _ATL_NO_COM_SUPPORT

因为PreMessageLoop()没有返回S_OK,而是尝试注册COM对象,如果Windows Service不包含COM组件,则需加上此句

 

4、重载CAtlServiceModuleT::Run()函数:

HRESULT CMyServiceModule::Run(int nShowCmd = SW_HIDE) throw()

{

OutputDebugString(L"\nRun");                                       //输出信息到调试窗口

LogEvent(L"\nRun");                                                            //输出信息到事件查看器

SetTimer(NULL,1,2000,(TIMERPROC)OnTimerProc); //设置定时器

 

DWORD  dwID;

HANDLE hThread;

hThread = ::CreateThread(0, 0, MyThreadWrapper, (void*)this,0,&dwID); //开启新线程

 

return __super::Run();

}

//定时器函数

VOID CALLBACK OnTimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)

{

_AtlModule.MyProc();

}

void CMyServiceModule::MyProc()

{

static int n=0;

n++;

CString str;

str.Format(L"%i",n);

LogEvent(str);                                          

}

 

5、重载CAtlServiceModuleT::OnStop()函数:

//停止服务

void CMyServiceModule::OnStop() throw()

{

OutputDebugString(L"\nOnStop");

LogEvent(L"OnStop");

__super::OnStop();

}

 

6、最好在Run中启动多线程,参见线程管理器类

 

二、修改服务的配置

 

 

代码
HRESULT CtestserviceModule::RegisterAppId(bool bService)
{
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
= 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(
"Windows服务示例,by zhouping2000@gmail.com")); //修改服务说明
Description.lpDescription = szDescription;
::ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION,
&Description);
::CloseServiceHandle(hService);
}
else
hr
= AtlHresultFromLastError();
::CloseServiceHandle(hSCM);
}
}
}
return hr;
}

 

 

三、定时器

 

 

代码
VOID CALLBACK OnTimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)
{
_AtlModule.Adder();
}

extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
LPTSTR
/*lpCmdLine*/, int nShowCmd)
{
//只是为演示;应该在重载Run()函数

SetTimer(NULL,
1,2000,(TIMERPROC)OnTimerProc);

MSG msg;
while(GetMessage(&msg,0,0,0))
DispatchMessage(
&msg);

return _AtlModule.WinMain(nShowCmd);
}

void CMyServiceModule::Adder()
{
n
++;
CString str;
str.Format(L
"%i",n);
LogEvent(str);
//写入事件查看器
}

 

 

四、重载Windows Service运行函数Run()

代码
HRESULT CMyServiceModule::Run(int nShowCmd = SW_HIDE) throw()
{
SetTimer(NULL,
1,2000,(TIMERPROC)OnTimerProc);//应该在GetMessage()循环之上

MSG msg;
while(GetMessage(&msg,0,0,0))
DispatchMessage(
&msg);
return S_OK;
}

 

posted @ 2010-07-07 16:41  宝哥哥  阅读(3007)  评论(0编辑  收藏  举报