让你的GUI程序随WINDOWS服务一起启动

本文介绍了一种将GUI程序转换为Windows服务程序的方法,解决了管理员频繁远程登录和注销导致的程序退出问题。文章详细讨论了实现过程中的三个核心难点:确保先启动依赖服务、使服务程序能启动GUI应用、获取系统注销信息并启动相应程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文内容
一.应用场景
二.本文难点
三.关键代码
四.创建Windows服务
五.修改参数并启动服务 
源码下载


一.应用场景

    客户服务器上装的软件越来越多,由原来一个人管理改为几个人同时管理了,因此不同的管理员需要经常进行远程登陆,注销操作。

    服务器上原有的一些程序是windows程序,用户登陆注销后,程序就退出了,咋办?把GUI程序改成windows服务程序是可行的,但客户希望能尽快解决此问题啊,咋办?于是就有了本文的想法,先这样用用吧! 呵呵...



二.本文难点

    说起来就一句话,做起来可得考虑以下三个问题:
    1.如程序要访问Oracle数据库,在启动你的程序前,得先将Oracle数据库服务启动。
    2.让Windows服务程序支持启动你的有界面的应用程序。(默认是不能与桌面交互的)
    3.如何让Windows服务获取系统注销信息,以启动相应的GUI程序.


三.关键代码

  3.1 获取系统注销信息

    方法:通过与Microsoft.Win32.SessionEndingEventHandler建关关联获取系统注销信息

        protected override void OnStart(string[] args)
        {
           //获取系统注销,关机
            Microsoft.Win32.SystemEvents.SessionEnding += new Microsoft.Win32.SessionEndingEventHandler(this.SystemEvents_SessionEnding);


         }


        protected override void OnStop()
        {
            // TODO: 在此处添加代码以执行停止服务所需的关闭操作。
             //切记在服务停止时,移除事件.
            Microsoft.Win32.SystemEvents.SessionEnding -= new Microsoft.Win32.SessionEndingEventHandler(this.SystemEvents_SessionEnding);
        }

  3.2 检查并启动Windows服务

        /// <summary>
        /// 启动已暂停或停止的服务
         /// </summary>
        private void StartService()
        {


            try
            {
                foreach (string serviceName in rwCnfg.GsServiceNames)
                {
                    ServiceController myService = new ServiceController(serviceName);
                    ServiceControllerStatus status = myService.Status;
                    switch (status)
                    {
                        case ServiceControllerStatus.ContinuePending:


                            break;


                        case ServiceControllerStatus.PausePending:


                            break;
                        case ServiceControllerStatus.StartPending:


                            break;
                        case ServiceControllerStatus.Running:


                            break;
                        case ServiceControllerStatus.Paused:
                        case ServiceControllerStatus.Stopped:
                            {
                                myService.Start();
                                myService.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 2, 0));
                                Common.wLog("完成启动服务: " + myService.ServiceName + " . " + System.DateTime.Now.ToString());
                            }
                            break;
                        case ServiceControllerStatus.StopPending:


                            break;
                        default:


                            break;
                    }
                }
            }
            catch (Exception err)
            {
                Common.wLog(err.ToString());
            }
        }

3.3 检查并启动对应GUI程序

/// <summary>
        /// 启动所有要启动的程序
        /// </summary>
        private void StartProgram()
        {
            try
            {
                foreach (string ProgramPath in rwCnfg.GsProgramPaths)
                {
                    string fileName = "";
                    //fileName = System.IO.Path.GetFileName(ProgramPath); //文件名
                    //string ext = System.IO.Path.GetExtension(ProgramPath); //扩展名
                    fileName = System.IO.Path.GetFileNameWithoutExtension(ProgramPath);// fileName.Replace(ext, "");
                    if (!IsExistProcess(fileName))
                    {
                        ProcessStartInfo startInfo = new ProcessStartInfo(ProgramPath);
                        startInfo.WindowStyle = ProcessWindowStyle.Normal;
                        Process.Start(startInfo);


                        Common.wLog("完成启动程序: " + fileName + ",完整路径:" + ProgramPath + " . " + System.DateTime.Now.ToString());


                        System.Threading.Thread.Sleep(3 * 1000); //间隔3秒;
                    }
                }
            }
            catch (Exception err)
            {
                Common.wLog(err.ToString());
            }


        }


        /// <summary>
        /// 检查该进程是否已启动
        /// </summary>
        /// <param name="processName"></param>
        /// <returns></returns>
        private bool IsExistProcess(string processName)
        {


            Process[] MyProcesses = Process.GetProcesses();
            foreach (Process MyProcess in MyProcesses)
            {
                if (MyProcess.ProcessName.CompareTo(processName) == 0)
                {
                    return true;


                }
            }
            return false;
        }

3.4 为当前Windows服务设置可与桌面交互选项

      为"serviceProcessInstaller1" 的 Committed 事件添加以下操作:

      (注意引入 System.Management 命名空间)

     private void serviceProcessInstaller1_Committed(object sender, InstallEventArgs e)
        {
            try
            {
                ConnectionOptions myConOptions = new ConnectionOptions();
                myConOptions.Impersonation = ImpersonationLevel.Impersonate;
                ManagementScope mgmtScope = new System.Management.ManagementScope(@"root\CIMV2", myConOptions);


                mgmtScope.Connect();
                ManagementObject wmiService = new ManagementObject("Win32_Service.Name='" + serviceInstaller1.ServiceName + "'");


                ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");


                InParam["DesktopInteract"] = true;


                ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", InParam, null);


            }
            catch (Exception err)
            {
                Common.wLog(err.ToString());
            }
        }

执行效果: (不再需要手动去设置)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值