如何c编写windows程序服务程序

前段时间做一个数据迁移项目,刚开始用B/S架构做的项目,但B/S要寄存在IIs中,而IIs又不稳定因素,如果重启IIs就要打开页面才能运行项目。有不便之处,就改用Windows服务实现。这篇就总结下,windows服务的编写,调试,安装卸载。
Windows服务介绍
Microsoft Windows 服务能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序。这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面。这使服务非常适合在服务器上使用,或任何时候,为了不影响在同一台计算机上工作的其他用户,需要长时间运行功能时使用。还可以在不同于登录用户的特定用户帐户或默认计算机帐户的安全上下文中运行服务。本文就向大家介绍如何运用Visual C#来一步一步创建一个文件监视的Windows服务程序,然后介绍如何安装、测试和调试该Windows服务程序。
创建Windows服务
创建好项目之后 --- && 双击&Service1.cs &---- && &出现一个设计界面 & ----&& 右键界面 &--- && 弹出对话框选择添加安装程序
上面一系列操作完成后,就可以对windows服务名称描述以及启动方式等进行修改。
[RunInstaller(true)]
public class Installer1 : System.Configuration.Install.Installer
/// &summary&
/// 必需的设计器变量。
/// &/summary&
private ponentModel.Container components = null;
private System.ServiceProcess.ServiceProcessInstaller spI
private System.ServiceProcess.ServiceInstaller sI
public Installer1()
// 该调用是设计器所必需的。
InitializeComponent();
// TODO: 在 InitComponent 调用后添加任何初始化
#region Component Designer generated code
/// &summary&
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// &/summary&
private void InitializeComponent()
components = new ponentModel.Container();
// 创建ServiceProcessInstaller对象和ServiceInstaller对象
this.spInstaller = new System.ServiceProcess.ServiceProcessInstaller();
this.sInstaller = new System.ServiceProcess.ServiceInstaller();
// 设定ServiceProcessInstaller对象的帐号、用户名和密码等信息
this.spInstaller.Account = System.ServiceProcess.ServiceAccount.LocalS
this.spInstaller.Username = null;
this.spInstaller.Password = null;
// 设定服务名称
this.sInstaller.ServiceName = "PmsDataUpdateService";
//服务描述
this.sInstaller.Description = "hi longhao !";
// 设定服务的启动方式
this.sInstaller.StartType = System.ServiceProcess.ServiceStartMode.A
this.Installers.AddRange(
new System.Configuration.Install.Installer[] { this.spInstaller, this.sInstaller });
#endregion
修改好后回头,写入自己想要的操作。Service1.cs出现设计界面,双击设计界面进入cs代码页。可以重写这些方法。
protected override void OnStart(string[] args)
//服务开启执行代码
protected override void OnStop()
//服务结束执行代码
protected override void OnPause()
//服务暂停执行代码
base.OnPause();
protected override void OnContinue()
//服务恢复执行代码
base.OnContinue();
protected override void OnShutdown()
//系统即将关闭执行代码
base.OnShutdown();
除此之外还有一个Program.cs文件:打开看下。
使得一个Windows服务程序能够正常运行,我们需要像创建一般应用程序那样为它创建一个程序的入口点。在Windows服务程序中,我们也是在Main()函数中完成这个操作的。首先我们在Main()函数中创建一个Windows服务的实例,该实例应该是ServiceBase类的某个子类的对象,然后我们调用由基类ServiceBase类定义的一个Run()方法。然而Run()方法并不就开始了Windows服务程序,我们必须通过前面提到的服务控制管理器调用特定的控制功能来完成Windows服务程序的启动,也就是要等到该对象的OnStart()方法被调用时服务才真正开始运行。如果你想在一个Windows服务程序中同时启动多个服务,那么只要在Main()函数中定义多个ServiceBae类的子类的实例对象就可以了,方法就是创建一个ServiceBase类的数组对象,使得其中的每个对象对应于某个我们已预先定义好的服务。
/// &summary&
/// 应用程序的主入口点。
/// &/summary&
static void Main()
ServiceBase[] ServicesToR
ServicesToRun = new ServiceBase[]
new Service1(),
new Service2()
ServiceBase.Run(ServicesToRun);
如果你在你需要的函数里面写过你需要的方法后,点运行则不可运行。
安装卸载windows服务
1、安装需要用,这个小玩意可以在网上下载到的。
2、把他放到你编写好的服务程序/bin/Debug文件夹下。
4、用命令读到你服务.exe文件夹下。
5、运行&installutil.exe&
6、安装服务命令:&installutil &yourservices.exe
7、卸载服务命令:&installutil &/u &yourservices.exe
注意的是:安装跟卸载需要保证程序是一样的,没有变更过的,要不会提示卸载不干净。也就是在已安装过服务的时候,不要在vs中修改你的程序。
调试windows服务
保证你的服务已安装成功,且处于启动模式。
点调试---&& 附加到进程
注意的是:
打开任务管理器:结束进程。
阅读(...) 评论()编写 Window 服务程序-.NET教程,Windows开发-虚拟主机资讯|虚拟主机动态
产品服务快速通道
----------------
==域名注册==
英文域名注册
中文域名注册
==网站推广==
==虚拟主机==
----------------
双线路虚拟主机
基本型虚拟主机
商用型虚拟主机
论坛型虚拟主机
功能型虚拟主机
Vip合租虚拟主机
虚拟主机性能对比
虚拟主机免费试用
机房速度测试
----------------
==租用托管==
服务器租用
----------------
==企业邮局==
购买企业邮局
----------------
==付款方式==
----------------
==联系我们==
您当前位置:->-> ->
编写 Window 服务程序-.NET教程,Windows开发
作者:网友供稿
  西部数码-全国虚拟主机10强!20余项管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金!
文章页数:&
编写 window 服务程序&&一、直观认识windows服务。&&&&&& 打开windows“控制面板/管理工具/服务”,系统显示windows服务列表。&&&&&& &&&&&&& 双击服务,可以显示和更改服务属性。在这个对话框中,可以控制服务的启动、暂停和停止。在这里还可以配置服务的启动类型,令服务在系统启动时自行启动。因此,windows服务经常作为服务器程序运行。&&&&&& &&&&&& 在故障恢复这个属性页,可以配置该服务失败后系统的相应。一些病毒程序就是在这里做文章,将病毒程序激活的。&&&&&& &二、windows服务的开发要点&&&&&&& visual studio的随机文档里,详细介绍了windows服务程序的开发步骤,并且带有实例,笔者不再赘述。读者只需注意几个要点:&&&&&&& 1、创建一个派生自servicebase的入口类。这个入口类管理这个windows服务的生存期。&&&&& public class myservice : system.serviceprocess.servicebase&&&& {&&&&&&&& ……&&&& }&&&&&&&& 2、在入口类的main方法里将服务向windows的服务控制器(service control manager, scm)注册,代码:&&&&&&& ……&&&&&&&& system.serviceprocess.servicebase[]&&&&&&&& servicestorun = new system.serviceprocess.servicebase[] { new myservice() };&&&&&&&& system.serviceprocess.servicebase.run(servicestorun);&&&&&&&& ……&&&&&&&& 3、重写 onstart 、onstop ,或onpause 和 oncontinue 方法来响应服务状态的更改。通常需要重写 onstart 方法,结束服务时在 onstop 方法中释放资源,酌情重写onpause 和 oncontinue方法。&&&&&&& 4、windows服务通常启动一个定时器来定时或轮询进行业务处理。&&&&&&& 5、windows服务需要安装后才能使用。通常通过两个办法安装windows服务:在命令行运行installutil.exe;在windows服务程序的代码中添加projectinstraller类的实例,里面包含serviceprocessinstaller类和serviceinstaller类的实例。&&&&&&& 上述两个办法在framework的随机文档中均有描述,在此不再赘述。&&&&&&& 6、windows服务在windows的服务控制器(service control manager, scm)中运行,因此调试起来不像其他visual studio应用程序那样简单。关于windows服务的调试,在visual studio的随机文档里面有介绍,在此不再赘述。三、windows服务的异常处理&&&&&&& windows服务没有用户界面,在运行过程中难以将异常通知给用户。通常情况下,windows服务在运行过程中发生了异常,可能导致服务运行挂起,但没有任何提醒。&&&&&&& 推荐的一个做法是在windows服务中捕获异常,并把异常信息写在windows的事件日志中。打开windows的“控制面板/管理工具/事件查看器”,系统显示windows事件日志。&&&&&&& &&&&&&& 在一个实际的应用中,笔者除了把异常和提示记录在事件日志中,还把严重错误自动通过邮件发送给相关人员。同时,所有记录在事件日志中的信息,还重定向到一个自行开发的控制台程序中,用以随时监控服务。&&&&&&& 三、windows事件日志的开发要点和技巧&&&&&&& visual studio的随机文档里,在介绍windows服务程序的开发步骤的同时,也介绍了如何向windows服务中加入事件日志,笔者不再赘述。开发要点如下:&&&&&&& 1、在需要写入日志的类中创建eventlog的实例eventlog,在构造函数里加入代码:&&&& if (!system.diagnostics.eventlog.sourceexists("mysource")) &&&& {&&&&&&&& &&&& system.diagnostics.eventlog.createeventsource("mysource","myeventlog");&&&& }&&&& eventlog.source = " mysource ";&&&& eventlog.log = " myeventlog ";&&& 2、在需要写事件日志的地方写日志,例如:&&&& protected override void onstop()&&&& {&&&&&&&& eventlog.writeentry("in onstop."); &&&& }&&&&&&&&& 读者可以在实际应用中尝试使用下面的技巧。&&&&&&&& 1、把写windows事件日志的代码封装成独立的class,这样不仅在windows服务中,而且在其他的业务代码中都可以使用windows事件日志。代码见附件。&&&&&&& 2、为方便调试和跟踪,visual sdudio提供了trace类。在应用程序的debug编译版本中,用trace类可以把调试和跟踪信息写到控制台。有一个技巧,可以同时把写入trace的内容写入windows事件日志。要点如下:&&&&&&& 首先声明一个事件监听类eventlogtracelistener的实例,&&&&&&&&&&static private& eventlogtracelistener ctracelistener = new eventlogtracelistener( m_eventlog );&&&&&&& 将eventlogtracelistener的实例加入trace的监听列表:&&&&&&&& &trace.listeners.add( ctracelistener );&&&&&&& 此后,凡是写入trace的调试信息,均写入windows事件日志中。如果不希望将trace继续写入事件日志,运行下面代码即可:&&&&&&&& &trace.listeners.remove( ctracelistener );&&& &&&&& & 3、写入事件日志的信息,还可以同时写入其他应用程序窗体中的显示控件。&&&&&&& 首先打开窗体的设计视图,从工具箱/组件中选择eventlog并加入窗体,配置eventlog的enableraisingevents属性为true。&&&&&&& 加入eventlog的entrywritten事件处理方法,该事件的第二个参数类行为system.diagnostics.entrywritteneventargs,其中包含了windows事件日志条目中的必要内容,将该内容显示在窗体中的某个显示控件中即可。示例代码如下:/// &summary&/// 监听事件日志/// &/summary&/// &param name="sender"&&/param&/// &param name="e"&&/param&private void eventlog_entrywritten(object sender, &&&& system.diagnostics.entrywritteneventargs e){&&&& try&&&& {&&&&&&&& // 把日志内容写到名为listeventlog的list控件中&&&&&&&& listeventlog.items.insert( 0, &&&&&&&&&&&&& e.entry.timewritten + " " +&&&&&&&&&&&&& e.entry.message );&&&&&&&&& // list控件保存不超过500行的日志&&&&&&&& while( listeventlog.items.count & 500 )&&&&&&&& {&&&&&&&&&&&&& listeventlog.items.removeat( listeventlog.items.count-1 );&&&&&&&& }&&&& }&&&& catch( exception ex )&&&& {&&&&&&&& messagebox.show( ex.message );&&&& }}四、与windows服务的通讯&&&&&& 在应用程序或其他服务中,可以与windows服务通讯,包括:&&&&&&&& 管理windows服务的生命期,即开启、停止、暂停和重启服务;&&&&&&&& 获得windows服务的属性和状态;&&&&&&&& 获得特定计算机上的服务列表;&&&&&&&& 向特定的服务发送命令。&&&&&&& 这些操作是通过servicecontroller 类完成的。servicecontroller是一个可视化控件,可以在工具箱中找到。&&&&&&& 比较有意思的是servicecontroller 中executecommand这个方法,调用这个方法,可以向windows服务发送命令,指挥windows服务的一些操作。例如,在windows服务的入口类中有一个复写oncustomcommand()的方法:&&&&&&&& /// &summary&&&&&&&&& /// 执行用户自定义消息&&&&&&&& /// &/summary&&&&&&&&& /// &param name="command"&消息编号&/param&&&&&&&&& protected override void oncustomcommand( int command )&&&&&&&& {&&&&&&&&&&&&& try&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&& switch( command )&&&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&&&& case 1: // 业务操作&&&&&&&&&&&&&&&&&&&&&&&&&&& dobusiness1();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& case 2: //业务操作&&&&&&&&&&&&&&&&&&&&&&&&&&& dobusiness2();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& default:&&&&&&&&&&&&&&&&&&&&&&&&&&& ……&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&& }&&&&&&&&&&&&& catch( exception ex )&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&& // 错误信息&&&&&&&&&&&&&&&&&& string strerrormsg = string.format("异常:{0}\n", ex.message );&&&&&&&&&&&&&&&&&& // 写日志&&&&&&&&&&&&&&&&&& tlineeventlog.dowriteeventlog( strerrormsg, eventtype.error );&&&&&&&&&&&&&&&&&& // 给管理员发邮件&&&&&&&&&&&&&&&&&& cmail.sendmail( propertymanager.strmailfromaddress, propertymanager.strmailadminaddress, "",&&&&&&&&&&&&&&&&&&&&&& "异常信息提示",strerrormsg );&&&&&&&&&&&&&&&&&& // 写trace&&&&&&&&&&&&&&&&&& trace.writeline( strerrormsg );&&&&&&&&&&&&& }&&&&&&&& }&&&&&&& 在另外一个应用程序中通过servicecontroller的executecommand()方法向这个windows服务发送命令:&&&&&& &&&& mycontroller.executecommand(2);&&&&&&& windows服务将执行业务方法:dobusiness2();&&&&&&& 应该承认,利用servicecontroller与windows服务通讯的功能目前还十分薄弱。通过executecommand只能与windows服务进行简单而有限的通讯。&&&&&&& 笔者在实际的应用中,分别用一个命令行程序、一个控制台程序和一个webservice和windows服务进行通讯,启动、停止服务,或通过executecommand控制服务的行为。&&&&&&& 附件:操纵windows事件日志的通用类using system.using system.&namespace mycommon.eventlog{&&&& public enum eventtype { error,information,warning }&&&& /// &summary&&&&& /// &&&& /// &/summary&&&&& public class tlineeventlog&&&& {&&&&&&&& // 任务日志&&&&&&&& static private eventlog m_eventlog = new eventlog();&&&&&&&& // 源名称,从配置文件中读取&&&&&&&& static private string m_streventsource = &&&&&&&&&&&&& configurationsettings.appsettings["f_eventlog.source"].tostring().trim();&&&&&&&& // 日志名称,从配置文件中读取&&&&&&&& static private string m_streventlog = &&&&&&&&&&&&& configurationsettings.appsettings["f_eventlog.log"].tostring().trim();&&&&&&&&& // 调试信息写入日志&&&&&&&& static private eventlogtracelistener ctracelistener = &&&&&&&&&&&&& new eventlogtracelistener( m_eventlog );&&&&&&&&& // 缺省构造函数。配置文件读取失败时,提供默认的源名称和日志名称&&&&&&&& public tlineeventlog()&&&&&&&& {&&&&&&&&&&&&& if( m_streventsource.length == 0 )&&&&&&&&&&&&&&&&&& m_streventsource = "mysource";&&&&&&&&&&&&&& if( m_streventlog.length == 0 )&&&&&&&&&&&&&&&&&& m_streventlog&&& = "mylog";&&&&&&&&&&&&&& m_eventlog.source = m_&&&&&&&&&&&&& m_eventlog.log&&& = m_&&&&&&&& }&&&&&&&&& // 构造函数。提供源名称和日志名称。&&&&&&&& public tlineeventlog( string streventsource, string streventlog )&&&&&&&& {&&&&&&&&&&&&& m_streventsource =&&&&&&&&&&&&& m_streventlog&&& =&&&& &&&&&&&& m_eventlog.source = m_&&&&&&&&&&&&& m_eventlog.log&&& = m_&&&& }&&&&&&&&& /// &summary&&&&&&&&& /// 写事件日志&&&&&&&& /// &/summary&&&&&&&&& /// &param name="strmessage"&事件内容&/param&&&&&&&&& /// &param name="eventtype"&事件类别,错误、警告或者消息&/param&&&&&&&&& static public void dowriteeventlog( string strmessage, eventtype eventtype )&&&&&&&& {&&&&&&&&&&&&& if (!system.diagnostics.eventlog.sourceexists( m_streventsource )) &&&&&&&&&&&&& {&&&& &&&&&&&&&&&&&&&&&&&&&& system.diagnostics.eventlog.createeventsource( &&&&&&&&&&&&&&&&&&&&&& m_streventsource,m_streventlog );&&&&&&&&&&&&& }&&&&&&&&&&&&&& eventlogentrytype entrytype = new eventlogentrytype();&&&&&&&&&&&&& switch(eventtype)&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&& case eventtype.error:&&&&&& &&&&&&&&&&&&&&&&&&&&&& entrytype = eventlogentrytype.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& rmation: &&&&&&&&&&&&&&&&&&&&&& entrytype =&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& case eventtype.warning:&&&& &&&&&&&&&&&&&&&&&&&&&& entrytype = eventlogentrytype.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& default:&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&& entrytype =&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&& m_eventlog.writeentry( strmessage, entrytype ); &&&&&&&& }&&&&&&&&& /// &summary&&&&&&&&& /// 写事件日志,默认为消息&&&&&&&& /// &/summary&&&&&&&&& /// &param name="strmessage"&事件内容&/param&&&&&&&&& static public void dowriteeventlog( string strmessage )&&&&&&&& {&&&& &&&&&&&& if (!system.diagnostics.eventlog.sourceexists( m_streventsource )) &&&&&&&&&&&&& {&&&&&&&& &&&&&&&&&&&&&&&&&& system.diagnostics.eventlog.createeventsource( &&&&&&&&&&&&&&&&&&&&&& m_streventsource,m_streventlog );&&&&&&&&&&&&& }&&&&&&&&&&&&& m_eventlog.writeentry( strmessage ); &&&&&&&& }&&&&&&&&& /// &summary&&&&&&&&& /// 调试信息写入日志&&&&&&&& /// &/summary&&&&&&&&& public static void opentrace()&&&&&&&& {&&&&&&&&&&&&& if( ctracelistener != null )&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&& if( !trace.listeners.contains( ctracelistener ) )&&&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&&&& trace.listeners.add( ctracelistener );&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&& }&&&&&&&& }&&&&&&&&& /// &summary&&&&&&&&& /// 调试信息不写入日志&&&&&&&& /// &/summary&&&&&&&&& public static void closetrace()&&&&&&&& {&&&&&&&&&&&&& if( trace.listeners.indexof(ctracelistener) &= 0 )&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&& trace.listeners.remove( ctracelistener );&&&&&&&&&&&&& }&&&&&&&& }&&&& }}&作者简介:张昱,联想利泰软件公司(原联想软件设计中心) e-zhangyu@
文章整理:西部数码--专业提供、服务
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
文章页数:&
??????????
??????????
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
版权所有 西部数码()
CopyRight (c) 2002~ all right reserved.
公司地址:四川省成都市金牛区一环路北一段99号环球广场24楼 邮编:610031
电话总机:028-08 38
售前咨询:总机转201 202 203 204 206 208
售后服务:总机转211 212 213 214
财务咨询:总机转224 223 传真:028- 财务QQ:
售前咨询QQ:2182518
售后服务QQ:VC++ 创建Windows服务
&&&&&& 首先,附上Windows创建服务的源代码,这个很好用的,大家一般都是选择的这个使用。
#include&XXXX.h&& //包含的头文件&&
//定义全局函数变量&&
void Init();&
BOOL IsInstalled();&
BOOL Install();&
BOOL Uninstall();&
void LogEvent(LPCTSTR pszFormat, ...);&
void WINAPI ServiceMain();&
void WINAPI ServiceStrl(DWORD dwOpcode);&
TCHAR szServiceName[] = _T(&WatchDog&);&
SERVICE_STATUS_HANDLE hServiceS&
SERVICE_STATUS&
DWORD dwThreadID;&
int APIENTRY WinMain(HINSTANCE hInstance,&
&&&&&&&&&&&&&&&&&&&& HINSTANCE hPrevInstance,&
&&&&&&&&&&&&&&&&&&&& LPSTR&&&& lpCmdLine,&
&&&&&&&&&&&&&&&&&&&& int&&&&&& nCmdShow)&
&&& Init();&
&&& dwThreadID = ::GetCurrentThreadId();&
&&& SERVICE_TABLE_ENTRY st[] =&
&&&&&&& { szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },&
&&&&&&& { NULL, NULL }&
&&& if (stricmp(lpCmdLine, &/install&) == 0)&
&&&&&&& {&
&&&&&&&&&& Install();&
&&&&&&& }&
&&& else if (stricmp(lpCmdLine, &/uninstall&) == 0)&
&&&&&&& {&
&&&&&&&&&&& Uninstall();&
&&&&&&& }&
&&&&&&& {&
&&&&&&&& if (!::StartServiceCtrlDispatcher(st))&
&&&&&&& {&
&&&&&&&&&&& LogEvent(_T(&Register Service Main Function Error!&));&
&&&&&&& }&
&&& return 0;&
//*********************************************************&&
//Functiopn:&&&&&&&&&&& Init&&
//Description:&&&&&&&&& 初始化&&
//Calls:&&&&&&&&&&&&&&& main&&&&&&&&&&
//&&&&&&&&& &author&niying &time&&&&&& &version&&&&& &desc&&&
//*********************************************************&&
void Init()&
&&& hServiceStatus = NULL;&
&&& status.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;&
&&& status.dwCurrentState = SERVICE_START_PENDING;&
&&& status.dwControlsAccepted = SERVICE_ACCEPT_STOP;&
&&& status.dwWin32ExitCode = 0;&
&&& status.dwServiceSpecificExitCode = 0;&
&&& status.dwCheckPoint = 0;&
&&& status.dwWaitHint = 0;&
//*********************************************************&&
//Functiopn:&&&&&&&&&&& ServiceMain&&
//Description:&&&&&&&&& 服务主函数,这在里进行控制对服务控制的注册&&
//&&&&&&&&& &author&niying &time&&&&&& &version&&&&& &desc&&&
//*********************************************************&&
void WINAPI ServiceMain()&
&&& // Register the control request handler&&
&&& status.dwCurrentState = SERVICE_START_PENDING;&
&&& status.dwControlsAccepted = SERVICE_ACCEPT_STOP;&
&&& //注册服务控制&&
&&& hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);&
&&& if (hServiceStatus == NULL)&
&&&&&&& LogEvent(_T(&Handler not installed&));&
&&& SetServiceStatus(hServiceStatus, &status);&
&&& status.dwWin32ExitCode = S_OK;&
&&& status.dwCheckPoint = 0;&
&&& status.dwWaitHint = 0;&
&&& status.dwCurrentState = SERVICE_RUNNING;&
&&& SetServiceStatus(hServiceStatus, &status);&
&&& //模拟服务的运行。应用时将主要任务放于此即可&&
&&&&&&& //可在此写上服务需要执行的代码,一般为死循环&&
&&&&& while(1)&
&&&&&&&&&& //循环干什么&&
&&&& }&&&&&
&&& status.dwCurrentState = SERVICE_STOPPED;&
&&& SetServiceStatus(hServiceStatus, &status);&
&&& OutputDebugString(_T(&Service stopped&));&
//*********************************************************&&
//Functiopn:&&&&&&&&&&& ServiceStrl&&
//Description:&&&&&&&&& 服务控制主函数,这里实现对服务的控制,&&
//&&&&&&&&&&&&&&&&&&&&& 当在服务管理器上停止或其它操作时,将会运行此处代码&&
//Calls:&&
//Called By:&&
//Table Accessed:&&
//Table Updated:&&
//Input:&&&&&&&&&&&&&&& dwOpcode:控制服务的状态&&
//Output:&&
//Return:&&
//Others:&&
//History:&&
//&&&&&&&&& &author&niying &time&&&&&& &version&&&&& &desc&&&
//*********************************************************&&
void WINAPI ServiceStrl(DWORD dwOpcode)&
&&& switch (dwOpcode)&
&&& case SERVICE_CONTROL_STOP:&
&&&&&&& status.dwCurrentState = SERVICE_STOP_PENDING;&
&&&&&&& SetServiceStatus(hServiceStatus, &status);&
&&&&&&& PostThreadMessage(dwThreadID, WM_CLOSE, 0, 0);&
&&& case SERVICE_CONTROL_PAUSE:&
&&& case SERVICE_CONTROL_CONTINUE:&
&&& case SERVICE_CONTROL_INTERROGATE:&
&&& case SERVICE_CONTROL_SHUTDOWN:&
&&& default:&
&&&&&&& LogEvent(_T(&Bad service request&));&
&&&&&&& OutputDebugString(_T(&Bad service request&));&
//*********************************************************&&
//Functiopn:&&&&&&&&&&& IsInstalled&&
//Description:&&&&&&&&& 判断服务是否已经被安装&&
//&&&&&&&&& &author&niying &time&&&&&& &version&&&&& &desc&&&
//*********************************************************&&
BOOL IsInstalled()&
&&& BOOL bResult = FALSE;&
&&& //打开服务控制管理器&&
&&& SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);&
&&& if (hSCM != NULL)&
&&&&&&& //打开服务&&
&&&&&&& SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);&
&&&&&&& if (hService != NULL)&
&&&&&&& {&
&&&&&&&&&&& bResult = TRUE;&
&&&&&&&&&&& ::CloseServiceHandle(hService);&
&&&&&&& }&&&&
&&&&&&& ::CloseServiceHandle(hSCM);&
&&& return bR&
//*********************************************************&&
//Functiopn:&&&&&&&&&&& Install&&
//Description:&&&&&&&&& 安装服务函数&&
//&&&&&&&&& &author&niying &time&&&&&& &version&&&&& &desc&&&
//*********************************************************&&
BOOL Install()&
&&& if (IsInstalled())&
&&&&&&& return TRUE;&
&&& //打开服务控制管理器&&
&&& SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);&
&&& if (hSCM == NULL)&
&&&&&&& MessageBox(NULL, _T(&Couldn't open service manager&), szServiceName, MB_OK);&
&&&&&&& return FALSE;&
&&& // Get the executable file path&&
&&& TCHAR szFilePath[MAX_PATH];&
&&& ::GetModuleFileName(NULL, szFilePath, MAX_PATH);&
&&& //创建服务&&
&&& SC_HANDLE hService = ::CreateService(hSCM, szServiceName, szServiceName,&
&&&&&&& SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,SERVICE_AUTO_START , SERVICE_ERROR_NORMAL,&
&&&&&&& szFilePath, NULL, NULL, _T(&&), NULL, NULL);&
&&& if (hService == NULL)&
&&&&&&& ::CloseServiceHandle(hSCM);&
&&&&&&& MessageBox(NULL, _T(&Couldn't create service&), szServiceName, MB_OK);&
&&&&&&& return FALSE;&
&&& ::CloseServiceHandle(hService);&
&&& ::CloseServiceHandle(hSCM);&
&&& return TRUE;&
//*********************************************************&&
//Functiopn:&&&&&&&&&&& Uninstall&&
//Description:&&&&&&&&& 删除服务函数&&
//&&&&&&&&& &author&niying &time&&&&&& &version&&&&& &desc&&&
//*********************************************************&&
BOOL Uninstall()&
&&& if (!IsInstalled())&
&&&&&&& return TRUE;&
&&& SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);&
&&& if (hSCM == NULL)&
&&&&&&& MessageBox(NULL, _T(&Couldn't open service manager&), szServiceName, MB_OK);&
&&&&&&& return FALSE;&
&&& SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);&
&&& if (hService == NULL)&
&&&&&&& ::CloseServiceHandle(hSCM);&
&&&&&&& MessageBox(NULL, _T(&Couldn't open service&), szServiceName, MB_OK);&
&&&&&&& return FALSE;&
&&& SERVICE_STATUS&
&&& ::ControlService(hService, SERVICE_CONTROL_STOP, &status);&
&&& //删除服务&&
&&& BOOL bDelete = ::DeleteService(hService);&
&&& ::CloseServiceHandle(hService);&
&&& ::CloseServiceHandle(hSCM);&
&&& if (bDelete)&
&&&&&&& return TRUE;&
&&& LogEvent(_T(&Service could not be deleted&));&
&&& return FALSE;&
//*********************************************************&&
//Functiopn:&&&&&&&&&&& LogEvent&&
//Description:&&&&&&&&& 记录服务事件&&
//&&&&&&&&& &author&niying &time&&&&&& &version&&&&& &desc&&&
//*********************************************************&&
void LogEvent(LPCTSTR pFormat, ...)&
&&& TCHAR&&& chMsg[256];&
&&& HANDLE& hEventS&
&&& LPTSTR& lpszStrings[1];&
&&& va_list pA&
&&& va_start(pArg, pFormat);&
&&& _vstprintf(chMsg, pFormat, pArg);&
&&& va_end(pArg);&
&&& lpszStrings[0] = chM&
&&& hEventSource = RegisterEventSource(NULL, szServiceName);&
&&& if (hEventSource != NULL)&
&&&&&&& ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);&
&&&&&&& DeregisterEventSource(hEventSource);&
#include&XXXX.h&& //包含的头文件
//定义全局函数变量
void Init();
BOOL IsInstalled();
BOOL Install();
BOOL Uninstall();
void LogEvent(LPCTSTR pszFormat, ...);
void WINAPI ServiceMain();
void WINAPI ServiceStrl(DWORD dwOpcode);
TCHAR szServiceName[] = _T(&WatchDog&);
SERVICE_STATUS_HANDLE hServiceS
SERVICE_STATUS
DWORD dwThreadID;
int APIENTRY WinMain(HINSTANCE hInstance,
&&&&&&&&&&&&&&&&&&&& HINSTANCE hPrevInstance,
&&&&&&&&&&&&&&&&&&&& LPSTR&&&& lpCmdLine,
&&&&&&&&&&&&&&&&&&&& int&&&&&& nCmdShow)
&dwThreadID = ::GetCurrentThreadId();
&&& SERVICE_TABLE_ENTRY st[] =
&&&&&&& { szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
&&&&&&& { NULL, NULL }
&if (stricmp(lpCmdLine, &/install&) == 0)
&&&& Install();
&else if (stricmp(lpCmdLine, &/uninstall&) == 0)
&&&Uninstall();
&& if (!::StartServiceCtrlDispatcher(st))
&&&LogEvent(_T(&Register Service Main Function Error!&));
&return 0;
//*********************************************************
//Functiopn:&&&Init
//Description:&&&初始化
//Calls:&&&&main&&
//&&&&author&niying &time&&&&version&&&&desc&
//*********************************************************
void Init()
&&& hServiceStatus = NULL;
&&& status.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
&&& status.dwCurrentState = SERVICE_START_PENDING;
&&& status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
&&& status.dwWin32ExitCode = 0;
&&& status.dwServiceSpecificExitCode = 0;
&&& status.dwCheckPoint = 0;
&&& status.dwWaitHint = 0;
//*********************************************************
//Functiopn:&&&ServiceMain
//Description:&&&服务主函数,这在里进行控制对服务控制的注册
//&&&&author&niying &time&&&&version&&&&desc&
//*********************************************************
void WINAPI ServiceMain()
&&& // Register the control request handler
&&& status.dwCurrentState = SERVICE_START_PENDING;
&status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
&//注册服务控制
&&& hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
&&& if (hServiceStatus == NULL)
&&&&&&& LogEvent(_T(&Handler not installed&));
&&& SetServiceStatus(hServiceStatus, &status);
&&& status.dwWin32ExitCode = S_OK;
&&& status.dwCheckPoint = 0;
&&& status.dwWaitHint = 0;
&status.dwCurrentState = SERVICE_RUNNING;
&SetServiceStatus(hServiceStatus, &status);
&//模拟服务的运行。应用时将主要任务放于此即可
&&&&&&& //可在此写上服务需要执行的代码,一般为死循环
&&&&& while(1)
&&&&&&&&&& //循环干什么
&&& status.dwCurrentState = SERVICE_STOPPED;
&&& SetServiceStatus(hServiceStatus, &status);
&&& OutputDebugString(_T(&Service stopped&));
//*********************************************************
//Functiopn:&&&ServiceStrl
//Description:&&&服务控制主函数,这里实现对服务的控制,
//&&&&&&当在服务管理器上停止或其它操作时,将会运行此处代码
//Called By:
//Table Accessed:
//Table Updated:
//Input:&&&&dwOpcode:控制服务的状态
//History:
//&&&&author&niying &time&&&&version&&&&desc&
//*********************************************************
void WINAPI ServiceStrl(DWORD dwOpcode)
&&& switch (dwOpcode)
&&& case SERVICE_CONTROL_STOP:
&&status.dwCurrentState = SERVICE_STOP_PENDING;
&&&&&&& SetServiceStatus(hServiceStatus, &status);
&&&&&&& PostThreadMessage(dwThreadID, WM_CLOSE, 0, 0);
&&& case SERVICE_CONTROL_PAUSE:
&&& case SERVICE_CONTROL_CONTINUE:
&&& case SERVICE_CONTROL_INTERROGATE:
&&& case SERVICE_CONTROL_SHUTDOWN:
&&& default:
&&&&&&& LogEvent(_T(&Bad service request&));
&&OutputDebugString(_T(&Bad service request&));
//*********************************************************
//Functiopn:&&&IsInstalled
//Description:&&&判断服务是否已经被安装
//&&&&author&niying &time&&&&version&&&&desc&
//*********************************************************
BOOL IsInstalled()
&&& BOOL bResult = FALSE;
&//打开服务控制管理器
&&& SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
&&& if (hSCM != NULL)
&&//打开服务
&&&&&&& SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);
&&&&&&& if (hService != NULL)
&&&&&&&&&&& bResult = TRUE;
&&&&&&&& ::CloseServiceHandle(hService);
&&&&&&& ::CloseServiceHandle(hSCM);
&&& return bR
//*********************************************************
//Functiopn:&&&Install
//Description:&&&安装服务函数
//&&&&author&niying &time&&&&version&&&&desc&
//*********************************************************
BOOL Install()
&&& if (IsInstalled())
&&&&&&& return TRUE;
&//打开服务控制管理器
&&& SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
&&& if (hSCM == NULL)
&&&&&&& MessageBox(NULL, _T(&Couldn't open service manager&), szServiceName, MB_OK);
&&&&&&& return FALSE;
&&& // Get the executable file path
&&& TCHAR szFilePath[MAX_PATH];
&&& ::GetModuleFileName(NULL, szFilePath, MAX_PATH);
&//创建服务
&&& SC_HANDLE hService = ::CreateService(hSCM, szServiceName, szServiceName,
&&SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,SERVICE_AUTO_START , SERVICE_ERROR_NORMAL,
&&&&&&& szFilePath, NULL, NULL, _T(&&), NULL, NULL);
&&& if (hService == NULL)
&&&&&&& ::CloseServiceHandle(hSCM);
&&&&&&& MessageBox(NULL, _T(&Couldn't create service&), szServiceName, MB_OK);
&&&&&&& return FALSE;
&&& ::CloseServiceHandle(hService);
&&& ::CloseServiceHandle(hSCM);
&&& return TRUE;
//*********************************************************
//Functiopn:&&&Uninstall
//Description:&&&删除服务函数
//&&&&author&niying &time&&&&version&&&&desc&
//*********************************************************
BOOL Uninstall()
&&& if (!IsInstalled())
&&&&&&& return TRUE;
&&& SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
&&& if (hSCM == NULL)
&&&&&&& MessageBox(NULL, _T(&Couldn't open service manager&), szServiceName, MB_OK);
&&&&&&& return FALSE;
&&& SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
&&& if (hService == NULL)
&&&&&&& ::CloseServiceHandle(hSCM);
&&&&&&& MessageBox(NULL, _T(&Couldn't open service&), szServiceName, MB_OK);
&&&&&&& return FALSE;
&&& SERVICE_STATUS
&&& ::ControlService(hService, SERVICE_CONTROL_STOP, &status);
&//删除服务
&&& BOOL bDelete = ::DeleteService(hService);
&&& ::CloseServiceHandle(hService);
&&& ::CloseServiceHandle(hSCM);
&&& if (bDelete)
&&&&&&& return TRUE;
&&& LogEvent(_T(&Service could not be deleted&));
&&& return FALSE;
//*********************************************************
//Functiopn:&&&LogEvent
//Description:&&&记录服务事件
//&&&&author&niying &time&&&&version&&&&desc&
//*********************************************************
void LogEvent(LPCTSTR pFormat, ...)
&&& TCHAR&&& chMsg[256];
&&& HANDLE& hEventS
&&& LPTSTR& lpszStrings[1];
&&& va_list pA
&&& va_start(pArg, pFormat);
&&& _vstprintf(chMsg, pFormat, pArg);
&&& va_end(pArg);
&&& lpszStrings[0] = chM
&hEventSource = RegisterEventSource(NULL, szServiceName);
&if (hEventSource != NULL)
&&ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
&&DeregisterEventSource(hEventSource);
&&& 我在开发的时候用到了DLL里面的函数,开始的时候采用的静态导入的方法,但是发现服务开机启动以后就死掉了,这里不是DLL路径的问题。
&& 没办法,自己只得用动态导入的方法,还好,服务自动开机运行了,还算正常吧。
&& 小提示:如果需要弹出MessageBox消息,比如让服务可以与桌面进行交互。& 这个在服务里面可以设置。
&&&& 当然,我这里的初始化参数已经设置好了,在DOS命令里面安装完成后,你会发现,那个框,我已经替你选上了。
&&&& //重要说明,服务最好不要直接编译执行,虽然是exe,最好的方式是安装,&
&&&&&&&&& 安装命令&&& DOS& 下:&& ServiceName.exe&&&& /install
&&&&&&&&& 卸载命令&& DOS下 :ServiceName.exe&&&&& /uninstall&&&
&&&&&& 直接运行exe不仅会报错,还会导致服务开机不能自动运行。
&&&& 大多的时候,你直接运行exe都会报1063错误,就是因为你把服务以控制台的方式运行了。&
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'

我要回帖

更多关于 编写windows应用程序 的文章

 

随机推荐