将任意程序以Windows服务启动_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 将任意程序以Windows服务启动

将任意程序以Windows服务启动

 2013/9/2 23:13:50  coding4love  博客园  我要评论(0)
  • 摘要:公司服务器在每天启动时,并没有登录系统,因此想要运行特定的程序,只有把它作为Windows服务启动要求不修改原来的程序,但是又需要与SCM(服务控制管理器)通信,需要另建一个windows服务程序,让其调用我们的目标程序网上一些所谓可以把exe注册为服务的工具(如srvinstw.exe,instsrv.exe,srvany.exe等)实际并没有效果
  • 标签:程序 Windows 服务 启动

公司服务器在每天启动时,并没有登录系统,因此想要运行特定的程序,只有把它作为Windows服务启动

要求不修改原来的程序,但是又需要与SCM(服务控制管理器)通信,需要另建一个windows服务程序,让其调用我们的目标程序

网上一些所谓可以把exe注册为服务的工具(如srvinstw.exe, instsrv.exe, srvany.exe等)实际并没有效果,或者说只对本身具有与SCM通信功能的程序有作用

 

以下为C#的windows服务实现

ServiceBase的派生类中实现虚函数OnStart和OnStop即可

 1 using System;
 2 using System.Configuration;
 3 using System.Diagnostics;
 4 using System.ServiceProcess;
 5 using System.Threading;
 6  
 7 namespace MyWindowsService
 8 {
 9     public partial class MyService : ServiceBase
10     {
11         private static EventLog log = new EventLog();
12         private static Thread thread = null;
13         private static Process proc = null;
14         private string exePath = null;
15  
16         public MyService()
17         {
18             InitializeComponent();
19             log.Source = "app.log"; //记录日志,使用WriteEntry写入windows事件
20             string dir = System.AppDomain.CurrentDomain.BaseDirectory;
21             ExeConfigurationFileMap map = new ExeConfigurationFileMap();
22             map.ExeConfigFilename = dir + "App.config"; //读取和服务程序同一目录下的配置文件,其中设置了目标程序的路径
23             Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
24             exePath = config.AppSettings.Settings["exePath"].Value; //读取key为exePath的值
25         }
26  
27         protected override void OnStart(string[] args)
28         {
29             try
30             {
31                 if (thread == null)
32                 {
33                     thread = new Thread(startExe); //线程中启动程序
34                 }
35                 thread.Start();
36             }
37             catch(Exception e)
38             {
39                 log.WriteEntry(e.ToString());
40             }
41         }
42  
43         protected override void OnStop()
44         {
45             try
46             {
47                 if (proc != null && !proc.HasExited)
48                 {
49                     proc.Kill(); //停止服务时关闭程序
50                 }
51                 if (thread != null && thread.ThreadState == System.Threading.ThreadState.Running)
52                 {
53                     thread.Abort(); //关闭线程
54                 }
55             }
56             catch (Exception e)
57             {
58                 log.WriteEntry(e.ToString());
59             }
60         }
61  
62         private void startExe()
63         {
64             try
65             {
66                 proc = new Process();
67                 ProcessStartInfo startInfo = new ProcessStartInfo(exePath); //设置程序路径
68                 proc.StartInfo = startInfo;
69                 proc.Start();
70             }
71             catch (Exception e)
72             {
73                 log.WriteEntry(e.ToString());
74             }
75         }
76     }
77 }

其中注意几个问题:

1.启动目标程序时候需要使用新线程,如果在service线程中启动,会阻塞服务与SCM的通信,造成服务启动失败

2.OnStart和OnStop中所有可能抛出的异常都需要捕获,否则启动时如果有异常,则会提示服务启动又停止了

3.启动的目标程序只能以SYSTEM账户运行,因此看不到程序界面

4.服务程序也可使用C++实现,同样最少实现OnStart和OnStop两个虚函数即可

 

服务的安装,两个办法:

1.编写安装/卸载程序,调用windows API中的函数,CreateService()和DeleteService()

2.使用.Net Framework自带的工具InstallUtil.exe,一般位于%SystemRoot%\Microsoft.NET\Framework\版本号\

安装服务:installuitl [服务程序路径]

卸载服务:installuitl /u [服务程序路径]

 

发表评论
用户名: 匿名