我正在尝试从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。
我试图将其作为:
运行我还为可执行文件创建了一个清单,要求管理员提升。
没有任何作用,它总是抛出完全相同的异常。我没有想法......
答案 0 :(得分:2)
您必须将SetLastError = true添加到WTSQueryUserToken的DllImport属性,否则GetLastWin32Error没有意义。
此外,您必须在LocalSystem帐户as stipulated in the documentation(而不仅仅是“管理员用户”)的上下文中运行此代码:
获取指定的登录用户的主要访问令牌 会话ID。要成功调用此函数,请调用 应用程序必须在LocalSystem的上下文中运行 帐户并拥有SE_TCB_NAME权限。