日历
网志分类
展开全部
· ***    All     ***
· ***    Mood    ***
· ***    Life    ***
· *** Technology ***
· ***     Yc     ***
· ***  Cartoon   ***
· *** Collection ***
· ***  Unsorted  ***
媒体播放器

Get the Flash Player to see this player.
SkyDrive is currently not available.

站内搜索
友情链接
· 我的歪酷 非非共享界
· 风雨妖虹
· kingbeful@csdn
· 手心的太阳@瞬间十年
· Moment@Travis
· 江南麒麟居
· εз毛线团εз
· 乌拉的neverland
· 碾过的日子 闲也陶陶
· 狡兔三窟 *^.^*
· 橄榄林的风
· 水色の街
· Powerful and delicate, Life struggling
· 阿德咖吧
· 陷阱
· 风之华
· vkobe的Neverland@@
· 白日梦已死 · 伤越夜海
· 望天
· 空の軌跡
· 没什么好东西的空间
· 心情...咖啡屋
· 随风独自凉
· Some where i belong
· .★·°双晨·故事°☆ .
· BigWorld的记事本
· *Sara's*
· 人生若只如初见
· 宠辱不惊闲看庭前花开花落·去留无意漫随天外云卷云舒
· 我思我不在
· 飞扬飘雨
· lazy的猫猫
常用链接
· [Google]
· [Google Accounts]
· [IT Items]
· [Telnet@Yanxi]
· [Wikipedia]
· [Linux Manpages]
· [Mofile.com]
· [163888.net]
· [fm.qq.com]
· [Proxy]
· [Animepaper.net]
· [FreeproxySite]
· [gonwan@fc2]
· [skydrive.live.com]
· [gonwan@lifelogger]

订阅 RSS

0109283

歪酷博客

逆さまの蝶
In this Craziness
Uncertainy
一人一人の想いを
僕らは何処かに遺せるだろうか

In this Craziness
You gave me life
一つの想いを
僕らは何処まで守れるだろうか



« 上一篇: 我能說什么呢 下一篇: Windows Service Howto (2) »
丸子·酱 @ 2008-01-25 23:57

    还是用中文写吧-.-

    首先是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(...);
}

    好了, 请继续看下文.


曾经的这一天...



评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定