windows service程序的入门范例(一)

Windows Service 程序编写方法

1.最简单的创建一个windows service程序
(1)新建一个win32控制台程序
(2)开始->运行->cmd,必须右键—>以管理员身份运行,此时进入dos命令提示符界面。
(3)输入 sc create test binPath= “D:\Code_Test\VS2012_test\test_console\test_console\Release\test_console.exe”
 
图1


【注意】等号“=”后面,必须空一格,否则可能报错。


2.查看已经创建的服务
(1)开始->附件->运行->输入:services.msc

(2)进入系统的服务界面,可看到新创建的test服务。如下图2所示。


图2 查看服务
3.删除一个服务程序
进入命令提示符,输入指令:sc delete test
 
图3 删除一个服务


4.程序实例
4.1 概述

(1)由于service程序,不需要界面,我们在建工程的时候,建立一个控制台程序即可。常规的控制台程序如下图4所示。
 
图4 常见的控制台程序


(2)main函数的使用方法
由于windows服务不需要界面,所以大部分程序为win32控制台应用程序,所以程序主函数为main 而不是WinMain()。在主函数要做的主要工作就是两件事:
初始化一个SERVICE_TABLE_ENTRY 分派表结构体。
然后调用StartServiceCtrlDispatcher();这将把调用进程的主线程转换为控制分派器。该分派器启动一个新线程,该线程运行分派表中对应于你的服务的ServiceMain()函数。ServiceMain()函数将在下面提到。



4.2 ServiceMain()函数用法
ServiceMain函数为void WINAPI ServiceMain(int argc, char** argv)格式的函数,函数名字可以任意定义。它的作用就是:将你需要执行的任务放到该函数中循环执行即可。
ServiceMain()就是服务程序的工作函数。
在ServiceMain执行你的任务前,需要给SERVICE_TABLE_ENTRY 分派表结构体进行赋值,注意由于此时服务还没有开始执行你的任务所以我们将服务的状态设置为SERVICE_START_PENDING,即正在初始化。


4.3 程序代码
以下代码,为全部的代码,可以直接运行,已经验证通过。
(1) 新建一个控制台程序
(2) 在main()所在的文件里面,使用以下代码

(3) 这个代码的功能,是每隔5s,打印一条日志到日志文件C:\\log.txt里面。


##########################################################################

// test_console.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <windows.h>

using namespace std;

#define SLEEP_TIME 5000 //间隔时间

#define FILE_PATH "C:\\log.txt" //信息输出文件

bool brun=false;

SERVICE_STATUS servicestatus;

SERVICE_STATUS_HANDLE hstatus;

int WriteToLog(char* str);

void WINAPI ServiceMain(int argc, char** argv);

void WINAPI CtrlHandler(DWORD request);

int InitService();

int WriteToLog(char* str)
{

	FILE* pfile;
	fopen_s(&pfile,FILE_PATH,"a+");
	if (pfile==NULL)
	{
		return -1;
	}
	fprintf_s(pfile,"%s\n",str);
	fclose(pfile);
	return 0;
}

void WINAPI ServiceMain(int argc, char** argv)
{
	servicestatus.dwServiceType = SERVICE_WIN32;
	servicestatus.dwCurrentState = SERVICE_START_PENDING;
	servicestatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_STOP;//在本例中只接受系统关机和停止服务两种控制命令
	servicestatus.dwWin32ExitCode = 0;
	servicestatus.dwServiceSpecificExitCode = 0;
	servicestatus.dwCheckPoint = 0;
	servicestatus.dwWaitHint = 0;

	hstatus = ::RegisterServiceCtrlHandler(L"testservice", CtrlHandler);

	if (hstatus==0)

	{

		WriteToLog("RegisterServiceCtrlHandler failed");
		return;

	}

	WriteToLog("RegisterServiceCtrlHandler success");

	//向SCM 报告运行状态

	servicestatus.dwCurrentState = SERVICE_RUNNING;

	SetServiceStatus (hstatus, &servicestatus);

	//下面就开始任务循环了,你可以添加你自己希望服务做的工作

	brun=true;

	MEMORYSTATUS memstatus;

	char str[100];

	memset(str,'\0',100);

	while (brun)
	{
		GlobalMemoryStatus(&memstatus);
		int availmb=memstatus.dwAvailPhys/1024/1024;
		sprintf_s(str,100,"available memory is %dMB",availmb);
		WriteToLog(str);
		Sleep(SLEEP_TIME);
	}
	WriteToLog("service stopped");
}

void WINAPI CtrlHandler(DWORD request)
{
	switch (request)
	{
	case SERVICE_CONTROL_STOP:
		brun=false;
		servicestatus.dwCurrentState = SERVICE_STOPPED;
		break;

	case SERVICE_CONTROL_SHUTDOWN:
		brun=false;
		servicestatus.dwCurrentState = SERVICE_STOPPED;
		break;

	default:
		break;
	}

	SetServiceStatus (hstatus, &servicestatus);
}


int _tmain(int argc, _TCHAR* argv[])
{
	SERVICE_TABLE_ENTRY entrytable[2];

	entrytable[0].lpServiceName= L"testservice";

	entrytable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain;

	entrytable[1].lpServiceName=NULL;

	entrytable[1].lpServiceProc=NULL;

	StartServiceCtrlDispatcher(entrytable);

	return 0;
}



大家运行程序,会生成一个exe文件。

(4)以管理员身份,运行命令提示符 cmd.exe
 
首先,注册服务(注意, 代码里面的服务名称是testservice,此处要一致)
sc create testservice binPath= “D:\Code_Test\VS2012_test\test_console\test_console\Debug\test_console.exe”
②    然后,启动服务(注意,服务名称要写对)
sc start testservice
服务的运行结果如下图5所示:
 
图5 后台服务写日志成功


关闭服务和删除服务
             sc stop testservice

             sc delete testservice


图6 关闭与删除



 



------------------------------------------------

以上例子,已经验证通过,大家可以放心使用。



时间:2016.09.09

作者:小龙

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
《Visual C#.NET范例入门与提高》配套光盘使用说明 本书所附光盘的内容包含了开发实例的所有程序源码,所有程序源码都是在Win2000 Professional,Visual C#.NET环境下编译并运行通过。要运行本光盘上的实例,用户应首先安装Visual C#.NET,另外本书中部分例子属于ASP.NET应用程序,用户必须安装ASP.NET的相应环境,具体方法本书有介绍。另外如果有些程序在其他操作系统下无法直接运行,请读者根据原书中的操作步骤自行编写程序。 第2章的ch2_6,ch2_7,ch2_10,需要使用的图片在光盘目录pic下。 第5章中ch5_1,ch5_2两例使用的是Win2000 Professional原始的Windows Media Player组件,如果用户升级了Windows Media Player到其他版本,则会无法直接运行这两个例子,但书中的方法仍然有效,读者可以自己模仿编写新的程序,或者卸载新安装的Windows Media Player版本即可直接运行本盘中的程序。 运行第6章的例子前,必须先安装Microsoft Access和SQL Server软件,其中需要使用的Access数据库已经放在ch6目录下,读者可根据书中的具体说明自行设计数据库的存放路径,此外还必须能够访问安装在Microsoft SQL Server 2000或者SQL Server 2000 Desktop Engine下面的Northwind 数据库,具体的安装办法见书。例子CH6.6属于ASP.NET应用程序,默认路径应存放在D:\Inetpub\WWWROOT(如果操作系统在C盘,则为C:\Inetpub\WWWROOT,下同)目录下,为方便起见,将源程序附于光盘目录localhost下。 第8章的Web Service应用程序中,首先需要安装IIS服务,以及进行正确的FrontPage首页配置(这一步如果安装的操作系统是Windows 2000 Service版本,或者重新安装了IIS5.0以上版本后,也可以不执行)。最后将Web 服务复制到D:\Inetpub\wwwroot子文件夹中,否则将不能正确调用Web服务。为方便起见,将WebService的源程序附于光盘目录localhost下。 另外ch9_2是制作一个控件,直接运行不了,且无任何意义,需要结合Textloginbox项目来使用。9.9节对应“ch9其它文件夹”中的Setup子目录,也不能直接运行,它示范的是一个安装程序,可以在Setup的debug子目录下测试这个安装程序。 读者需要将光盘上的文件拷贝到本地磁盘,去掉“只读”属性后即可编译运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值