首页 > 技术文章 > windows 服务的启动与安装

wisdo 2015-12-20 14:19 原文

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

  

 

推荐阅读