0

我被分配构建一个 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)

但是我在调​​用 CreateProcessAsUser 时收到错误 87 (ERROR_INVALID_PARAMETER)。有人可以指出我做错了什么?

该代码被实现为在 LocalSystem 帐户下运行的 Windows 服务。

4

1 回答 1

3
  • WTSQueryUserToken 只能在 LocalSystem 下调用
  • WTSQueryUserToken 返回一个 PrimaryToken。无需复制它。
  • 这个令牌已经有正确的 sessionID 和环境(它是从当前登录的用户派生的),所以不需要创建一个 environmentblock
于 2012-04-10T13:58:25.020 回答