C# 从Windows服务启动GUI应用程序-未显示窗口
我已经编写了一个简单的windows服务,它将启动C# 从Windows服务启动GUI应用程序-未显示窗口,c#,windows,windows-services,C#,Windows,Windows Services,我已经编写了一个简单的windows服务,它将启动 onstart()服务的方法。启动服务后,exe仅启动它 在内存中显示,但在资源管理器中不显示 我正试图从我的代码中启动一个calc.exe。它在内存中显示exe,但是 不进入我的视野(即在浏览器中) 下面是我在onStart()方法中启动exe的代码 根据定义,服务不是交互式的,所以当您从服务启动应用程序时,不应该期望显示任何用户界面元素 这是出于设计…服务在不同的帐户权限下运行(LocalService/NetworkService等),因
onstart()
服务的方法。启动服务后,exe仅启动它
在内存中显示,但在资源管理器中不显示
我正试图从我的代码中启动一个calc.exe
。它在内存中显示exe,但是
不进入我的视野(即在浏览器中)
下面是我在onStart()方法中启动exe的代码
根据定义,服务不是交互式的,所以当您从服务启动应用程序时,不应该期望显示任何用户界面元素
这是出于设计…服务在不同的帐户权限下运行(LocalService/NetworkService等),因此它们无法访问您的桌面(在您的登录帐户的控制下)
服务意味着默默地完成他们的工作,这是他们应该做的。(除了在windows事件日志中记录一些重要内容之外)服务在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;
}
正如前面提到的,windows服务“通常”在单独的帐户(“LocalSystem”或“NetworkService”)下运行。这就是为什么您可能看不到由您的服务启动的程序的UI的原因。此外,服务并不打算有UI,它们充当后台服务 但也要注意,通过服务启动应用程序可能会有很高的安全风险,因为应用程序使用与服务相同的权限运行。通常这将是本地系统帐户
我不知道你想用你的服务来实现什么,但是考虑使用Windows的自动启动功能而不是服务来运行你的应用程序。
< P>如果你打开你的服务的属性窗口,转到登录标签,然后检查“允许服务与桌面交互”复选框,你将得到你想要的行为。此外,根据您要运行的应用程序,您可能需要更改登录帐户。您希望看到什么?请尝试运行批处理文件。您尝试启动哪种类型的exe?请将您的问题重新表述为更有意义的问题。当浏览一系列问题时,它不会告诉你很多……而且,默认情况下,任务管理器只显示在您的登录帐户下运行的进程。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;
}