在 Windows 7 上,WTSQueryUserToken 在 C# 中始终抛出“尝试引用不存在的令牌”

2023-12-03

我正在尝试从 Windows 7 上的 Windows 服务启动进程。

这是我获取用户令牌的代码。

uint sessionId = Kernel32.WTSGetActiveConsoleSessionId();
var userTokenPtr = new IntPtr();
if (!WtsApi32.WTSQueryUserToken(sessionId, out userTokenPtr))
{
    int lastError = Marshal.GetLastWin32Error();
    throw new Win32Exception(lastError);
}

这些是 DllImport 语句:

public class Kernel32
{
    [DllImport("kernel32.dll", EntryPoint = "WTSGetActiveConsoleSessionId")]
    public static extern uint WTSGetActiveConsoleSessionId();
}

public class WtsApi32
{
    [DllImport("Wtsapi32.dll", EntryPoint = "WTSQueryUserToken")]
    public static extern bool WTSQueryUserToken(UInt32 sessionId, out IntPtr phToken);
}

我从这个答案中获取了代码并按原样复制:https://stackoverflow.com/a/11266955/410075

它总是抛出 Win32Exception 并显示消息“尝试引用不存在的令牌”。这是数据:sessionId = 1 和lastError = 1008。

我尝试将其运行为:

  • 调试进程(使用 Visual Studio 托管进程)
  • 调试进程(没有 Visual Studio 托管进程)
  • 管理员用户
  • 提升的管理员用户
  • 一个 Windows 服务。
  • 以管理员用户身份登录的 Windows 服务。
  • 当我向上帝、撒旦、佛陀和雷尔祈祷时。

我还为可执行文件创建了一个清单,以要求管理员提升。

什么都不起作用,它总是抛出完全相同的异常。我没有主意了...


您必须将 SetLastError = true 添加到 WTSQueryUserToken 的 DllImport 属性,否则,获取最后一个Win32错误没有意义。

此外,您必须在 LocalSystem 帐户的上下文中运行此代码按照文件规定(不仅仅是“管理员用户”):

获取由指定的登录用户的主访问令牌 会话 ID。要成功调用此函数,调用 应用程序必须在本地系统的上下文中运行 帐户并拥有 SE_TCB_NAME 权限。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Windows 7 上,WTSQueryUserToken 在 C# 中始终抛出“尝试引用不存在的令牌” 的相关文章

随机推荐