2017-01-20 71 views
-1

我需要從下系統運行(系統進程運行的另一個進程作爲當前用戶),另一個進程在當前用戶下運行的過程。德爾福:運行過程,用戶和系統帳戶環境變量

我可以用這個代碼運行,但與環境變量的問題..例如在新的 '用戶模式' 過程中,我看到APPDATA值是C:\ WINDOWS \ system32 \設置\ systemprofile \應用程序數據\漫遊,而不是C:\ Users \用戶名\ AppData \漫遊

function RunProcessAsCurrentUser(FileName: string): Boolean; 
var 
    ProcessId: Integer; 
    hWindow, hProcess, TokenHandle: THandle; 
    si: Tstartupinfo; 
    p: Tprocessinformation; 
begin 
    Result := False; 
    hWindow := FindWindow('Progman', 'Program Manager'); 
    GetWindowThreadProcessID(hWindow, @ProcessID); 
    hProcess := OpenProcess (PROCESS_ALL_ACCESS, FALSE, ProcessID); 
    if OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, TokenHandle) then 
    begin 

     FillChar(si,SizeOf(si),0); 
     with Si do begin 
     cb := SizeOf(Si); 
     dwFlags := startf_UseShowWindow; 
     wShowWindow := SW_NORMAL; 
     lpDesktop := PChar('winsta0\default'); 
     end; 

     Result := CreateProcessAsUser(TokenHandle, nil, 
     PChar('"'+FileName+'"'), 
     nil, nil, false, Create_default_error_mode, nil, nil, si, p); 
    end; 
end; 

問題是win7,8,10實際

我認爲,所有的過程設置從explorer.exe的複製(和新工藝爲用戶在任務管理器中運行),但看起來像是從系統保持...請幫助以解決

+0

建議:使用Delphi'的ShellExecute()'和Windows'runas':http://www.sevenforums.com/tutorials/419-run-different-user.html – paulsm4

+0

請注意,使用'runas'會調用UAC提升提示,而'CreateProcessAsUser()'不會。 –

回答

2

當使用CreateProcessAsUser()時,您應該使用CreateEnvironmentBlock()檢索用戶環境:

檢索指定用戶的環境變量。然後可以將該塊傳遞給CreateProcessAsUser函數。

將該值傳遞給參數CreateProcessAsUser()。否則,新進程會繼承調用進程的環境。

例如:

function RunProcessAsCurrentUser(FileName: string): Boolean; 
var 
    ProcessId: Integer; 
    hWindow, hProcess, TokenHandle: THandle; 
    si: Tstartupinfo; 
    p: Tprocessinformation; 
    lpEnvironment: Pointer; 
begin 
    Result := False; 

    hWindow := FindWindow('Progman', 'Program Manager'); 
    if hWindow = 0 then Exit; 

    GetWindowThreadProcessID(hWindow, @ProcessID); 
    hProcess := OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessID); 
    if hProcess = 0 then Exit; 

    try 
    if not OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, TokenHandle) then Exit; 

    FillChar(si,SizeOf(si),0); 
    with Si do begin 
     cb := SizeOf(Si); 
     dwFlags := startf_UseShowWindow; 
     wShowWindow := SW_NORMAL; 
     lpDesktop := PChar('winsta0\default'); 
    end; 

    lpEnvironment := nil; 
    CreateEnvironmentBlock(@lpEnvironment, TokenHandle, FALSE); 
    try 
     Result := CreateProcessAsUser(TokenHandle, nil, 
     PChar('"'+FileName+'"'), 
     nil, nil, FALSE, CREATE_DEFAULT_ERROR_MODE, 
     lpEnvironment, nil, si, p); 
    finally 
     DestroyEnvironmentBlock(lpEnvironment); 
    end; 
    finally 
    CloseHandle(hProcess); 
    end; 
end; 
+1

謝謝!順便說一句,我們的測試表明,該CREATE_UNICODE_ENVIRONMENT應該用來代替CREATE_DEFAULT_ERROR_MODE。和CreateEnvironmentBlock(lpEnvironment,TokenHandle,FALSE);而不是CreateEnvironmentBlock(@lpEnvironment,TokenHandle,FALSE); –