Оказывается, существует поддерживаемый способ сделать это. В основном вам нужно сделать двойной косвенный, чтобы сделать эту работу. Сначала вы хотите получить сеанс для токена пользователя с помощью WTSQueryUserToken . Затем вам нужно получить связанный токен администратора с GetTokenInformation (поиск информации TokenLinkedToken). Теперь, когда у вас есть admintokn, вы можете вызвать CreateProcessAsUser с этим токеном. Если вам нужен блок среды, вы можете вызвать CreateEnvironmentBlock , чтобы получить правильные переменные среды.
Вот фрагмент кода VB, который я получил от сотрудника (который передал этот совет):
Public Function StartAppInSessionAsAdmin(ByVal SessionID As String, ByVal WinstationName As String, ByVal AppName As String) As Integer
Dim hToken As IntPtr
Dim hLinkedToken As IntPtr
Dim bRet As Boolean
Dim pi As New PROCESS_INFORMATION
Dim si As New STARTUPINFO
Dim err As Integer
Dim iret As Integer
Dim lpEB As IntPtr
Dim TLT As New TOKEN_LINKED_TOKEN
Dim TLTSize As Integer
Dim retSize As Integer
si.lpDesktop = WinstationName '”Winsta0\default”
si.cb = Marshal.SizeOf(si)
TLTSize = Marshal.SizeOf(TLT.LinkedToken)
'get SessionID token
bRet = WTSQueryUserToken(Integer.Parse(SessionID), hToken)
'we need to get the TokenLinked Token
bRet = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, hLinkedToken, TLTSize, retSize)
'Use CreateEnvironment Block with the original token to create an environment for the new program with the USER Environment
bRet = CreateEnvironmentBlock(lpEB, hToken, False)
If bRet Then
'Call CreateProcessAsUser to create the process using the user's modified Token
iret = CreateProcessAsUser(hLinkedToken, Nothing, AppName, 0, 0, False, 1072, lpEB, Nothing, si, pi)
'Give user a feedback
If iret <> 0 Then
GiveFeedback(SessionID, "Message from StartAppInSessionAsAdmin", "CreateProcessAsUser succeeded", 2)
Else
err = Marshal.GetLastWin32Error
GiveFeedback(SessionID, "Message from StartAppInSessionAsAdmin", "CreateProcessAsUser failed with error " & err.ToString, 5)
End If
End If
End Function
Он также написал сообщение в блоге с дополнительной информацией: http://blogs.msdn.com/b/itasupport/archive/2010/03/29/uac-bypass-o-meglio-il-modo-supportato-e-by-design-di-aggirare-la-uac.aspx