2013-05-18 1 views
3

Я пытаюсь запустить процесс из службы Windows на Windows 7.WTSQueryUserToken всегда бросает «была сделана попытка сослаться на маркер, который не существует» на Windows 7 в C#

Это мой код получить токен пользователя.

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 входит в систему как пользователь admin.
  • Как я молился Богу, сатане, Будде и Раэлю.

Я также создал манифест для исполняемого файла, требующего администратора.

Ничего не работает, и это всегда вызывает точно такое же исключение. Я вне идеи ...

+2

Вы должны ** добавить 'SetLastError = true' к атрибуту DllImport для WTSQueryUserToken, иначе GetLastWin32Error не имеет смысла. Кроме того, выполняете ли вы это в контексте учетной записи LocalSystem, как указано в документации (а не только «пользователь admin»)? –

+0

Это один из тех моментов RTFM ... Все, чего мне не хватало, это запустить его как учетную запись LocalSystem. Я предположил, что у моего собственного пользователя будет разрешение на создание процесса как самого себя, но это не так. –

+0

Вы можете добавить это как ответ, и я соглашусь с ним, если вы хотите, чтобы ваши заслуженные репутационные очки или я сделаю это позже сегодня. –

ответ

2

Вы должны добавить SetLastError = true для атрибута DllImport для WTSQueryUserToken, иначе GetLastWin32Error не имеет смысла.

Кроме того, необходимо запустить этот код в контексте LocalSystem счета as stipulated in the documentation (а не просто «пользователя с правами администратора»):

Получает первичный маркер доступа вошедшего в систему пользователя определяется идентификатор сеанса. Чтобы успешно выполнить эту функцию, приложение-вызов должно выполняться в контексте учетной записи LocalSystem и иметь привилегию SE_TCB_NAME.

Смежные вопросы