设置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();

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

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

设置c#windows服务描述及允许服务与桌面交互的几种方法

 

例如:

当我需要运行服务程序的时候,弹出我的应用程序,则要在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。

 

你可能感兴趣的:(windows)