![]() |
Externes Programm starten, beenden, in den Vordergrund holen
Hallo liebe User der DP,
ich stehe etwas auf dem Schlauch wegen folgendem Problem: Ich möchte aus meinem Programm heraus eine weitere Anwendung starten, falls Sie noch nicht gestartet wurde. Wurde Sie bereits gestartet, soll die Anwendung in den Vordergrund geholt und nicht nochmals gestartet werden. Wenn ich das "Hauptprogramm" beendete, will ich prüfen ob die weitere Anwendung auch noch läuft und diese dann ggf. auch beenden. Ich habe schon mit ShellExecuteEx usw. rumprobiert und mir die Handles zurückgeben lassen, aber irgendwie mache ich wohl etwas falsch. Ich bekomme zwar einen Cardinal-Wert zurück, aber dieser existiert auch noch, wenn die Anwendung schon beendet wurde und dann startet Sie nicht nochmal... Funktion zur Ausführung der Anwendung:
Delphi-Quellcode:
Aufruf:
function ExecAndWait(Filename, Params: String;
WindowState: Word = SW_SHOWNORMAL; Wait : Boolean = False): Cardinal; var {$IFDEF UNICODE} ShExecInfoW: SHELLEXECUTEINFOW; {$ENDIF} ShExecInfoA: SHELLEXECUTEINFOA; // MSDN: ShellExecuteEx, ShellExecuteInfo begin Result := 0; if (Filename = '') or not FileExists(FileName) then exit; {$IFDEF UNICODE} if Win32IsUnicode then begin ProgramStarting := True; ZeroMemory(@ShExecInfoW, SizeOf(ShExecInfoW)); ShExecInfoW.Wnd := GetForegroundWindow; ShExecInfoW.cbSize := SizeOf(SHELLEXECUTEINFOW); ShExecInfoW.fMask := SEE_MASK_NOCLOSEPROCESS; ShExecInfoW.lpVerb := 'open'; ShExecInfoW.lpFile := PWideChar(WideString(Filename)); ShExecInfoW.lpParameters := PWideChar(WideString(Params)); ShExecInfoW.lpDirectory := PWideChar(WideString(ExtractFileDir(Filename))); ShExecInfoW.nShow := WindowState; try ShellAPI.ShellExecuteExW(@ShExecInfoW); Result := ShExecInfoW.hProcess; if Wait then WaitForSingleObject(ShExecInfoW.hProcess, INFINITE); finally CloseHandle(ShExecInfoW.hProcess); ProgramStarting := False; end; end else {$ENDIF} begin ZeroMemory(@ShExecInfoA, SizeOf(ShExecInfoA)); ShExecInfoA.Wnd := GetForegroundWindow; ShExecInfoA.cbSize := sizeof(SHELLEXECUTEINFOA); ShExecInfoA.fMask := SEE_MASK_NOCLOSEPROCESS; ShExecInfoA.lpVerb := 'open'; ShExecInfoA.lpFile := PAnsiChar(AnsiString(Filename)); ShExecInfoA.lpParameters := PAnsiChar(AnsiString(Params)); ShExecInfoA.lpDirectory := PAnsiChar(AnsiString(ExtractFileDir(Filename))); ShExecInfoA.nShow := WindowState; try ShellExecuteExA(@ShExecInfoA); Result := ShExecInfoA.hProcess; if Wait then WaitForSingleObject(ShExecInfoA.hProcess, INFINITE); finally CloseHandle(ShExecInfoA.hProcess); end; end; end;
Delphi-Quellcode:
Hat jemand einen Tipp für mich?
var
cMod: Cardinal; begin if (IsWindow(cMod)) then begin ShowWindow(cMod, SW_NORMAL); SetForegroundWindow(cMod); end else begin cMod := ExecAndWait(ExtractFilePath(Application.ExeName)+'\mod\newapp.exe', '', SW_SHOWNORMAL, False); end; Gruß NetSonic |
Re: Externes Programm starten, beenden, in den Vordergrund h
Du verwechselst Prozess- und Fensterhandles. Du könntest mit
![]() ![]() |
Re: Externes Programm starten, beenden, in den Vordergrund h
Hm, ok
also liefert mir die Funktion das Fenster-Handle, aber nicht das Prozess-Handle zurück?!? Wie komme ich denn am effektivsten mit dem Fenster-Handle an das Prozess-Handle. Kann ich mir das nicht auch direkt in der Funktion zurückgeben lassen? Oder anhand des ExeNamens den Prozess-Handle ermitteln? |
Re: Externes Programm starten, beenden, in den Vordergrund h
Zitat:
|
Re: Externes Programm starten, beenden, in den Vordergrund h
:wall:
Ich habe also das Prozess-Handle und benötige das Fenster-Handle?! Und das muss ich mir mit EnumWindows holen? Richtig?!? |
Re: Externes Programm starten, beenden, in den Vordergrund h
Jepp, wie oben beschrieben. Es mag evtl. noch andere Wege geben, aber dieser fällt mir immer zuerst ein.
|
Re: Externes Programm starten, beenden, in den Vordergrund h
Guten Morgen,
ich habe mich jetzt mal mit Deinen Vorschlägen auseinander gesetzt und folgendes probiert:
Delphi-Quellcode:
Jetzt will ich prüfen, ob das Fenster vorhanden ist:
Type
TEnumData = Record hW: HWND; pID: DWORD; End; Function EnumProc( hw: HWND; Var data: TEnumData ): Bool; stdcall; Var pID: DWORD; Begin Result := True; If (GetWindowLong(hw, GWL_HWNDPARENT) = 0) and (IsWindowVisible( hw ) or IsIconic(hw)) and ((GetWindowLong(hw, GWL_EXSTYLE) and WS_EX_APPWINDOW) <> 0) Then Begin GetWindowThreadProcessID( hw, @pID ); If pID = data.pID Then Begin data.hW := hW; Result := False; End; { If } End; { If } End; { EnumProc } Function WindowFromProcessID( pID: DWORD ): HWND; Var data: TEnumData; Begin data.pID := pID; data.hW := 0; EnumWindows( @EnumProc, longint(@data) ); Result := data.hW; End;
Delphi-Quellcode:
Allerdings gibt mir die Funktion "WindowFromProcessID" immer 0 zurück. Mach ich da einen Denkfehler?
if (WindowFromProcessID(cMod) <> 0) then
begin ShowWindow(WindowFromProcessID(cMod), SW_NORMAL); SetForegroundWindow(WindowFromProcessID(cMod)); end else begin cMod := ExecAndWait(ExtractFilePath(Application.ExeName)+'\mod\newapp.exe', '', SW_SHOWNORMAL, False); end; |
Re: Externes Programm starten, beenden, in den Vordergrund h
Tja, wenn der Code von Experts-Exchange nicht funktioniert, weiß ich im Moment auch nicht weiter :gruebel:
|
Re: Externes Programm starten, beenden, in den Vordergrund h
Hallo,
wenn es um Processe etc. geht schau Dir mal diese Tools ![]() |
Re: Externes Programm starten, beenden, in den Vordergrund h
Tja, da stellt sich mir jetzt auch die Frage, woran das liegen könnte.
Habe mir den Code jetzt wieder und wieder angesehen, aber ich finde das Problem nicht. Ich habe die beiden Funktionen in eine externe Unit ausgelagert. Aber daran wird es ja wohl nicht liegen?!? +++ edit +++ Ich habe es jetzt mit FindWindow gelöst. Der Klassename der Programms ist nämlich immer eindeutig, entgegen dem Programm-Titel... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:20 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