C#实现对Windows 服务安装

Windows服务作用:定时用户消息推送,WEB程序实时统计等

Windows服务创建:C#创建服务的方式也有很多种,建议大家在做之前可以先全面了解一下这方面东西再去动手这样便于解决中间遇到一些比较棘手的小问题。

主要说一种通过SC命令实现服务的创建、修改、查询、卸载、开始、暂停,具体服务工作的业务可以另行完善。

1,创建一个控制台程序,当然也可以写个winform或者其他XXX

2,在创建好的项目中新建一个服务

创建完服务,剩下的就需要代码实现了。

思路:我们将通过模拟在命令窗中输入SC服务命令创建和操作服务,所以这里先把一些公用的方法写出来。

运行命令并返回命令输出消息

 /// <summary>
        /// 运行CMD命令
        /// </summary>
        /// <param name="cmd">命令</param>
        /// <returns></returns>
        public static string Cmd(string[] cmd)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.Start();
            p.StandardInput.AutoFlush = true;
            for (int i = 0; i < cmd.Length; i++)
            {
                p.StandardInput.WriteLine(cmd[i].ToString());
            }
            p.StandardInput.WriteLine("exit");
            string strRst = p.StandardOutput.ReadToEnd();
            p.WaitForExit();
            p.Close();
            CloseProcess("cmd.exe");//执行结束,关闭cmd进程
            return strRst;
        }

结束Process 方法

  /// <summary>
        /// 关闭进程
        /// </summary>
        /// <param name="ProcName">进程名称</param>
        /// <returns></returns>
        public static bool CloseProcess(string ProcName)
        {
            bool result = false;
            System.Collections.ArrayList procList = new System.Collections.ArrayList();
            string tempName = "";
            int begpos;
            int endpos;
            foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
            {
                tempName = thisProc.ToString();
                begpos = tempName.IndexOf("(") + 1;
                endpos = tempName.IndexOf(")");
                tempName = tempName.Substring(begpos, endpos - begpos);
                procList.Add(tempName);
                if (tempName == ProcName)
                {
                    if (!thisProc.CloseMainWindow())
                        thisProc.Kill(); // 当发送关闭窗口命令无效时强行结束进程
                    result = true;
                }
            }
            return result;
        }

因为服务的请求可能会从系统服务或者应用程序发起请求,所以我们要加一个完善的主方法请求判断,如果是命令行过来的就给用户提供可选的操作菜单,否则运行服务。

定义一个枚举,记录不同请求来源。

  /// <summary>
        /// 定义程序被启用的几种形式
        /// </summary>
        public enum appModel
        {
            /// <summary>
            /// 网页启用
            /// </summary>
            Web,
            /// <summary>
            /// 系统服务启用
            /// </summary>
            Service,
            /// <summary>
            /// 窗体程序启用
            /// </summary>
            Windows,
            /// <summary>
            /// 控制台启用
            /// </summary>
            Console
        }

主方法内添加状态判断

 static void Main(string[] args)
        {
            appModel mode = AutoDetectAppType();//获取应用程序请求来源
            if (mode.Equals(appModel.Console))
            {//如果是控制台程序,验证是否对服务操作
                Console.WriteLine("选择金销帮后台服务操作");
                Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
                var rs = int.Parse(Console.ReadLine());
                DoParameter(rs);
            }
            else if (mode.Equals(appModel.Service))
            {
                //如果是服务,运行系统服务
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[]
                {
                    new MainServer(),
                };
                ServiceBase.Run(ServicesToRun);
            }
        }

根据用户每次选择不同的菜单对Windows服务发出命令

 /// <summary>
        /// 判断用户输入参数
        /// </summary>
        /// <param name="rs">控制台输入参数</param>
        public static void DoParameter(int rs)
        {
            //[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出
            switch (rs)
            {
                case 0:
                    //查询
                    string back_query = Cmd(new string[] { "sc query  jinxiaobangServices" });//查询服务信息
                    Console.WriteLine("------------------------------------------------------------------------------------");
                    Console.WriteLine("查询服务信息如下:\n\n\n " + back_query);//输出查询结果
                    Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
                    Console.WriteLine("------------------------------------------------------------------------------------");

                    var param_query = int.Parse(Console.ReadLine());
                    DoParameter(param_query);
                    break;
                case 1:
                    //安装服务
                    var path = Process.GetCurrentProcess().MainModule.FileName;
                    string back_create = Cmd(new string[] { "sc create jinxiaobangServices binpath= \"" + path + "\" displayName= JXBServices start= auto obj= localsystem ", "sc description   \"jinxiaobangServices\"  \"金销帮后台异步通知、数据统计、定时任务等处理\" " });
                    Console.WriteLine("------------------------------------------------------------------------------------");
                    Console.WriteLine("安装成功\n\n\n" + back_create);
                     Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
                     Console.WriteLine("------------------------------------------------------------------------------------");

                    var param_create = int.Parse(Console.ReadLine());
                    DoParameter(param_create);
                    break;
                case 2:
                    //卸载服务
                    string back_delete = Cmd(new string[] { "sc delete  jinxiaobangServices" });//卸载服务
                    Console.WriteLine("------------------------------------------------------------------------------------");
                    Console.WriteLine("卸载成功\n\n\n" + back_delete);
                    Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
                    Console.WriteLine("------------------------------------------------------------------------------------");

                    var param_delete = int.Parse(Console.ReadLine());
                    DoParameter(param_delete);
                    break;
                case 3:
                    //启动服务
                    //Process.Start("sc", "start  jinxiaobangServices");//sc执行命令
                      string back_start = Cmd(new string[] { "sc start  jinxiaobangServices" });//启动服务
                      Console.WriteLine("------------------------------------------------------------------------------------");
                      Console.WriteLine("启动成功\n\n\n" + back_start);
                      Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
                      Console.WriteLine("------------------------------------------------------------------------------------");

                    var param_start = int.Parse(Console.ReadLine());
                    DoParameter(param_start);
                    break;
                case 4:
                    //停止服务
                    string back_stop = Cmd(new string[] { "sc stop  jinxiaobangServices" });//停止服务
                    Console.WriteLine("------------------------------------------------------------------------------------");
                    Console.WriteLine("停止服务\n\n\n" + back_stop);
                    Console.WriteLine("如需操作请选择,[0]服务状态查询[1]安装服务 [2]卸载服务 [3]启动服务[4]停止服务[5]退出");
                    Console.WriteLine("------------------------------------------------------------------------------------");

                    var param_stop = int.Parse(Console.ReadLine());
                    DoParameter(param_stop);
                    //退出
                    break;
                case 5:
                    //退出
                    break;
            }
        }

到这里就把整个服务操作过程了解清楚了,后面就可以准备自己的业务代码。例如服务启动时和停止时分别做一些业务操作

 protected override void OnStart(string[] args)
        {
            // TODO:  在此处添加代码以启动服务。
            FileStream fs = new FileStream(@"C:\Windows\JinXBWinServer.log", FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);
            sw.BaseStream.Seek(0, SeekOrigin.End);
            sw.WriteLine("WindowsService: Service Started" + DateTime.Now.ToString() + "\n");
            sw.Flush();
            sw.Close();
            fs.Close();
        }

        protected override void OnStop()
        {
            // TODO:  在此处添加代码以执行停止服务所需的关闭操作。
            FileStream fs = new FileStream(@"C:\Windows\JinXBWinServer.log", FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);
            sw.BaseStream.Seek(0, SeekOrigin.End);
            sw.WriteLine("WindowsService: Service Stopped" + DateTime.Now.ToString() + "\n");
            sw.Flush();
            sw.Close();
            fs.Close();
        }

可以分别通过OnStart和OnStop去记录一下服务操作记录,来做个测试。

服务编写完,先别急着F5测试。因为运行权限的问题,这时可能会出现1053:服务没有及时响应启动或控制请求。这是因为VS权限不足,可以在debug文件中用管理员运行测试一下,是不是OK了。

时间: 2024-10-10 18:25:57

C#实现对Windows 服务安装的相关文章

windows服务安装及卸载

1)安装脚本Install.bat%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe JobSchedule.exeNet Start ServiceOAsc config ServiceOA start= auto 2)卸载脚本Uninstall.bat%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u JobSchedule.exe w

C#编写的windows服务安装后启动提示“服务启动后又停止了”

使用C#编写的windows服务安装到服务器上行后进行启动时,总是提示“服务启动后又停止了”. 检查了服务逻辑是没问题,安装在开发本地也是正常,网上查了资料说是可能是服务没有注册,我检查了服务是正常注册,相对应的方法试很多了,但是都没有解决.后来无意中看了一个帖子说可以在windows的本地服务日志里边看报错信息.看到这个,我的问题就有办法处理了,查了一下保存信息,提示找不到“E:\\”,看到这里我就明白是怎么回事了,我的开发机有E盘,服务器上没有E盘,而我的日志文件默认写在E盘,所以服务启动后

Windows服务安装与控制

Windows服务安装与控制 1.建立服务 (1)定义一个ServiceInstaller using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WindowService { [System.ComponentModel.RunInstaller(true)] public class ServiceInstaller : System.Configurat

2.Windows服务--&gt;安装卸载服务

1.使用vs组件“VS2012开发人员命令提示” 工具,进行安装卸载服务(必须以“管理员身份运行") 安装和卸载的时候选择合适的安装程序工具地址,例如: 安装服务:C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe 服务路径 卸载服务:C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u 服务路径 例如: C:\Windows\Microsoft.N

02-keepalived实现对nginx服务的高可用(主备)

实验环境:controller3,controller4为后端web服务器,controller1,controller2为nginx负载均衡服务器,用keepalived实现主备模式的高可用 controller1  IP:9.110.187.120 10.1.1.120 controller2  IP:9.110.187.121 10.1.1.121 controller3  IP:10.1.1.122 controller4  IP:10.1.1.123 1.controller3,con

C#版Windows服务安装卸载小工具-附源码

前言 在我们的工作中,经常遇到Windows服务的安装和卸载,在之前公司也普写过一个WinForm程序选择安装路径,这次再来个小巧灵活的控制台程序,不用再选择,只需放到需要安装服务的目录中运行就可以实现安装或卸载. 开发思路 1.由于系统的权限限制,在运行程序时需要以管理员身份运行 2.因为需要实现安装和卸载两个功能,在程序运行时提示本次操作是安装还是卸载  需要输入 1 或 2 3.接下来程序会查找当前目录中的可执行文件并过滤程序本身和有时我们复制进来的带有vhost的文件,并列出列表让操作者

C#开发的Windows服务安装时需要“设置服务登录”

C#开发的Windows服务在安装的过程中会弹出一个"设置服务登录"对话框,要求输入用户名和密码.此时用户名和密码的形式必须以域用户的形式输入,如果没有加入域,用户名要用.\username 的格式,否则会提示错误. 注:需要设置服务登录,是因为serviceProcessInstaller的Account设置为User了,修改为LocalService安装Windows服务就不需要设置账号密码了.

windows服务安装启动报错误1053:服务没有及时响应启动或控制请求

1 <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup> 2 3 </configuration> 用.net 开发了一个C#语言的windows服务,在本地和测试环境,安装启动都正常,在新的线上环境报错,不能启动-报出-错误1053:服务没有及时响应启动或控制请求. 后来发现时线上.NET FRAM

Zookeeper以Windows服务安装运行

1.下载的Zookeeper是.cmd的批处理命令运行的,默认没有提供以windows服务的方式运行的方案 下载地址:http://zookeeper.apache.org/ 2.下载prunsrv 下载地址:http://archive.apache.org/dist/commons/daemon/binaries/windows/ 3.解压后复制文件 64位机器用amd64/prunsrv.exe  a. 复制 commons-daemon-1.0.15-bin-windows/amd64/