在使用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脚本时,获取当前文件所在目录