![]() |
Programmstart nach Update
Hallo,
ich bin gerade dabei für unsere Programme eine Update-Komponente zu schreiben. Der Ablauf ist wie folgt: - Updateliste wird von einem Webservice angefordet - falls Updates vorhanden sind, wird ein Updater aus den Resourcen entpackt - der Updater wird gestartet und die Updateliste wird an den Updater übergeben - der Updater arbeitet die Liste ab und startet am Ende die Applikation neu Problem dabei ist, dass der Updater je nach Installationort der Applikation mit Adminrechten gestartet wird, um z.B. Dateien unter C:\Programme\Applikation ersetzen zu können. Da der Updater in solch einem Fall mit Adminrechten läuft, wird aber auch am Ende die Applikation mit Adminrechten gestartet, was ja so nicht sein soll. Daher habe ich versucht die Applikation über CreateProcessAsUser zu starten. Jedoch läuft hier die Ermittlung des Usertoken per WTSQueryUserToken mit der Fehlermeldung ERROR_PRIVILEGE_NOT_HELD fehl. Nach intensiver Suche scheint es daran zu liegen, dass man WTSQueryUserToken nur aus einem Service heraus erfolgreich aufrufen kann. Daher wäre nun meine Frage, wie ich es schaffe die Applikation mit den Rechten des aktuell angemeldeten Users vom Updater, der mit Adminrechten läuft, aus auszuführen. Das ganze ohne die Verwendung von WTSQueryUserToken. Vielen Dank. madas |
AW: Programmstart nach Update
|
AW: Programmstart nach Update
Zitat:
madas |
AW: Programmstart nach Update
Ja, das hatte ich schon verstanden. Wo habe ich etwas von Rechnerneustart geschrieben? :)
|
AW: Programmstart nach Update
Kannst du nicht ein Zwischenprogramm einführen?
Dein Programm lädt Updates usw. herunter > Programm ruft anschließend das Zwischenprogramm auf Das Zwischenprogramm hat zwei Aufgaben: 1. es startet das Updatesetup als Administrator und wartet darauf, dass es beendet wird. 2. Im Falle eines erfolgreichen Updates wird anschließend das eigentliche Programm gestartet. Da das Zwischenprogramm keine erweiterten Rechte hat, brauchst du hier auch keine weiteren Rechte o.ä. anfordern Danach beendet sich das Zwischenprogramm und du siehst das geupdatete Programm wieder. |
AW: Programmstart nach Update
@Morphie: das verlagert das Problem doch nur. Ob der Updater nun, weil er elevated ist, eine elevierte Instanz des Programmes startet, oder eine elevierte Instanz des Zwischenprogrammes, dass dann eine elevierte Instanz des Programmes startet, macht keinen Unterschied ;)
Zitat:
|
AW: Programmstart nach Update
Nö
Code:
Das Zwischenprogramm läuft also in dem gleichen Kontext wie das ursprüngliche Programm. Daher kann es das Programm nach dem Setup auch einfach ganz normal starten.
Programm (normale Userrechte) > Zwischenprogramm (normale Userrechte) > Startet Setup mit erweiterten Rechten (UAC poppt auf)
> Startet das ursprüngliche Programm (normale Userrechte) Erst das Setup bekommt erweiterte Rechte, ruft aber nach dem Setup kein Programm selbst auf. |
AW: Programmstart nach Update
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: ![]() 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:
Grüße.
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; madas PS: Falls es Verbesserungsvorschläge gibt nur raus damit. :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz