Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Problem ShellExecute / CreateProcess + Wait mit Vista UAC (https://www.delphipraxis.net/92114-problem-shellexecute-createprocess-wait-mit-vista-uac.html)

Assertor 14. Mai 2007 19:22


Problem ShellExecute / CreateProcess + Wait mit Vista UAC
 
Hallo DPler,

mal wieder eine Frage die sich um Vista, UAC und die kleinen Details in Delphi bewegt.

Ich möchte ein Programm im aktuellen Rechtekontext einer Anwendung ausführen und auf das Ende der Ausführung warten. zu startende Anwendung benötigt Admin-Rechte (Vista Manifest eingebunden).

Das Problem ist, wenn ich CreateProcess(Ex) verwende, schmeißt mir Vista in meinem Programm eine Exception raus. Fehler 740, also ElevationRequired. Ich habe im MSDN von der unterschiedlichen Behandlung von ShellExecute und CreateProcess gelesen, insbesondere die besondere Behandlung von RequireElevation von ShellExecute.

Gibt es ein "echtes" ShellExecuteAndWait ohne Aufruf des CreateProcess?

Forumsuche zeigt nur Prä-Vista Beispiele, die alle CreateProcess nutzen...

Gruß winkel79

sh17 14. Mai 2007 20:58

Re: Problem ShellExecute / CreateProcess + Wait mit Vista UA
 
Das Sollte helfen:

Delphi-Quellcode:
function ExecAndWait(Filename, Params: Widestring;
                     WindowState: word = SW_SHOWNORMAL): boolean;
 var
  ShExecInfo : SHELLEXECUTEINFOW;
  r : Cardinal;
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shellexecuteex.asp
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/structures/shellexecuteinfo.asp
begin
  Result := false;
  if Filename = '' then exit;
  if not WideFileExists(FileName) then
  begin
    Log (true,P_ERROR,WideFormat(_('Kann die angegebene Datei nicht finden: %s'),[FileName]));
    exit;
  end;

  ShExecInfo.cbSize := sizeof(SHELLEXECUTEINFOW);
  ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  ShExecInfo.lpVerb := 'open';
  ShExecInfo.lpFile := PWideChar(Filename);
  ShExecInfo.lpParameters := PWideChar(Params);
  ShExecInfo.lpDirectory := PWideChar(WideExtractFileDir(Filename));
  ShExecInfo.nShow := WindowState;
  Result := ShellExecuteExW(@ShExecInfo);

  try
    if Result then
    begin
      r := WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
      if r <> WAIT_OBJECT_0 then
        Log(true,P_FATAL,IntToStr(r)+#10+WideFormat(_('Fehler beim Beenden von "%s".'),[Filename]));
    end else
      Log(true,P_FATAL,SysErrorMessage(GetLastError)+#10+WideFormat(_('Fehler beim Starten von "%s".'),[Filename]));
  finally
    CloseHandle(ShExecInfo.hProcess);
  end;
end;

Assertor 14. Mai 2007 21:27

Re: Problem ShellExecute / CreateProcess + Wait mit Vista UA
 
Hallo Sven,

danke für das Codebeispiel. Es funktioniert teilweise richtig.

Teilweise, weil ich nun das Problem habe, daß die UAC unter Vista in der Taskbar kommt. Das Problem habe ich in einem anderen Thread beschrieben und gelöst: Delphi-Praxis Thread

Wie kann ich dem ShellExecuteEx das Fensterhandle bzw. HWND von GetForegroundWindow übergeben um dieses UAC Feature zu umgehen?

Wie verhält es sich mit SHELLEXECUTEINFOW unter Win98? Um abwärtskompatibel zu bleiben vielleicht eine Platform-Weiche?
Bleibt hierbei bis auf SHELLEXECUTEINFOA und ShellExecuteExA alles gleich?

Danke für Eure Hilfe!

Gruß winkel79

Assertor 14. Mai 2007 21:54

Re: Problem ShellExecute / CreateProcess + Wait mit Vista UA
 
So, die Herren ;)

Vielleicht kann jemand (Sven?) noch mal einen kurzen Blick über den Code werfen. Tests unter Win98 (in VM), Vista und XP laufen soweit. Mit und ohne UAC und der richtigen Einblendung (siehe anderer Thread).

Delphi-Quellcode:
function ExecAndWait(Filename, Params: Widestring;
                     WindowState: word = SW_SHOWNORMAL): boolean;
var
  ShExecInfoW: SHELLEXECUTEINFOW;
  ShExecInfoA: SHELLEXECUTEINFOA;
  r : Cardinal;
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shellexecuteex.asp
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/structures/shellexecuteinfo.asp
begin
  Result := false;
  if Filename = '' then exit;
  if not WideFileExists(FileName) then
  begin
    // Log (true,P_ERROR,WideFormat(_('Kann die angegebene Datei nicht finden: %s'),[FileName]));
    exit;
  end;

  if Win32IsUnicode then
  begin
    ShExecInfoW.Wnd := GetForegroundWindow;
    ShExecInfoW.cbSize := sizeof(SHELLEXECUTEINFOW);
    ShExecInfoW.fMask := SEE_MASK_NOCLOSEPROCESS;
    ShExecInfoW.lpVerb := 'open';
    ShExecInfoW.lpFile := PWideChar(Filename);
    ShExecInfoW.lpParameters := PWideChar(Params);
    ShExecInfoW.lpDirectory := PWideChar(WideExtractFileDir(Filename));
    ShExecInfoW.nShow := WindowState;
    Result := ShellExecuteExW(@ShExecInfoW);
  end
  else
  begin
    ShExecInfoA.Wnd := GetForegroundWindow;
    ShExecInfoA.cbSize := sizeof(SHELLEXECUTEINFOA);
    ShExecInfoA.fMask := SEE_MASK_NOCLOSEPROCESS;
    ShExecInfoA.lpVerb := 'open';
    ShExecInfoA.lpFile := PChar(AnsiString(Filename));
    ShExecInfoA.lpParameters := PChar(AnsiString(Params));
    ShExecInfoA.lpDirectory := PChar(AnsiString(WideExtractFileDir(Filename)));
    ShExecInfoA.nShow := WindowState;
    Result := ShellExecuteExA(@ShExecInfoA);
  end;
  try
    if Result then
    begin
      if Win32IsUnicode then
        r := WaitForSingleObject(ShExecInfoW.hProcess, INFINITE)
      else
        r := WaitForSingleObject(ShExecInfoA.hProcess, INFINITE);
    end;
  finally
    if Win32IsUnicode then
      CloseHandle(ShExecInfoW.hProcess)
    else
      CloseHandle(ShExecInfoA.hProcess);
  end;
end;
Die Logaufrufe von Sven hab ich entfernt bzw. auskommentiert. Die Function Win32IsUnicode ist lediglich ein globaler
Delphi-Quellcode:
(Win32Platform = VER_PLATFORM_WIN32_NT)
Danke für Eure Hilfe!

Gruß winkel79

sh17 15. Mai 2007 07:22

Re: Problem ShellExecute / CreateProcess + Wait mit Vista UA
 
Soweit alles ok. Ich hatte Dir auf die schnelle nur die Unicode-Variante geschrieben,da wir alles unter Windows ME sowieso nicht mehr unterstützen.

Assertor 15. Mai 2007 09:15

Re: Problem ShellExecute / CreateProcess + Wait mit Vista UA
 
Zitat:

Zitat von sh17
Soweit alles ok. Ich hatte Dir auf die schnelle nur die Unicode-Variante geschrieben,da wir alles unter Windows ME sowieso nicht mehr unterstützen.

Verständlich, war ja auch nicht weiter wild die Anpassung. Wir haben leider noch ein paar Win98/Me PCs in der Zielgruppe - sogar teilweise noch DOSe :roll:

Danke für Deine Hilfe, Sven! :dp:

P.S.: Sollte man die ShellExecuteInfoW/A nicht besser vor der Nutzung nullen? Ich werd das mal sicherheitshalber noch einbauen:

Edit1: Hab des jetzt einfach mal per
Delphi-Quellcode:
ZeroMemory(@ShExecInfoW, SizeOf(ShExecInfoW));
bzw.
Delphi-Quellcode:
ZeroMemory(@ShExecInfoA, SizeOf(ShExecInfoA));
noch schnell genullt. Sollte passen.

Weazy 16. Feb 2009 19:30

Re: Problem ShellExecute / CreateProcess + Wait mit Vista UA
 
sehr schön, genau was ich gesucht habe! Was muss ich ändern damit nicht gewartet sondern nur ausgeführt wird?

API 16. Feb 2009 19:31

Re: Problem ShellExecute / CreateProcess + Wait mit Vista UA
 
Zitat:

Zitat von Weazy
sehr schön, genau was ich gesucht habe! Was muss ich ändern damit nicht gewartet sondern nur ausgeführt wird?

Was macht wohl WaitForSingleObject?

GPRSNerd 17. Feb 2009 09:15

Re: Problem ShellExecute / CreateProcess + Wait mit Vista UA
 
Um das ganze Delphi 2009 tauglich zu machen, müssen folgende Typecasts von PChar nach PAnsiChar korrigiert werden:

Delphi-Quellcode:
ShExecInfoA.lpFile      := PAnsiChar(AnsiString(Filename));
ShExecInfoA.lpParameters := PAnsiChar(AnsiString(Parameters));
ShExecInfoA.lpDirectory := PAnsiChar(AnsiString(ExtractFileDir(Filename)));
Desweiteren kann man getrost WideExtractFileDir und WideFileExists durch die "regulären", seit D2009 unicode-tauglichen, Varianten ExtractFileDir und FileExists ersetzt werden.

Gruß,
Stefan

himitsu 17. Feb 2009 09:20

Re: Problem ShellExecute / CreateProcess + Wait mit Vista UA
 
man könnte aber auch statt
Delphi-Quellcode:
ShExecInfoW: SHELLEXECUTEINFOW;
// oder
ShExecInfoA: SHELLEXECUTEINFOA;
einfach ein
Delphi-Quellcode:
ShExecInfo: SHELLEXECUTEINFO;
verwenden und bei PChar (ohne diese TypeCasts) bleiben :stupid:

Statt Wide-/AnsiString dann natürlich auch nur String.


ok, hatte das überlesen
Zitat:

Wie verhält es sich mit SHELLEXECUTEINFOW unter Win98? Um abwärtskompatibel zu bleiben vielleicht eine Platform-Weiche?
Bleibt hierbei bis auf SHELLEXECUTEINFOA und ShellExecuteExA alles gleich?


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:49 Uhr.
Seite 1 von 5  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz