Я боролся с этим в течение недели, и после прочтения большого количества информации об этой проблеме, наконец-то получил решение для этого ...
Вы должны использовать функцию CreateProcessAsUser следующим образом:
Private Shared Sub Executer(ByVal content As String)
Dim objProcess As System.Diagnostics.Process
Dim filename As String
filename = "e:\lock.bat"
'create a bat file with ''rundll32.exe user32.dll,LockWorkStation'' inside
Dim UserTokenHandle As IntPtr = IntPtr.Zero
WindowsApi.WTSQueryUserToken(WindowsApi.WTSGetActiveConsoleSessionId, UserTokenHandle)
Dim ProcInfo As New WindowsApi.PROCESS_INFORMATION
Dim StartInfo As New WindowsApi.STARTUPINFOW
StartInfo.cb = CUInt(Marshal.SizeOf(StartInfo))
WindowsApi.CreateProcessAsUser(UserTokenHandle, filename, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, False, 0, IntPtr.Zero, Nothing, StartInfo, ProcInfo)
If Not UserTokenHandle = IntPtr.Zero Then
WindowsApi.CloseHandle(UserTokenHandle)
End If
End Sub
Получил большую часть кода из здесь , где вы также можете найти WindowsApi для использования с этой функцией.
Я все еще пытаюсь найти, если можно избежать файла bat, но по крайней мере это очень приличное решение.
EDIT:
Чтобы не использовать внешний файл * .bat для выполнения кода, просто отредактируйте класс WindowsApi и замените CreateProcessAsUser и импортируемую часть advapi32.dll следующим:
<DllImport("Advapi32.dll", EntryPoint:="CreateProcessAsUser", ExactSpelling:=False, SetLastError:=True, CharSet:=CharSet.Unicode)> _
Public Shared Function CreateProcessAsUser( _
ByVal hToken As IntPtr, _
ByVal lpApplicationName As String, _
<[In](), Out(), [Optional]()> ByVal lpCommandLine As StringBuilder, _
ByVal lpProcessAttributes As IntPtr, _
ByVal lpThreadAttributes As IntPtr, _
<MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandles As Boolean, _
ByVal dwCreationFlags As Integer, _
ByVal lpEnvironment As IntPtr, _
ByVal lpCurrentDirectory As String, _
<[In]()> ByRef lpStartupInfo As STARTUPINFOW, _
<Out()> ByRef lpProcessInformation As PROCESS_INFORMATION) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
И теперь вы можете использовать stringbuilder в качестве аргумента thrid (comandline) для функции CreateProcessAsUser и поместить второй (applicationame) как «Nothing», например:
Dim cmdline As New StringBuilder
cmdline.Append("rundll32.exe user32.dll,LockWorkStation")
WindowsApi.CreateProcessAsUser(UserTokenHandle, Nothing, cmdline, IntPtr.Zero, IntPtr.Zero, False, 0, IntPtr.Zero, Nothing, StartInfo, ProcInfo)
И это будет РАБОТАТЬ !!!!
С уважением,
AP