Thanx to .
Delphi :
function RunAsUser(CommandLine, WorkDirectory: string; Wait: Boolean): Boolean;
const
TOKEN_ADJUST_SESSIONID = $0100;
dwTokenRights = TOKEN_QUERY or TOKEN_ASSIGN_PRIMARY or TOKEN_DUPLICATE or TOKEN_ADJUST_DEFAULT or TOKEN_ADJUST_SESSIONID;
var
WExe, WCmdLine, wCurrDir: WideString;
hProcessToken, dwLastErr, retLength, hwnd, dwPID, hShellProcess, hShellProcessToken, hPrimaryToken: Cardinal;
tkp: TOKEN_PRIVILEGES;
PI: TProcessInformation;
SI: TStartupInfoW;
begin
Result:= False;
hShellProcessToken:= 0;
hPrimaryToken:= 0;
hShellProcess:= 0;
if WorkDirectory = '' then WorkDirectory:= GetCurrentDir;
Wexe:= SeparateText(CommandLine, ' ');
WCmdLine:= CommandLine;
wCurrDir:= WorkDirectory;
if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hProcessToken) then Exit;
tkp.PrivilegeCount:= 1;
LookupPrivilegeValueW(nil, SE_INCREASE_QUOTA_NAME, tkp.Privileges[0].Luid);
tkp.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hProcessToken, FALSE, tkp, 0, nil, retLength);
dwLastErr:= GetLastError();
CloseHandle(hProcessToken);
if (dwLastErr <> ERROR_SUCCESS) then Exit;
hwnd:= GetShellWindow();
if hwnd = 0 then Exit;
GetWindowThreadProcessId(hwnd, dwPID);
if dwPID = 0 then Exit;
hShellProcess:= OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPID);
if hShellProcess = 0 then Exit;
try
if not OpenProcessToken(hShellProcess, TOKEN_DUPLICATE, hShellProcessToken) then Exit;
if not DuplicateTokenEx(hShellProcessToken, dwTokenRights, nil, SecurityImpersonation, TokenPrimary, hPrimaryToken) then Exit;
SI.cb:= SizeOf(SI);
FillChar(SI, SI.cb, 0);
SI.wShowWindow:= SW_SHOWNORMAL;
SI.dwFlags:= STARTF_USESHOWWINDOW;
Result:= CreateProcessWithTokenW(
hPrimaryToken,
0,
PWideChar(WExe),
PWideChar(wCmdLine),
0,
nil,
PWideChar(wCurrDir),
@si,
@pi);
if not Result then Exit;
if Wait then
while MsgWaitForMultipleObjects(1, PI.hProcess, False, INFINITE, QS_ALLINPUT) <> WAIT_OBJECT_0 do
ProcessMessages;
CloseHandle(PI.hProcess);
finally
CloseHandle(hShellProcessToken);
CloseHandle(hPrimaryToken);
CloseHandle(hShellProcess);
end;
end;