在使用windows 操作系统时,我们对windows服务再也熟悉不过了,这些服务有的是系统层的,有的是应用层的,大部分都是运行在桌面的后台,可以在进程中看到,有时候在做web项目时,在站点启动时要启动相应的服务,比如报警之类的,下面主要介绍在C#程序中安装 启动 与停止服务的方法, 可通过两种方式来启动,一种是通过运行编写好的 bat 文件,另一种是通过程序直接安装启动服务,具体做法如下:
1. bat 文件来安装 启动 停止 服务
首先将 bat 文件编写成以管理员的身份运行,在程序启动时,检测服务是否存在,如果不存在,就运行bat文件,安装服务,安装好后启动即可,如果服务已经存在,就要检测服务的状态,如果是停止,就要对服务进行启动.
以管理员运行bat 文件安装并启动服务:
@Rem InstallUtil service webapiservice under administrator permissions @Rem created 2015-12-20 @Rem Author wisdo @All Rights Reserved @echo off @echo place wait a minutes... %1 %2 ver|find "5.">nul&&goto :mystart mshta vbscript:createobject("shell.application").shellexecute("%~s0","goto :mystart","","runas",1)(window.close)&goto:exit :mystart %~d0 CD %~dp0 set %cd%="%windir%system32" InstallUtil wisdo.exe net start wisdo pause :exit exit
相应的停止服务就是 net stop wisdo
相应的C#中运行 bat 文件的代码:
readonly string serviceName="wisdo"; readonly string sveFilePath = "/content/services/";
/// <summary> /// 安装服务 /// </summary> /// <param name="filePath">bat文件所在的目录</param>
/// <param name="sveName">服务的名称</param> private void InstallService(string filePath,string sveName) { filePath = System.Web.HttpContext.Current.Server.MapPath(filePath); // 当前请求的绝对路径 if (!IsExisted(sveName)) { System.Diagnostics.Process pro = new System.Diagnostics.Process(); pro.StartInfo.WorkingDirectory = filePath; pro.StartInfo.FileName = "wisdo.bat"; pro.StartInfo.CreateNoWindow = true; pro.StartInfo.UseShellExecute = true; pro.Start(); pro.WaitForExit(); } else { StartService(sveName); //启动服务,同样是运行启动服务的 bat 文件,只要将安装服务的bat文件中的 InstallUtil wisdo.exe 改成 net start wisdo 即可 } }
需要引入的命名空间名字: using System.Configuration.Install;
2. 以C#代码的方式来安装,启动,停止 卸载服务
同样需要引入命名空间: using System.ServiceProcess;
#region webServiceAPI 服务启动与停止 /// <summary> /// 启动服务 /// </summary> /// <param name="sveName">服务的名称</param> private void StartService(string sveName) { try { ServiceController sveCtr = new ServiceController(sveName); if (sveCtr.Status != ServiceControllerStatus.Running || sveCtr.Status != ServiceControllerStatus.StartPending) { sveCtr.Start(); } } catch (Exception) { //TODO: 日志记录 } } /// <summary> /// 停止服务 /// </summary> /// <param name="name">服务名称</param> private void StopService(string name) { try { ServiceController sveCtr = new ServiceController(name); if (sveCtr.Status != ServiceControllerStatus.Stopped || sveCtr.Status != ServiceControllerStatus.StopPending) { sveCtr.Stop(); } } catch (Exception) { //TODO: 日志记录 } } /// <summary> /// 判断是否存在服务 /// </summary> /// <param name="name">服务名称</param> /// <returns></returns> private bool IsExisted(string name) { try { //ServiceController srvCtrl = new ServiceController(name); //ServiceControllerStatus scStatus = srvCtrl.Status; //return true; ServiceController[] sctrs = ServiceController.GetServices(); foreach (ServiceController item in sctrs) { if (item.ServiceName.ToLower() == name.ToLower()) { return true; } } return false; } catch (Exception) { //TODO: 日志记录 return false; } } /// <summary> /// 安装服务 /// </summary> /// <param name="filePath"></param> /// <param name="sveName"></param> private void InstallService(string filePath,string sveName) {
try{ filePath = sveFilePath + "wisdoService.exe"; filePath = System.Web.HttpContext.Current.Server.MapPath(filePath); System.Collections.Hashtable hashState = new System.Collections.Hashtable(); AssemblyInstaller asInst = new AssemblyInstaller(); asInst.UseNewContext = true; asInst.Path = System.Web.HttpContext.Current.Server.MapPath(filePath); asInst.Install(hashState); asInst.Commit(hashState); //启动服务 StartService(sveName);
}
catch(Exception)
{
//TODO: 日志记录
} } /// <summary> /// 卸载服务 /// </summary> /// <param name="filePath"></param> /// <param name="sveName"></param> private void UnInstallService(string filePath,string sveName) { filePath = sveFilePath + "UnwisdoService.exe"; if (IsExisted(sveName)) { AssemblyInstaller asInst = new AssemblyInstaller(); asInst.UseNewContext = true; asInst.Path = System.Web.HttpContext.Current.Server.MapPath(filePath); asInst.Uninstall(null); asInst.Dispose(); } } #endregion
但这里要注意一点: 会有权限的问题,也就是说win7及以上版本的 windows 操作系统中,如果服务最被设计成系统层的服务,那么在这里通过C# 程序的方式来安装与启动时会涉及到权限的问题,虽然有对应的解决办法,但办法比较复杂,这里就会涉及到操作系统管理员的权限,如果能满足最小的需求,可以采用借助 bat 文件的方法来安装与启动服务.
参考文章:
http://www.cnblogs.com/therock/articles/2261371.html 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离
http://www.cnblogs.com/luxilin/p/3347212.html C# window Service实现调用有UI的应用程序(关于win xp以后的window系统)
http://www.cnblogs.com/SunShineYPH/archive/2011/12/13/2285570.html Bat命令学习
http://www.cnblogs.com/wisdo/p/5060346.html BAT文件命令
http://blog.chinaunix.net/uid-27000874-id-3224772.html win7中以管理员身份运行bat脚本时,获取当前文件所在目录