AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

RunAs unter Win7 (ohne UAC)

Ein Thema von Dalai · begonnen am 15. Mär 2012 · letzter Beitrag vom 17. Mär 2012
Antwort Antwort
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.909 Beiträge
 
Delphi 12 Athens
 
#1

AW: RunAs unter Win7 (ohne UAC)

  Alt 16. Mär 2012, 12:30
Und warum wartest du dann über das Handle anstatt schlicht via IPC der ersten Instanz Bescheid zu sagen?
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai
Online

Registriert seit: 9. Apr 2006
1.683 Beiträge
 
Delphi 5 Professional
 
#2

AW: RunAs unter Win7 (ohne UAC)

  Alt 16. Mär 2012, 13:32
Irgendwie reden wir aneinander vorbei. Ich mache es mal anhand von etwas Code - hier von einem Testprogramm - klar:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
    function RunAs(const verb: string): Boolean;
  public
    { Public-Deklarationen }
  end;

const
    SEE_MASK_NOASYNC = $00000100;
    SEE_MASK_WAITFORINPUTIDLE = $02000000;

var
  Form1: TForm1;
  hnd: THandle;

implementation

function TForm1.RunAs(const verb: string): Boolean;
var sei: TShellExecuteInfo;
begin
    ShowMessage(verb);
    FillChar(sei, SizeOf(sei), 0);
    sei.cbSize:= SizeOf(sei);
    sei.Wnd:= 0;
    sei.fMask:= SEE_MASK_NOASYNC OR
                SEE_MASK_WAITFORINPUTIDLE (*OR
                SEE_MASK_FLAG_NO_UI*)
 OR
                SEE_MASK_NOCLOSEPROCESS;
    sei.lpVerb:= PChar(verb);
    sei.lpFile:= PChar(Application.ExeName);
    sei.lpParameters:= PChar('runas');
    sei.nShow:= SW_SHOWNORMAL;
    Result:= ShellExecuteEx(@sei);
    hnd:= sei.hProcess;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    if RunAs('runas') then ShowMessage('OK');
    ShowMessage(IntToStr(hnd));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    if RunAs('runasuser') then ShowMessage('OK');
    ShowMessage(IntToStr(hnd));
end;
Beim Klick auf Button1 bekomme ich die Meldung 'runas', gefolgt vom UAC-Dialog seitens Windows und nach Ende desselben dann die Meldung 'OK' (oder bei Abbruch der UAC eben gar keine) und zum Schluss das ermittelte Handle.

Beim Klick auf Button2 bekomme ich die Meldung 'runasuser', und danach kommen parallel die Dialoge "Ausführen als" (Windows) und 'OK' (von meinem Programm) und zum Schluss wieder das Handle. Es wird hier also noch gar kein Prozess gestartet, mit dem ich in irgendeiner Weise kommunizieren könnte - was davon abgesehen auch gar nicht geht, weil die "echte" Anwendung auf eine Instanz beschränkt ist via Mutex.

Das ermittelte Handle ist übrigens 0, wenn ich bei 'runas' die UAC abbreche und bei 'runasuser' ist es in jedem Fall 0. Ich kann also gar nicht auf ein Handle warten bei 'runasuser', weil die Funktion ShellExecuteEx gar keins zurückgibt.

MfG Dalai
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#3

AW: RunAs unter Win7 (ohne UAC)

  Alt 16. Mär 2012, 13:51
Du könntest über Findwindow ein gegf. vorhandenes Programm ohne UAC, vor der Mutxprüfung suche und per Message einen Befehl zum beenden senden.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.909 Beiträge
 
Delphi 12 Athens
 
#4

AW: RunAs unter Win7 (ohne UAC)

  Alt 16. Mär 2012, 14:10
Beim Klick auf Button2 bekomme ich die Meldung 'runasuser', und danach kommen parallel die Dialoge "Ausführen als" (Windows) und 'OK' (von meinem Programm) und zum Schluss wieder das Handle.
Ok, das hatte ich nicht so verstanden. Ich dachte es ginge um das Warten auf den Prozess oder so.

Dennoch könntest du ein Handle (z.B. ein Fensterhandle) als Parameter mitgeben, über das das gestartete Programm z.B. eine Windows Message schicken kann als Antwort.

Ich schaue mir aber mal an was es sonst noch für Möglichkeiten geben könnte...
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai
Online

Registriert seit: 9. Apr 2006
1.683 Beiträge
 
Delphi 5 Professional
 
#5

AW: RunAs unter Win7 (ohne UAC)

  Alt 16. Mär 2012, 14:57
Dennoch könntest du ein Handle (z.B. ein Fensterhandle) als Parameter mitgeben, über das das gestartete Programm z.B. eine Windows Message schicken kann als Antwort.
Das bringt mir nichts. Das Programm benutzt ein Mutex, um mehrfache Instanzen zu verhindern. Ich muss also die laufende Instanz sofort nach (einem erfolgreichen) ShellExecuteEx schließen, damit die neue Instanz die Chance hat, zu starten. Da die Funktion ShellExecuteEx im Falle von 'runasuser' sofort die Kontrolle an das Programm zurückgibt, beendet sich das Programm und das war's; es wird keine neue Instanz gestartet und die laufende beendet sich.

Nebenbei bemerkt ist ShellExecuteEx bei 'runasuser' immer erfolgreich, auch wenn man im "Ausführen als"-Dialog gar nichts macht (ihn also stehenlässt). Man kann also gar nicht unterscheiden, wie der Nutzer den "Ausführen als"-Dialog verlässt. Ich hoffe, nun ist klar, wo das Problem liegt.

Ich habe mir die Sache mal mit AutoIt angeschaut und dort verhält sich Windows exakt genauso. Es liegt also wohl am Win7 selbst - ob von MS beabsichtigt oder nicht, bleibt offen.

MfG Dalai
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.909 Beiträge
 
Delphi 12 Athens
 
#6

AW: RunAs unter Win7 (ohne UAC)

  Alt 16. Mär 2012, 15:34
Das Programm benutzt ein Mutex, um mehrfache Instanzen zu verhindern. Ich muss also die laufende Instanz sofort nach (einem erfolgreichen) ShellExecuteEx schließen, damit die neue Instanz die Chance hat, zu starten.
Ich mache das in meiner Updaterunit ähnlich, aber die macht die Synchronisation der Starts per IPC.

Ich starte, wenn ich noch keine Adminrechte habe, eine Instanz mit Adminrechten. Diese Instanz benennt die aktuellen Dateien um und kopiert die neuen Dateien ins Verzeichnis. Dann startet sie die ggf. neue Exe, die dann auch Adminrechte hat, sagt der ersten Instanz Bescheid und beendet sich selbst.
Die erste Instanz startet die neue Exe im selben Kontext wie die ursprüngliche Exe (also z.B. ohne Adminrechte) und beendet sich. Die neu gestartete Exe sagt der neuen Admin-Instanz Bescheid und wartet.
Die neue Admin-Instanz löscht nun die zuvor gesicherten Dateien, wenn das Update bis hierhin gekommen ist, meldet den Erfolg des Aufräumens an die neue Instanz im Benutzerkontext und beendet sich.
Die neue Instanz im Benutzerkontext lädt den Zustand der ersten Instanz wieder und sagt dann dem Benutzer Bescheid, dass das Update fertig ist.
Dazu kommt noch die Kommunikation für die Fortschrittsanzeige.

Das funktioniert so sehr gut und ich denke, dass das bei dir auch gehen würde. Deine neue Instanz merkt am Parameter, dass da noch eine alte Instanz beendet werden muss. Dann meldet diese der ersten Instanz, dass sie erfolgreich gestartet ist und wartet bis sich die erste Instanz beendet hat (der Mutex also reserviert werden konnte).
Die erste Instanz wartet nach dem Start bis die Antwort der neuen Instanz kommt und beendet sich dann.

Das sollte doch funktionieren, oder?
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai
Online

Registriert seit: 9. Apr 2006
1.683 Beiträge
 
Delphi 5 Professional
 
#7

AW: RunAs unter Win7 (ohne UAC)

  Alt 16. Mär 2012, 21:06
Deine neue Instanz merkt am Parameter, dass da noch eine alte Instanz beendet werden muss. Dann meldet diese der ersten Instanz, dass sie erfolgreich gestartet ist und wartet bis sich die erste Instanz beendet hat (der Mutex also reserviert werden konnte).
Die erste Instanz wartet nach dem Start bis die Antwort der neuen Instanz kommt und beendet sich dann.

Das sollte doch funktionieren, oder?
Ich werd mir das mal anschauen. Das Nervige an der Sache ist, dass ich mal wieder mehr Aufwand treiben muss, weil MS zu doof/faul/whatever ist, um auf allen Systemen ein konsistentes Verhalten hinzubekommen. Schließlich funktioniert es bei Win2k/XP problemlos, und ShellExecuteEx wartet auch dann, wenn fMask gar nicht gesetzt (und damit 0) ist.

MfG Dalai
  Mit Zitat antworten Zitat
Antwort Antwort


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:09 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