Windows服务编译遇到的一些问题

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

这次我主要想说的是怎么写Windows下的服务程序,本人对VC用的不是很熟悉,就用哪个cl.exe, link.exe, nmake, makefile来个最原始的。
在这之前我看了一下 http://www.vckbase.com/document/viewdoc/?id=1474 这篇文章。 自己来实践一下。

用普通的文本编辑器就可以完成的。
我的环境:
Microsoft Windows 2000 [Version 5.00.2195]
(C) 版权所有 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
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

main.c
Microsoft (R) Incremental Linker Version 6.00.8168
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
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

main.c
Microsoft (R) Incremental Linker Version 6.00.8168
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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值