AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Programmstart nach Update

Ein Thema von madas · begonnen am 15. Mär 2013 · letzter Beitrag vom 18. Mär 2013
Antwort Antwort
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#1

AW: Programmstart nach Update

  Alt 15. Mär 2013, 11:37
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.
  Mit Zitat antworten Zitat
CCRDude

Registriert seit: 9. Jun 2011
678 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Programmstart nach Update

  Alt 15. Mär 2013, 13:14
@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

Da das Zwischenprogramm keine erweiterten Rechte hat,
Wieso nicht? Danach sucht madas ja eben - von einem elevierten Prozess aus einen Prozess zu starten, der es nicht ist.
  Mit Zitat antworten Zitat
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#3

AW: Programmstart nach Update

  Alt 15. Mär 2013, 13:56

Code:
Programm (normale Userrechte) > Zwischenprogramm (normale Userrechte) > Startet Setup mit erweiterten Rechten (UAC poppt auf)
                                                                      > Startet das ursprüngliche Programm (normale Userrechte)
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.
Erst das Setup bekommt erweiterte Rechte, ruft aber nach dem Setup kein Programm selbst auf.
  Mit Zitat antworten Zitat
madas

Registriert seit: 9. Aug 2007
207 Beiträge
 
#4

AW: Programmstart nach Update

  Alt 18. Mär 2013, 14: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 14:35 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:24 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