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中启动多线程,参见线程管理器类

 

二、修改服务的配置

 

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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;
}

 

 

三、定时器

 

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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()

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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;
}

 

转载于:https://www.cnblogs.com/followmyheart/articles/1772974.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值