【问题标题】:Launching GUI App from Windows Service - Window Does Not Appear从 Windows 服务启动 GUI 应用程序 - 窗口不出现
【发布时间】:2010-11-09 16:54:50
【问题描述】:

我编写了一个简单的 Windows 服务,它将启动在 onstart() 服务的方法。启动服务后,exe仅启动 出现在内存中,但在资源管理器中不显示。

我正在尝试从我的代码中启动calc.exe。它显示了内存中的 exe,但它 在资源管理器中没有出现在我的视图中(即)。

下面是我在 onStart() 方法中启动 exe 的代码

    Process pr=new Process();
    pr.StartInfo.FileName="calc.exe";
    pr.StartInfo.WindowStyle=ProcessWindowStyle.Maximized;
    pr.StartInfo.CreateNoWindow=false;
    pr.Start();
//  pr.WaitForExit();

【问题讨论】:

  • 你期待什么?请尝试运行批处理文件。
  • 您要启动什么类型的 exe?
  • 请将您的问题重新表述为更有意义的内容。浏览问题列表时,它并不能说明很多...

标签: c# windows windows-services


【解决方案1】:

服务在 Vista 或更高版本的其他会话中运行,并且直接从服务启动的应用程序默认在同一会话中启动。可以在其他会话中启动应用程序 - 您必须找到用户会话的 id 并使用 CreateProcessAsUser。

如果有多个用户登录并且您需要为所有用户启动程序,您必须找到所有会话的 ID。

这里是示例代码:

int session = Win32.WTSGetActiveConsoleSessionId();
if (session == 0xFFFFFFFF)
{
    return false;
}

IntPtr userToken;
bool res = Win32.WTSQueryUserToken(session, out userToken);
if (!res)
{
    this.log.WriteEntry("Error WTSQueryUserToken");
    return false;
}

string path = GetPath();
string dir = Path.GetDirectoryName(path);
Win32.STARTUPINFO si = new Win32.STARTUPINFO();
si.lpDesktop = "winsta0\\default";
si.cb = Marshal.SizeOf(si);

Win32.PROCESS_INFORMATION pi = new Win32.PROCESS_INFORMATION();
Win32.SECURITY_ATTRIBUTES sa = new Win32.SECURITY_ATTRIBUTES();
sa.bInheritHandle = 0;
sa.nLength = Marshal.SizeOf(sa);
sa.lpSecurityDescriptor = IntPtr.Zero;

if (!Win32.CreateProcessAsUser(userToken,       // user token
                                path,           // exexutable path
                                string.Empty,   // arguments
                                ref sa,         // process security attributes ( none )
                                ref sa,         // thread  security attributes ( none )
                                false,          // inherit handles?
                                0,              // creation flags
                                IntPtr.Zero,    // environment variables
                                dir,            // current directory of the new process
                                ref si,         // startup info
                                out pi))        // receive process information in pi
{
    int error = Marshal.GetLastWin32Error();
    this.log.WriteEntry("Error CreateProcessAsUser:" + error);
    return false;
}

【讨论】:

    【解决方案2】:

    服务在不同的帐户权限(LocalService/NetworkService 等)下运行,因此它们无权访问您的桌面(在您的登录帐户的控制下)。

    服务应该默默地完成他们的工作,这就是他们应该做的。 (除了当他们有重要的事情要说时在 Windows 事件日志中记录一些东西)

    【讨论】:

    • 此外,默认情况下,任务管理器仅显示在 您的 登录帐户下运行的进程。
    【解决方案3】:

    如果您打开服务的属性窗口,请转到“登录”选项卡,然后选中“允许服务与桌面交互”复选框,您将获得所需的行为。此外,根据您要运行的应用程序,您可能需要更改登录帐户。

    【讨论】:

      【解决方案4】:

      根据定义,服务不是交互式的,因此您不应期望在从服务启动应用程序时显示任何用户界面元素。

      这是设计使然...

      【讨论】:

        【解决方案5】:

        就像其他人已经提到的那样,Windows 服务“通常”在单独的帐户(“LocalSystem”或“NetworkService”)下运行。这就是您可能看不到由您的服务启动的程序的 UI 的原因。此外,服务不具有 UI,它们充当后台服务。

        但还要注意,通过服务启动应用程序可能存在很高的安全风险,因为应用程序运行的权限与您的服务相同。通常这将是本地系统帐户。

        我不知道你想用你的服务实现什么,但考虑使用 windows 的自动启动功能而不是服务来运行你的应用程序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-09-06
          • 1970-01-01
          • 2011-05-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-04
          • 1970-01-01
          相关资源
          最近更新 更多