zoukankan      html  css  js  c++  java
  • 设置c#windows服务描述及允许服务与桌面交互的几种方法(转)

    方法一:

    在ProjectInstaller.cs重写 install() ,Uninstall()方法

    public override void Install(IDictionary stateServer)
      {
       Microsoft.Win32.RegistryKey system,
        //HKEY_LOCAL_MACHINE/Services/CurrentControlSet
        currentControlSet,
        //.../Services
        services,
        //.../<Service Name>
        service,
        //.../Parameters - this is where you can put service-specific configuration
        config;
    
       try
       {
        //Let the project installer do its job
        base.Install(stateServer);
    
        //Open the HKEY_LOCAL_MACHINE/SYSTEM key
        system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
        //Open CurrentControlSet
        currentControlSet = system.OpenSubKey("CurrentControlSet");
        //Go to the services key
        services = currentControlSet.OpenSubKey("Services");
        //Open the key for your service, and allow writing
        service = services.OpenSubKey(this.serviceInstaller1.ServiceName, true);
        //Add your service's description as a REG_SZ value named "Description"
        service.SetValue("Description","PI实时数据采集:能源--每天8点或20点取一次数据;汽车衡--每天1点取一次数据;设备状态--每分钟取一次数据。");
        //(Optional) Add some custom information your service will use...
        //允许服务与桌面交互
        service.SetValue("Type",0x00000110);
        config = service.CreateSubKey("Parameters");
       }
       catch(Exception e)
       {
        Console.WriteLine("An exception was thrown during service installation:/n" + e.ToString());
       }
      }
    
      public override void Uninstall(IDictionary stateServer)
      {
       Microsoft.Win32.RegistryKey system,
        currentControlSet,
        services,
        service;
    
       try
       {
        //Drill down to the service key and open it with write permission
        system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
        currentControlSet = system.OpenSubKey("CurrentControlSet");
        services = currentControlSet.OpenSubKey("Services");
        service = services.OpenSubKey(this.serviceInstaller1.ServiceName, true);
        //Delete any keys you created during installation (or that your service created)
        service.DeleteSubKeyTree("Parameters");
        //...
       }
       catch(Exception e)
       {
        Console.WriteLine("Exception encountered while uninstalling service:/n" + e.ToString());
       }
       finally
       {
        //Let the project installer do its job
        base.Uninstall(stateServer);
       }
      }
    方法二:
    此方法经测试,发现无效,勾是选上了,但程序启动后还是没有界面出现,好像需要电脑重启才生效

    我们写一个服务,有时候要让服务启动某个应用程序,就要修改服务的属性,勾选允许服务与桌面交互,

    可以用修改注册表实现,我们必须在安装后操作,所以请重写Installer的OnAfterInstall。

           protected override void OnAfterInstall(System.Collections.IDictionary savedState) {
                RegistryKey rk = Registry.LocalMachine;
                string key = @"SYSTEM/CurrentControlSet/Services/" + this.sInstaller.ServiceName;
                RegistryKey sub = rk.OpenSubKey(key, true);
                int value = (int)sub.GetValue("Type");
                if (value < 256) {
                    sub.SetValue("Type", value | 256);
                }
                base.OnAfterInstall(savedState);
            }

    onstart的时候修改注册表   
       [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/你的服务名]   
       "Type"=dword:00000010   
       key    value+256   
       比如现在00000010是16+256=272   
       16进制就是00000110 

    方法三:
    使用System.ServiceProcess.ServiceController
            ConnectionOptions coOptions = new ConnectionOptions();
                coOptions.Impersonation = ImpersonationLevel.Impersonate;
                ManagementScope mgmtScope = new System.Management.ManagementScope(@"root/CIMV2", coOptions);
                mgmtScope.Connect();
                ManagementObject wmiService;
                wmiService = new ManagementObject("Win32_Service.Name='" + ServiceController.ServiceName + "'");
                ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
                InParam["DesktopInteract"] = true;
                ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", InParam, null);
                ServiceController.Start();

    描述:在自己写的一个系统服务程序,需要经常用到“允许与桌面进行交互”的设置,网上很多使用修改注册表的形式实现,我测试过,修改注册表后,选中的勾是选上了,

    但不能弹出应用程序;据说重启电脑后可以,但我不想重启,实际应用也不允许重启,故没有测试重启是否可行的情况。如图:

    例如:

    当我需要运行服务程序的时候,弹出我的应用程序,则要在Windows服务“允许服务与桌面交互”中打勾,

    当我不想弹出应用程序界面的时候,则去掉其中的勾选。

    实现方式:

    1.在服务程序安装时编程实现,ProjectInstaller.cs

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Configuration.Install;
    using Microsoft.Win32; //对注册表操作一定要引用这个命名空间
    
    
    namespace MonitorService
    {
        [RunInstaller(true)]
        public partial class ProjectInstaller : Installer
        {
            public ProjectInstaller()
            {
                InitializeComponent();            
                //this.Context.Parameters["ServerCode"].ToString(); // 读取安装时输入的服务器编号           
            }
    
            private void ProjectInstaller_AfterInstall(object sender, InstallEventArgs e)
            {
                //设置允许服务与桌面交互
                SetServiceTable("MonitorService");            
            }
            /// <summary>
            /// 设置允许服务与桌面交互 ,修改了注册表,要重启系统才能生效
            /// </summary>
            /// <param name="ServiceName">服务程序名称</param>
            private void SetServiceTable(string ServiceName)
            {
                RegistryKey rk = Registry.LocalMachine;
                string key = @"SYSTEM/CurrentControlSet/Services/" + ServiceName;
                RegistryKey sub = rk.OpenSubKey(key, true);
                int value = (int)sub.GetValue("Type");
                sub.SetValue("Type", value | 256);
            }
        }
    }

    2.注册表修改

    onstart的时候修改注册表   
       [HKEY_LOCAL_MACHINE"SYSTEM"CurrentControlSet"Services"你的服务名]   
       "Type"=dword:00000010   
       key    value+256   
       比如现在00000010是16+256=272   
       16精制就是00000110

    3.SC程序修改, 允许与桌面进行交互

     在dos命令提示符下输入:
    sc config MonitorService type= interact type= own

     回车即可。

    可以用批处理的方式实现,把下面代码保存为 myservice.bat 即可:

     rem 配置服务程序为允许与桌面进行交互方式
    @echo "准备停止服务程序..."
    sc stop MyService
    @echo "设置允许与桌面进行交互方式允许"
    sc config MyService type= interact type= own
    @echo "正在重新启动服务..."
    sc start MyService
    @echo "启动服务成功!"

    取消“允许与桌面进行交互”

    DOS命令提示符下运行下面语句即可:

     sc config MyService type= own

    经测试:1,2 可以选中“允许与桌面进行交互”,但启动服务的时候,不能弹出应用程序的界面。

               3 可以完美实现所有要求。

    至此,我遇到的问题也完美的得到解决。

    用VS2003部署,让服务程序安装完后立即启动服务并且选中“允许服务与桌面交互”及添加服务描述的方法

    -----------立即启动--------------   
    private void serviceInstaller1_AfterInstall(object sender, System.Configuration.Install.InstallEventArgs e)   
    {   
    ServiceController myService = new ServiceController("XJOAPigeonholeServer");   
    myService.Start();   
    myService.Dispose();   
    }   
      
      
    添加描述:1.1没有直接方法,2.0里有直接的方法 ServiceInstaller.Description   
    //----------------------------添加服务描述信息 开始 ------------   
    public override void Install(IDictionary stateServer)   
    {   
    Microsoft.Win32.RegistryKey system,   
    //HKEY_LOCAL_MACHINE/Services/CurrentControlSet   
    currentControlSet,   
    //.../Services   
    services,   
    //.../ <Service Name>   
    service,   
    //.../Parameters - this is where you can put service-specific configuration   
    config;   
    try   
    {   
    //Let the project installer do its job   
    base.Install(stateServer);   
      
    //Open the HKEY_LOCAL_MACHINE/SYSTEM key   
    system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");   
    //Open CurrentControlSet   
    currentControlSet = system.OpenSubKey("CurrentControlSet");   
    //Go to the services key   
    services = currentControlSet.OpenSubKey("Services");   
    //Open the key for your service, and allow writing   
    service = services.OpenSubKey(this.serviceInstaller1.ServiceName, true);   
    //Add your service's description as a REG_SZ value named "Description"   
    service.SetValue("Description","XJOA系统自动归档服务(BeijiOffice)");   
    //(Optional) Add some custom information your service will use...   
    //允许服务与桌面交互   
    service.SetValue("Type",0x00000110);   
    config = service.CreateSubKey("Parameters");   
    }   
    catch(Exception e)   
    {   
    Console.WriteLine("An exception was thrown during service installation:/n" + e.ToString());   
    }   
    }   
      
    public override void Uninstall(IDictionary stateServer)   
    {   
    Microsoft.Win32.RegistryKey system,   
    currentControlSet,   
    services,   
    service;   
      
    try   
    {   
    //Drill down to the service key and open it with write permission   
    system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");   
    currentControlSet = system.OpenSubKey("CurrentControlSet");   
    services = currentControlSet.OpenSubKey("Services");   
    service = services.OpenSubKey(this.serviceInstaller1.ServiceName, true);   
    //Delete any keys you created during installation (or that your service created)   
    service.DeleteSubKeyTree("Parameters");   
    //...   
    }   
    catch(Exception e)   
    {   
    Console.WriteLine("Exception encountered while uninstalling service:/n" + e.ToString());   
    }   
    finally   
    {   
    //Let the project installer do its job   
    base.Uninstall(stateServer);   
    }   
    }   
    //---------------------------- 结束 ----------------------------   

    四、这一服务程序运行时没有图形界面?

    不错,刚才直接运行mfc1.exe时我们看到了图形界面,但在服务列表中用右键菜单中的“启动”时却看不到任何界面。这该怎么办?

    我们还需要在使用CreateService函数时(Install()中),加上一个参数,这样才能允许程序与桌面交互,也就是可以显示界面。这个参数是SERVICE_INTERACTIVE_PROCESS。

    填加后的CreateService:

      SC_HANDLE hService = ::CreateService(
         hSCM, m_szServiceName, m_szServiceName,
         SERVICE_ALL_ACCESS,
    SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
         SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
         szFilePath, NULL, NULL, _T("RPCSS"), NULL, NULL);

      再次编译mfc1,卸载服务后,安装服务。我们可以看到,通过服务列表启动mfc1,原有的对话框出现了。

    如需将服务设为自动启动,则将 SERVICE_DEMAND_START 改为 SERVICE_AUTO_START。

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 王后传说
    Java实现 蓝桥杯VIP 算法训练 王后传说
    Java实现 蓝桥杯VIP 算法训练 特殊的数字四十
    win7桌面图标小盾牌怎么去掉(2种方法)
    使用GO语言灵活批量ssh登录服务器执行操作
    2016 Web 开发资源工具大搜罗
    sqlite的源代码加密,以及其它一些文章
    SQLite 对中文路径的支持(用到了StringToWideChar和Utf8Encode在D7的System单元中自带)
    AMD规范与CMD规范的区别
    值类型和引用类型、可空类型、堆和栈、装箱和拆箱
  • 原文地址:https://www.cnblogs.com/tianma3798/p/3835787.html
Copyright © 2011-2022 走看看