如何获取当前登录用户的会话ID?

问题描述 投票:0回答:4

我正在使用

从 Windows 服务内部运行一个进程
ProcessStartInfo processStartInfo = new ....
Process.Start(processStartInfo);

问题是,如果我在本地系统帐户下运行服务,它运行正常,但不显示程序窗口。 我尝试将用户凭据放入服务属性中,但随后“允许服务与桌面交互”复选框被禁用。

我真的需要运行从服务调用它的应用程序,并且我真的需要查看应用程序的窗口。

请帮助我。

UPD。好吧,您使用 Process.Start 的重载版本,它需要用户名、密码和域 - 它将把程序拉到桌面。但现在它在一个凭据下启动应用程序,但在不同用户的桌面上显示该应用程序。怎么会呢?

UPD2:我有一个主意!我可以使用 Sysinternals Suite 中的 psexec.exe。但问题是我需要“以管理员身份”默默地启动那件事。我不知道怎么办。 我的意思是,即使您已经拥有管理员权限,有时您也必须手动说“以管理员身份运行”,确认 UAC,然后才可以开始。我不知道如何在不带 UAC 的情况下默默地运行某些东西....

UPD3:亲爱的主。我有那个东西!终于。

好的。一开始问题确实出在会话 0 隔离上。因此,我需要构建一个可以从服务启动的中间应用程序,然后该应用程序又应该通过 RPC 启动我的应用程序并将其带到桌面。我决定使用 psexec 工具,而不是构建中间层应用程序(无论如何,它完全按照我需要的方式工作 - 通过 RPC)。 当我尝试在本地系统帐户下使用该工具时,由于某种原因它不起作用。然后我意识到 - 原因是 MS 在每个 pstool 中放入了该死的 EULA 弹出对话框,并且无法在本地系统帐户下单击按钮确认对话框。 因此解决方案是在注册表 HKU.DEFAULT\Software\Sysinternals\PsExec 中创建一个键,其 DWORD 值 EulaAccepted = 1

万岁,现在可以了! 但!现在我需要将程序带到当前登录用户的屏幕。为此,我需要会话 ID!

那么问题是:如何获取当前登录用户的session id?如果还没有人登录会发生什么?那会是什么会话 ID?

UPD4:就是这样!我得到了那个!

[DllImport("Kernel32.dll", EntryPoint = "WTSGetActiveConsoleSessionId")] 公共静态 extern int WTSGetActiveConsoleSessionId();

谢谢大家!

c# process service psexec createprocessasuser
4个回答
4
投票

您可以使用

WTSGetActiveConsoleSessionId
(从终端服务 API)获取活动控制台会话 ID。您只能在 WinXP/Win2K3 或更高版本上使用它,但这应该没问题,因为您可以在 Win2K 或更早版本上将会话 ID 硬编码为 0。这是它的
PInvoke
签名:

[DllImport("Kernel32.dll", SetLastError = true)]
[return:MarshalAs(UnmanagedType.U4)]
public static extern int WTSGetActiveConsoleSessionId ( );

至于在用户会话中启动进程,您可以参考我在here给出的答案。它基本上涉及调用四个API;

WTSGEtConsoleSessionId
WTSQueryUserToken
DuplicateTokenEx
,然后是
CreateProcessAsUser
,它可以在任何运行 WinXP/Win2K3 或更高版本的计算机上运行。


3
投票

一种解决方案是让第三个进程充当中介,并告诉它通过 RPC/命名管道启动应用程序。

流程:

  • Windows 服务
  • 中介申请
  • 您要运行的应用程序

垫片创建一个通信端点(命名管道、WCF 端点)并侦听它。当它收到继续的消息时,它会启动您想要运行的应用程序。

然后,当 Windows 服务想要启动应用程序时,它会找到并打开端点(命名管道、WCF 端点),并发送消息来启动应用程序。然后,中间应用程序负责进程启动业务,并且没有 Windows 服务所具有的任何限制。

使这个中间过程从登录开始,然后就可以开始了。

这类似于当您需要运行与桌面交互的测试时 Microsoft 测试代理/控制器的工作方式。


2
投票

这不需要中间过程就可以完成,但是需要 500 多行代码才能完成。基本上,您希望以当前登录用户的身份启动第二个进程。对于 Vista/7,该用户将有自己的 winlogon 进程,而对于 XP,他们将有一个资源管理器进程。您需要获取该正在运行的进程的主令牌、环境块、安全属性和线程安全属性,然后使用所有这些信息调用 Windows API 函数 CreateProcessAsUser,确保您也选择了正确的窗口站(通常为“WinSta0\Default” ”)。这都是可行的,但您可能会通过第二个进程和 IPC 的其他建议获得更好的时间。


1
投票

如果您在比 WindowsXP 更新的系统上尝试此操作,则此操作将不起作用。这是因为 Vista / Windows 7 中引入了一项称为会话 0 隔离的新功能。 http://msdn.microsoft.com/en-us/library/bb756986.aspx 您将无法让服务启动的应用程序显示在用户桌面上。

© www.soinside.com 2019 - 2024. All rights reserved.