Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WTSQueryUserToken始终抛出;试图引用一个不存在的令牌";在C中的Windows7上#_C#_Windows_Service_Pinvoke_Elevation - Fatal编程技术网

C# WTSQueryUserToken始终抛出;试图引用一个不存在的令牌";在C中的Windows7上#

C# WTSQueryUserToken始终抛出;试图引用一个不存在的令牌";在C中的Windows7上#,c#,windows,service,pinvoke,elevation,C#,Windows,Service,Pinvoke,Elevation,我正在尝试从Windows 7上的Windows服务启动进程 这是我获取用户令牌的代码 uint sessionId = Kernel32.WTSGetActiveConsoleSessionId(); var userTokenPtr = new IntPtr(); if (!WtsApi32.WTSQueryUserToken(sessionId, out userTokenPtr)) { int lastError = Marshal.GetLastWin32Error();

我正在尝试从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);
}
我从这个答案中提取了代码,并按原样复制了它:

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

我已尝试以以下方式运行此操作:

  • 调试进程(使用Visual Studio宿主进程)
  • 调试进程(没有Visual Studio宿主进程)
  • 管理员用户
  • 提升的管理员用户
  • Windows服务
  • 以管理员用户身份登录的Windows服务
  • 当我向上帝、撒旦、佛陀和雷尔祈祷时
我还为需要管理员提升的可执行文件创建了清单


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

您必须将SetLastError=true添加到WTSQueryUserToken的DllImport属性中,否则没有意义

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

获取由指定的已登录用户的主访问令牌 会话ID。要成功调用此函数,调用 应用程序必须在LocalSystem的上下文中运行 帐户并具有SE_TCB_名称权限


必须将
SetLastError=true
添加到WTSQueryUserToken的DllImport属性中,否则,GetLastWin32Error没有意义。另外,您是否按照文档中的规定在LocalSystem帐户的上下文中运行它(而不仅仅是“管理员用户”)?这是RTFM时刻之一。。。我所缺少的只是将其作为LocalSystem帐户运行。我假设我自己的用户有权创建一个流程本身,但事实并非如此。你可以将此添加为答案,如果你想要你应得的代表积分,我会接受,或者我今天晚些时候会这样做。