如何正常显示应用程序

时间:2013-11-19 10:06:37

标签: c# .net windows service process

我正在Windows 7 上创建一个复杂的服务,它通过加载.exe应用程序开始。实现此目标的唯一方法是在services.msc中启用“交互式服务检测”服务。

作为测试应用程序,我添加了以下代码,它只是打开系统计算器。它有效但不是预期的。我在启动服务时首先收到以下消息:

enter image description here

单击“查看此消息”时,它会按预期加载计算器,但会打开蓝色全屏模式,并在其中包含计算器。

我的问题基本上如下:如何自动显示应用程序,而不必提示用户“查看消息”,更重要的是,如何让应用程序正常显示,而不是这个“互动服务检测”沙箱?

这是我的示例服务的代码:

public partial class OpenCalculator : ServiceBase
    {
        public Process process;

        public OpenCalculator()
        {
            this.ServiceName = "Open Calculator";
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            start_calc();
        }

        protected override void OnStop()
        {
            process.Kill();
        }

        protected void start_calc()
        {
            try
            {
                process = new Process();
                process.StartInfo.FileName = @"C:\Windows\system32\calc.exe";
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.ErrorDialog = false;
                process.StartInfo.RedirectStandardError = true;
                process.StartInfo.RedirectStandardInput = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                process.Start();

                using (StreamWriter writer = File.AppendText("C:\\Users\\scaruana\\Desktop\\test.txt"))
                {
                    writer.WriteLine(process);
                }
            }
            catch (Exception ex)
            {
                using (StreamWriter writer = File.AppendText("C:\\Users\\scaruana\\Desktop\\test.txt"))
                {
                    writer.WriteLine(ex.Message);
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

服务在会话0中运行,您无法看到其桌面。交互式桌面托管在其他会话中。因此,例如,第一个交互式登录在会话1中运行。这意味着服务无法直接在交互式桌面上显示UI。

在旧版本的Windows(XP及更早版本)中,第一个交互式登录与服务共享会话0。因此,当您在服务控制管理器中启用允许服务与桌面交互选项时,该服务可以在交互式桌面上显示UI。然而,所有这些都以Vista结束,因为它存在安全风险。

因此,您需要启动一个新进程并专门强制它登录到已登录的交互式用户的桌面上。这不容易做到。此MSDN博客文章涵盖了您的选项:Launching an interactive process from Windows Service in Windows Vista and later

现在,您可以从服务开始新流程,并将新流程放到交互式桌面上。但这几乎肯定是解决问题的错误方法。正如您通过阅读链接文章所看到的那样,这样做很复杂。您的问题的标准解决方案是在登录用户的桌面上运行交互式过程。在您的服务需要显示UI之前,这一直是隐藏的。然后,该服务使用您首选的IPC机制与桌面应用程序通信,然后桌面应用程序显示UI。

答案 1 :(得分:0)

这个问题一直是令人非常沮丧的原因,我终于解决了我的问题。是的,我已经设法使服务加载GUI应用程序,即使每个人都说这是不可能的。虽然有一个警告 - “修复”可以被视为利用Windows中的漏洞,因为我使用的代码基本上通过了Vista和Windows 7 UAC。从本质上讲,应用程序始终以完全权限执行并绕过UAC。

如果有人遇到同样的问题,您需要做的是在PC上迭代登录用户列表,并选择在此会话(具有用户桌面)中打开UI应用程序,而不是在会话中0应该运行服务(并且没有桌面)。

对于某些人来说,这可能不是一个解决方案,因为它不安全。但就我而言,安全性不是主要问题,我只需要它来工作(必须是强制服务)。

希望这可以帮助那些遇到同样问题的人。