Registriert seit: 9. Aug 2007
207 Beiträge
|
AW: Programmstart nach Update
18. Mär 2013, 15:33
Die Quelltexte von Innosetup habe ich durch forstet, konnte jedoch nichts sinnvolles finden, was zu meiner Lösung beitragen wollte.
Nach weiterer Recherche im WWW bin ich auf folgenden Artikel gestoßen:
http://blogs.msdn.com/b/aaron_margos...vated-app.aspx
Ich habe dann versucht das Ganze mal nach Delphi zu portieren und es scheint auf den ersten Blick zu funzen. Die Funktion macht nur Sinn bzw. ist nur ausführbar, wenn das Programm in dem sie aufrufen wird mit Admin-Rechten läuft. Hier der Delphi Quelltext:
Delphi-Quellcode:
interface
function RunsAsDesktopUser(appFileName, appParams, currDir: WideString): Boolean;
uses
..., JwaWindows, JwsclToken, JwsclPrivileges, ...;
implementation
function RunsAsDesktopUser(appFileName, appParams, currDir: WideString): Boolean;
const
dwTokenRights: DWORD = TOKEN_QUERY or TOKEN_ASSIGN_PRIMARY or TOKEN_DUPLICATE or TOKEN_ADJUST_DEFAULT or TOKEN_ADJUST_SESSIONID;
var
hProcessToken, hShellProcess, hShellProcessToken, hPrimaryToken: THandle;
hHWND: HWND;
dwPID: DWORD;
tkp: TOKEN_PRIVILEGES;
startupInfo: TSTARTUPINFOW;
processInfo: TPROCESSINFORMATION;
lastError: String;
pAppParams: PWideChar;
begin
Result := False;
hProcessToken := THandle(nil); hShellProcess := THandle(nil); hShellProcessToken := THandle(nil); hPrimaryToken := THandle(nil);
dwPID := 0; lastError := EmptyStr;
ZeroMemory(@startupInfo, sizeof(startupInfo));
startupInfo.cb := sizeof(startupInfo);
startupInfo.lpDesktop := 'winsta0\default';
startupInfo.dwFlags := STARTF_USESHOWWINDOW;
startupInfo.wShowWindow := SW_SHOWDEFAULT;
try
if (OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hProcessToken)) then
begin
try
tkp.PrivilegeCount := 1;
if (LookupPrivilegeValue(nil, SE_INCREASE_QUOTA_NAME, tkp.Privileges[0].Luid)) then
begin
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hProcessToken, false, @tkp, SizeOf(TOKEN_PRIVILEGES), nil, nil);
if (GetLastError <> ERROR_SUCCESS) then
begin
lastError := 'AdjustTokenPrivileges: ' + SysErrorMessage(GetLastError);
Result := False;
Exit;
end;
end;
finally
CloseHandle(hProcessToken);
end;
end else
begin
lastError := 'OpenProcessToken: ' + SysErrorMessage(GetLastError);
Result := false;
Exit;
end;
hHWND := GetShellWindow;
if (hHWND = 0) then
begin
lastError := 'GetShellWindow: ' + SysErrorMessage(GetLastError);
Result := False;
Exit;
end;
GetWindowThreadProcessId(hHWND, @dwPID);
if (hHWND = 0) then
begin
lastError := 'GetWindowThreadProcessId: ' + SysErrorMessage(GetLastError);
Result := False;
Exit;
end;
hShellProcess := OpenProcess(PROCESS_QUERY_INFORMATION, False, dwPID);
if (hHWND = 0) then
begin
lastError := 'OpenProcess: ' + SysErrorMessage(GetLastError);
Result := False;
Exit;
end;
Result := OpenProcessToken(hShellProcess, TOKEN_DUPLICATE, hShellProcessToken);
if (not Result) then
begin
lastError := 'OpenProcessToken: ' + SysErrorMessage(GetLastError);
Exit;
end;
Result := DuplicateTokenEx(hShellProcessToken, dwTokenRights, nil, SecurityImpersonation, TokenPrimary, hPrimaryToken);
if (not Result) then
begin
lastError := 'DuplicateTokenEx: ' + SysErrorMessage(GetLastError);
Exit;
end;
if (appParams = EmptyWideStr) then
pAppParams := nil
else
pAppParams := PWideChar(appFileName + ' ' + appParams);
Result := CreateProcessWithTokenW(hPrimaryToken, 0, PWideChar(appFileName), pAppParams, 0, nil, PWideChar(currDir), @startupInfo, @processInfo);
if (not Result) then
begin
lastError := 'CreateProcessWithTokenW: ' + SysErrorMessage(GetLastError);
Exit;
end;
Result := True;
finally
CloseHandle(hShellProcessToken);
CloseHandle(hPrimaryToken);
CloseHandle(hShellProcess);
if (not Result) then
ShowMessage(lastError);
end;
end;
Grüße.
madas
PS: Falls es Verbesserungsvorschläge gibt nur raus damit.
Geändert von madas (18. Mär 2013 um 15:35 Uhr)
|