学习写服务程序-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 3977290
  • 博文数量: 536
  • 博客积分: 10470
  • 博客等级: 上将
  • 技术积分: 4825
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-26 14:08
文章分类

全部博文(536)

文章存档

2024年(3)

2021年(1)

2019年(1)

2017年(1)

2016年(2)

2013年(2)

2012年(10)

2011年(43)

2010年(10)

2009年(17)

2008年(121)

2007年(252)

2006年(73)

分类:

2007-09-27 14:06:11

linux/unix下服务程序写了很多个了。也就是最终转换为后台的daemon就可以(run in the background),当然在这之前你一定要明白什么是进程,进程组,子进程,父进程等等相关的进程概念! 以前写这种东西的时候还是一个个的fork(), exit(), 但后来发现既然有一个daemon()函数,要想看更多的信息就查man daemon吧。

这次我主要想说的是怎么写windows下的服务程序,本人对vc用的不是很熟悉,就用哪个cl.exe, link.exe, nmake, makefile来个最原始的。
在这之前我看了一下 这篇文章。 自己来实践一下。

用普通的文本编辑器就可以完成的。
我的环境:
microsoft windows 2000 [version 5.00.2195]
(c) 凯发k8官网下载客户端中心的版权所有 1985-2000 microsoft corp.

c:\>echo %path%
c:\oracle\ora81\bin;c:\program files\oracle\jre\1.1.7\bin;c:\winnt\system32;c:\winnt;c:\winnt\system32\wbem;c:\program files\securecrt;c:\program files\microsoft visual studio\vc98\bin;c:\gan\windmp\dmp\bin;c:\program files\microsoft visual studio\common\tools\winnt;c:\program files\microsoft visual studio\common\msdev98\bin;c:\program files\microsoft visual studio\common\tools;c:\program files\microsoft visual studio\vc98\bin

所有的测试我全部在:
c:\gan\ts\svc下测试的。文件名为main.c

============================================

/**
 * author: gan
 * date: 2007-9-27
 * name: main.c
 */

#include <stdio.h>
#include <windows.h>

#define svc_sleep_time 1000
#define svc_log_filename "c:\\svc.log"

service_status svc_st;
service_status_handle svc_hd;

void servicemain(int argc, char **argv);
void controlhandler(dword request);
int svc_init(void);

/**
 * write log file
 */

int svc_write_log(const char *str)
{
    file *fp;

    fp = fopen(svc_log_filename, "a ");
    if (fp == null)
    {
      printf("file open error! \n");
      return (-1);
    }

    fprintf(fp, "%s\n", str);
    fclose(fp);

    return (0);
}

/**
 * initialize service
 */

int svc_init(void)
{
    int ret;

    printf("svc_init called. \n");

    ret = svc_write_log("svc_init called, started. ");
    return (ret);
}

void controlhandler(dword request)
{
    switch (request)
    {
      case service_control_stop:
      case service_control_shutdown:
        printf("monitoring started.\n");
        svc_write_log("monitoring started.");

        svc_st.dwwin32exitcode = 0;
        svc_st.dwcurrentstate = service_stopped;
        setservicestatus(svc_hd, &svc_st);
        return;

      default:
        break;
    }

    setservicestatus(svc_hd, &svc_st);
}

/**
 * service main function
 */

void servicemain(int argc, char **argv)
{
    char str[32];
    memorystatus mem;

    svc_st.dwservicetype = service_win32;
    svc_st.dwcurrentstate = service_start_pending;
    svc_st.dwcontrolsaccepted = service_accept_stop | service_accept_shutdown;
    svc_st.dwwin32exitcode = 0;
    svc_st.dwservicespecificexitcode = 0;
    svc_st.dwcheckpoint = 0;
    svc_st.dwwaithint = 0;

    printf("servicemain called. \n");

    svc_hd = registerservicectrlhandler("memorystatus", (lphandler_function)controlhandler);
    if (svc_hd == (service_status_handle)0)
    {
      printf("registerservicectlhandler error. \n");
      return;
    }

    if (svc_init())
    {
      svc_st.dwcurrentstate = service_stopped;
      svc_st.dwwin32exitcode = 0;
      setservicestatus(svc_hd, &svc_st);
      return;
    }

    svc_st.dwcurrentstate = service_running;
    setservicestatus(svc_hd, &svc_st);

    while (svc_st.dwcurrentstate == service_running)
    {
      globalmemorystatus(&mem);
      sprintf(str, "%d", mem.dwavailphys);

      printf(str);

      if (svc_write_log(str))
      {
        svc_st.dwcurrentstate = service_stopped;
        svc_st.dwwin32exitcode = -1;
        setservicestatus(svc_hd, &svc_st);
        return;
      }

      sleep(svc_sleep_time);
    }
}

int main(int argc, char *argv[])
{
    service_table_entry svc_tab[2];

    printf("main test started.\n");

    svc_tab[0].lpservicename = "memorystatus";
    svc_tab[0].lpserviceproc = (lpservice_main_function)servicemain;

    svc_tab[1].lpservicename = null;
    svc_tab[1].lpserviceproc = null;

    startservicectrldispatcher(svc_tab);

    return 0;
}



==================================
编译该程序[你可以看到cl在这可以直接使用是因为我自己修改了path环境变量,本来cl.exe link.exe全部是在vc中使用的工具]:
c:\gan\ts\svc>cl advapi32.lib main.c
microsoft (r) 32-bit c/c optimizing compiler version 12.00.8168 for 80x86
凯发app官方网站 copyright (c) microsoft corp 1984-1998. all rights reserved.

main.c
microsoft (r) incremental linker version 6.00.8168
凯发app官方网站 copyright (c) microsoft corp 1992-1998. all rights reserved.

/out:main.exe
advapi32.lib
main.obj

------
这地方编译的时候需要advapi32.lib的哦。如果没有结果就是:
c:\gan\ts\svc>cl main.c
microsoft (r) 32-bit c/c optimizing compiler version 12.00.8168 for 80x86
凯发app官方网站 copyright (c) microsoft corp 1984-1998. all rights reserved.

main.c
microsoft (r) incremental linker version 6.00.8168
凯发app官方网站 copyright (c) microsoft corp 1992-1998. all rights reserved.

/out:main.exe
main.obj
main.obj : error lnk2001: unresolved external symbol __imp__setservicestatus@8
main.obj : error lnk2001: unresolved external symbol __imp__registerservicectrlhandlera@8
main.obj : error lnk2001: unresolved external symbol __imp__startservicectrldispatchera@4
main.exe : fatal error lnk1120: 3 unresolved externals

-------
在连接(link.exe)的时候就找不到相关的函数了。

==================================
接下来就是安装服务:
c:\gan\ts\svc>sc create memorystatus binpath= c:\gan\ts\svc\main.exe
[sc] createservice success

==================================
如果不需要可以删除服务:
c:\gan\ts\svc>sc delete memorystatus
[sc] deleteservice success

==================================
其实写这些东西看起来很容易, 关键是要理解写的方法。
下一篇介绍原理及相关解释:
阅读(4193) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

g_hk2008-02-21 09:42:49

是的,刚开始学的时候用的。 但主要是学习这个: http://blog.chinaunix.net/u/19782/showart_399405.html 自己实践的,代码我绝对不是ctrl c,ctrl v来的,部分也同原来是不一样的。写上author:gan我认为没什么不可以。 关键是自己用这东西不多, 快忘了自己还写了个这个, 多谢谢! 想必老兄是windows研发下的高人,有机会多交流!qq:82787822

|

chinaunix网友2008-02-20 19:08:25

这个程序应该是 devx 上 yevgeny menaker 的原创吧?! 你不写明转载就算了,改了几个变量名称就能加上个什么 “author: gan” 变成你的了吗?! 这个有点过分了吧?!

|
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图