2

我有一个在“SYSTEM”帐户下运行的 Windows 服务,用于检查每个登录用户是否正在运行特定的应用程序。如果应用程序没有运行,服务将启动它(在相应的用户名下)。
我正在尝试使用 CreateProcessAsUser() 来实现我的目标。该服务确实以相应的用户名启动应用程序,但未绘制 GUI。(是的,我确保启用了“允许服务与桌面交互”复选框)。

系统:XP SP3,语言:C#

以下是一些可能感兴趣的代码:

PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION();  
startInfo.cb = Marshal.SizeOf(startInfo);  
startInfo.lpDesktop = "winsta0\\default";  
bResult = Win32.CreateProcessAsUser(hToken, null, strCommand, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref startInfo, out processInfo);  

据我了解,设置 startInfo.lpDesktop = "winsta0\default"; 应该使用相应用户的桌面。
甚至与这里所说的相反:http: //support.microsoft.com/kb/165194,我尝试将 lpDesktop 设置为 null,或者根本不设置它,两者都给出相同的结果:进程以预期的名义启动用户和我可以看到窗口标题栏的一部分。“不可见”窗口拦截鼠标点击事件,按预期处理它们。它只是不画自己。

有没有人熟悉这样的问题并且知道我做错了什么?

4

1 回答 1

1

MSDN 有一个示例,说明如何作为另一个用户在窗口站和桌面对象上设置显式权限来创建进程:

CreateProcessAsUser() 窗口站和桌面

您可以使用 P/Invoke 将代码移植到 C#,也可以使用 C++/CLI 程序集。

但是,请注意,您的方案不受支持,并且可能会因 Vista(和 Windows 7)的Session-0 隔离而中断(下载右侧的白皮书)。

于 2010-04-06T11:01:30.847 回答