-->

WTSQueryUserToken总是抛出“试图引用不存在的令牌”在C#中的Windows 7(WT

2019-09-04 05:21发布

我试图从Windows服务推出的Windows 7的过程。

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

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服务登录为管理员用户。
  • 当我向上帝祈祷,撒旦,菩萨和雷尔。

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

没有什么工作,它总是抛出一模一样的例外。 我的想法......

Answer 1:

您必须WTSQueryUserToken否则添加SetLastError = true来DllImport属性, GetLastWin32Error是没有意义的。

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

获得由会话ID指定的登录用户的主访问令牌。 要成功地调用这个函数,调用应用程序必须在LocalSystem帐户的上下文中运行,并且有SE_TCB_NAME特权。



文章来源: WTSQueryUserToken always throws “An attempt was made to reference a token that does not exist” on Windows 7 in C#