从Windows服务启动GUI应用程序 - 窗口不会出现

时间:2009-07-10 12:37:36

标签: c# windows windows-services

我编写了一个简单的Windows服务,它将启动一个指定的exe 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();

5 个答案:

答案 0 :(得分:10)

服务在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;
}

答案 1 :(得分:4)

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

服务意味着默默地完成他们的工作,这就是他们应该做的事情。 (除了在事件日志中记录某些重要事项时),

答案 2 :(得分:3)

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

答案 3 :(得分:1)

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

这是设计......

答案 4 :(得分:0)

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

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

我不知道您尝试使用服务实现了什么,但考虑使用Windows的自动启动功能而不是服务来运行您的应用程序。