zoukankan      html  css  js  c++  java
  • C#实现WinForm随WINDOWS服务一起启动

    vote up 0 vote down star

    一.应用场景

        客户服务器上装的软件越来越多,由原来一个人管理改为几个人同时管理了,因此不同的管理员需要经常进行远程登陆,注销操作。
        服务器上原有的一些程序是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(020));
                                    Common.wLog(
    "完成启动服务: " + myService.ServiceName + " . " + System.DateTime.Now.ToString());
                                }
                                
    break;
                            
    case ServiceControllerStatus.StopPending:

                                
    break;
                            
    default:

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


      3.2 检查并启动对应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.3 为当前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());
                }
            }

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

    图 1 允许Windows服务与桌面交互参数设置

    四.创建Windows服务

    Flash格式下载
    http://www.cnblogs.com/furenjun/archive/2008/11/24/windowsServiceSample.html

     

    图 2 创建Windows服务

    五.修改参数并启动服务

    5.1   运行FRJWindowsServiceSetup.msi安装程序,安装服务. 

    5.2修改”MdcMaxServiceSetup”文件夹下的 “FRJWindowsService.exe.config” 文件中的配置信息;

    设置在GUI应用程序启动之前需要启动Windows 服务;

    本例以Sql2005服务为例.

    注意: Sql2005服务器名要根据实际电脑上的Sql2005服务器名来设置;

    启动程序的路径同样应根据实际情况来设置;

    如要再启动其他Windows服务或程序,可在配置文件中添加;

    注意格式:

    1. 启动windows服务 key=”ServiceName”+唯一序号  value=”windows服务名称

    2. 启动 应用程序  key=”ProgramPath”+唯一序号    value=”应用程序路径信息

    图 3   配置文件中的参数设置

    点击 开始-->运行,  输入 services.msc 打开服务管理界面.按下图所示操作.

     

    图 4  启动Windows服务
    重启电脑或注销当前用户,隔一段时间再登陆,查看程序运行效
  • 相关阅读:
    从Active Directory中获取用户信息 [转载]
    使用System.DirectoryServices.Protocols实现对AD的简单操作[转载]
    phpMyAdmin 尝试连接到MySQL 服务器的错误解决方法
    MYSQL phpmyadmin恢复数据(#2006 MySQL server has gone away)
    解决IBM T23笔记本的Resource Conflict 问题
    打造自己地图AxTOCContrl树形控件——XUTocControl(成功解决节点控件拖拽问题)
    mantis配置收集(转载)
    仿World Wind构造自己的C#版插件框架——WW插件机制精简改造
    两台oracle数据库相互导数据(转载)
    将SATA硬盘驱动嵌入Windows XP安裝盘(转载)
  • 原文地址:https://www.cnblogs.com/liufei88866/p/1732369.html
Copyright © 2011-2022 走看看