Проблема с параметрами в CreateProcessAsUser
Мне было поручено создать службу Windows, способную запускать процесс для текущего интерактивного пользователя с использованием VB.NET 2005.
После некоторых исследований я создал следующий код:
Dim hToken As IntPtr = IntPtr.Zero
Dim LastW32Error As Integer
If WTSQueryUserToken(WTSGetActiveConsoleSessionId(), hToken) Then
Dim hTokenDup As IntPtr = IntPtr.Zero
If DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, Nothing, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, hTokenDup) Then
Dim hEnv As IntPtr = IntPtr.Zero
If CreateEnvironmentBlock(hEnv, hTokenDup, False) Then
Dim strCommandLine As String = "c:\\windows\\system32\\NotePad.exe"
Dim saProcessAttributes As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES
Dim saThreadAttributes As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES
Dim pi As New PROCESS_INFORMATION
Dim si As New STARTUPINFO
saProcessAttributes.nLength = Convert.ToUInt32(Marshal.SizeOf(saProcessAttributes))
saThreadAttributes.nLength = Convert.ToUInt32(Marshal.SizeOf(saThreadAttributes))
si.cb = Convert.ToUInt32(Marshal.SizeOf(si))
If Not CreateProcessAsUser(hTokenDup, Nothing, strCommandLine, saProcessAttributes, saThreadAttributes, False, 0, hEnv, Nothing, si, pi) Then
LastW32Error = Marshal.GetLastWin32Error()
EvtLog.WriteEntry("CreateProcessAsUser: " + CStr(LastW32Error))
End If
Else
LastW32Error = Marshal.GetLastWin32Error()
EvtLog.WriteEntry("CreateEnvironmentBlock: " + CStr(LastW32Error))
End If
DestroyEnvironmentBlock(hEnv)
Else
LastW32Error = Marshal.GetLastWin32Error()
EvtLog.WriteEntry("DuplicateTokenEx: " + CStr(LastW32Error))
End If
CloseHandle(hTokenDup)
Else
LastW32Error = Marshal.GetLastWin32Error()
EvtLog.WriteEntry("WTSQueryUserToken: " + CStr(LastW32Error))
End If
CloseHandle(hToken)
Но я получаю ошибку 87 (ERROR_INVALID_PARAMETER) при вызове CreateProcessAsUser. Кто-нибудь может указать мне, что я делаю неправильно?
Код реализован в виде службы Windows, которая работает под учетной записью LocalSystem.
1 ответ
- WTSQueryUserToken может вызываться только в LocalSystem
- WTSQueryUserToken возвращает PrimaryToken. Не нужно дублировать это.
- Этот токен уже имеет правильный sessionID и среду (он получен из текущего вошедшего в систему пользователя), поэтому нет необходимости создавать блок среды