博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Allow windows service to "Interact with desktop"
阅读量:7131 次
发布时间:2019-06-28

本文共 5393 字,大约阅读时间需要 17 分钟。

Typically, services are designed to run unattended without any UI with any need to interact with desktop or any GUI application. However, in some cases, it is desired to let the service show and communicate with graphical applications. A reason might be to track an already developed application and start this app if closed. Or you might want some input from the user or want to alert him immediately about something serious that has happened. Whatever the reason be, there is always a need to find a way to enable your service to display the GUI application in an interactive windows satiation.

Solution is one click away and we only need to mark the "Allow Service to interact with desktop" as checked. But the question is can we do this programmatically? If yes then how? 
four.gif
There are four ways to change the windows service options and we will discuss them one by one. But before that you need to know that to make a service interact with the desktop, the service

  • Account type must be Local System.
  • Service type must be Own Process or Shared Process.

1. Through Windows Registry
A service installed on the system has its options saved in the system registry under "System\CurrentControlSet\Services"in LocalMachine key with your service name. The name/value pair we are interested in is "type". Its type is integer and it is equivalent to ServiceType in its value. Here is how we can do this.
var ServiceKeys = Microsoft.Win32.Registry                
.LocalMachine.OpenSubKey(String.Format( @"System\CurrentControlSet\Services\{0}", ServiceName), true);
            
try
   {
      var ServiceType = (ServiceType)(int)(ServiceKeys.GetValue("type"));
 
      //Service must be of type Own Process or Share Process
     if (((ServiceType & ServiceType.Win32OwnProcess) !=                                               ServiceType.Win32OwnProcess)
          && ((ServiceType & ServiceType.Win32ShareProcess) !=                                       ServiceType.Win32ShareProcess))
       {
        throw new Exception("ServiceType must be either Own Process or Shared   Process to enable interact with desktop");
       }
 
      var AccountType = ServiceKeys.GetValue("ObjectName");
      //Account Type must be Local System
      if (String.Equals(AccountType, "LocalSystem") == false)
         throw new Exception("Service account must be local system to enable interact with desktop");
      //ORing the InteractiveProcess with the existing service type
      ServiceType newType = ServiceType | ServiceType.InteractiveProcess;
                ServiceKeys.SetValue("type", (int)newType);
    }
    finally
    {
      ServiceKeys.Close();
 } 
This requires the system startup since registry change is not notified to Service Control Manager (SCM), change is visible in service property window though. It is because property window always load recent settings from the registry.
 
2. Through WMI
If you do not want to play with the registry or restart seems not a good option in your case then there is another solution for you which is WMI. WMI class WIN32_Service let you play with the windows service. This class provides a method called "Change" which allows you to modify the service. You can read more about WIN32_Service . Here is how to do the job. 
//Create a Management object for your service.
            var service = new System.Management.ManagementObject(
                String.Format("WIN32_Service.Name='{0}'", ServiceName));
            try
            {
                var paramList = new object[11];
                paramList[5] = true;//We only need to set DesktopInteract parameter
                var output = (int)service.InvokeMethod("Change", paramList);
                //if zero is returned then it means change is done.
                if (output != 0)
                    throw new Exception(string.Format("FAILED with code {0}", output));
 
            }
            finally
            {
                service.Dispose();
            } 
Good thing in this technique is it does not require any system reboot. Only a service restart is required.
3. Through Command
SC is a command-line utility for managing services. SC is available for scripting and script can be run through .net. It means we can use sc command to configure the windows service. You can see a complete list  to unleash the power of this command. For now our purpose is to enable the "Interact with desktop" option and config command is there to do this job. What we need to do is run the command through code and if output is "[SC] ChangeServiceConfig SUCCESSS" then it means our job is done. Here is how to do this
string command = String.Format("sc config {0} type= own type= interact", ServiceName);
var processInfo = new System.Diagnostics.ProcessStartInfo()
  {
    //Shell Command
    FileName = "cmd" 
    ,
    //pass command as argument./c means carries 
    //out the task and then terminate the shell command
    Arguments = "/c" + command 
    ,
   //To redirect The Shell command output to process stanadrd output
   RedirectStandardOutput = true 
   ,
  // Now Need to create command window. 
  //Also we want to mimic this call as normal .net call
  UseShellExecute = false 
  ,
  // Do not show command window
  CreateNoWindow = true                 
                
};
 
 var process = System.Diagnostics.Process.Start(processInfo);          
 
 var output = process.StandardOutput.ReadToEnd();
 if (output.Trim().EndsWith("SUCCESS") == false)
     throw new Exception(output); 
4. Through interop
Question is, do we need this when we have three nice options using managed code. For me it is useless and that's why I am leaving it 
Let me end this article with words of caution.
The "Interact with Desktop" option is not supported by Microsoft in Windows Vista and newer. So use it wisely and redesign your app if there is a solid chance that your service can be installed on Vista or Server 2008.

 

Link:

转载于:https://www.cnblogs.com/Googler/p/3208354.html

你可能感兴趣的文章
Android Root Source Code: Looking at the C-Skills
查看>>
shell 脚本简介
查看>>
【Transact-SQL】一句SQL删除重复记录
查看>>
bash编程之算术运算
查看>>
服务器类型
查看>>
安装VIM8和vim-go插件
查看>>
安装SCCM2012 R2
查看>>
CentOS6.5 NFS服务器的安装与基本参数
查看>>
I/O多路转接之select
查看>>
让有些“-l”链接静态库,而另一些链接共享库?
查看>>
使用Webstorm操作git
查看>>
uboot移植之start_armboot()函数分析
查看>>
移动办公是不能阻挡的未来办公趋势
查看>>
docker简单介绍及安装
查看>>
DNS服务(1)基本概念详解
查看>>
Redhat7DNS搭建
查看>>
python之rabbitMQ
查看>>
sys和shutil
查看>>
Django模板——html转义
查看>>
数理统计总结篇第一章
查看>>