还是用中文写吧-.-
首先是Windows NT service的大致框架, 用的是Win32 API, 如果你要看.NET的service怎么写, 可以飘走了.
1. 首先要安装一个service, 即注册一个service到SCM(Service Control Manager):
SC_HANDLE hServiceControlManager = OpenSCManager(...); // 拿到SCM的handle
SC_HANDLE hService = CreateService(...); // 创建service, 老长的参数反正-.-
注意权限的控制, 最后记得所有的handle都要close掉.
2. 卸载-.-, 也是一样:
SC_HANDLE hServiceControlManager = OpenSCManager(...); // 拿到SCM的handle.
SC_HANDLE hService = OpenService(...); // 拿到你要卸载的service的handle, 可以通过service的name.
DeleteService(hService); // delete, 明显.
3. 好了, 通过安装之后, service的列表里面应该可以看到你自己的service了, 然后就是具体的service控制怎么写了. service其实也就是一个console的程序, 只是一直在后台polling, 比如等待某些event, 然后做相应处理. 这么说来, 你一定知道了, service里面通常会有一个while(TRUE) 的循环, 嗯, bx.
a) service也是一个process, 而非M$的service似乎只能写成exe(M$的可以跑在svchost这个process里面, 似乎是这个东西权限太高), 所以service的entry point也是main函数(当然wmain也是可以的-.-, WinMain, wWinMain就募集了, 自己玩吧-.-).
b) main函数的主要工作就是调用StartServiceCtrlDispatcher这个API, 作用是连接到SCM, 并且dispatch当前service的thread. 这个API会传入一个SERVICE_TABLE_ENTRY的数组结构, 包含service的name和starting point回调函数, 也就是说大概是这个样子的:
int _tmain(int argc, TCHAR* argv[])
{
SERVICE_TABLE_ENTRY serviceTableEntry[] =
{
{ TEXT( "service_name"), (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};
StartServiceCtrlDispatcher(serviceTableEntry);
return 0;
}
// 不好意思, 用的都是Unicode和MBCS兼容的写法.
c) 然后就是ServiceMain这个回调函数了, service最主要的函数, 所有的处理都是在这里完成的, 包括那个while(TRUE).
函数第一步必须要注册一个service control的handler, 用来控制比如start, stop之类的操作, 这样就可以在windows自己的service列表那边控制了.
第二步则是一些初始化准备进入while(TRUE)循环. 需要注意的是, service的状态的每一次改变, 最好都调用SetServiceStatus这个API, 以便通知系统更新状态, 比如start pending, start, stop pending, stop之类.
第三步, 到while(TRUE)里面去吧, 做你自己的事情. 一般会定义一个event, 然后当这个event变成signal的时候从while循环里面推出, 然后结束service.
第四步, 也就是说从while循环里面出来了, 也就是这个sevice要stop了, 那么做一些uninitialize的工作吧, 还是记得要时常调用SetServiceStatus.
嗯, 来看一下大概的样子吧, 一定要注意这是一个回调函数:
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
g_hServiceStatusHandle = RegisterServiceCtrlHandler(TEXT( "service_name"), ServiceCtrlHandler);
if (g_hServiceStatusHandle)
{
g_hEvtServiceStop = CreateEvent(...); // 初始化一个event吧.
SetServiceStatus(...); // 时不时调用一把.
while (TRUE)
{
// 在这里自己爽去吧-.-, 暂且Beep吧.
Beep(...);
Sleep(...);
DWORD dwRet = WaitForSingleObject(...); // 等那个stop的event, 然后看是不是要break掉.
if (dwRet == ...)
{
break;
}
}
CloseHandle(g_hEvtServiceStop); // 统统关掉-.-
SetServiceStatus(...); // 时不时调用一把.
}
}
d) 最后是传给RegisterServiceCtrlHandler的ServiceCtrlHandle这个回调函数, 作用已经说过了, 大概是这个样子:
void WINAPI ServiceCtrlHandler(DWORD fdwControl)
{
switch (fdwControl)
{
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
SetEvent(g_hEvtServiceStop); // 弄成signal的.
SetServiceStatus(...); // 通知更新的service状态.
return;
default:
break;
}
SetServiceStatus(...);
}
好了, 请继续看下文.



