hWnd eines mit RunProgram() gestarteten Explorers ermitteln

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

hWnd eines mit RunProgram() gestarteten Explorers ermitteln

Beitrag von Kiffi »

Shalom,

mit nachfolgendem Code starte ich Notepad.exe und ermittel dessen
Fensterhandle. Klappt auch soweit ganz gut.

Wenn ich allerdings anstelle von Notepad den Explorer starten will
(RunProgram("explorer.exe", ...)), dann bekomme ich kein Fensterhandle.
Das liegt anscheinend daran, dass beim Starten des Explorers keine
gültige Prozess-ID zurückgeliefert wird, sondern lediglich ein neues
Fenster geöffnet wird. (wer den ProcessExplorer von Sysinternals
verwendet, kann das ganz gut beobachten).

Meine Frage: Wie bekomme ich das Fensterhandle eines von mir
gestarteten Explorers heraus? FindWindow_(Fenstername...) möchte ich
nicht verwenden.

Code: Alles auswählen

EnableExplicit

Define Prog_ID.l
Define Prog_PID.l
Define Prog_hWnd.l

Procedure.l ProcID2hWnd(ProcID.l)
  
  Protected hwnd.l
  Protected ProcTaskID.l
  
  hwnd = FindWindow_(#Null, #Null)
  
  While hwnd <> 0
    
    GetWindowThreadProcessId_(hwnd, @ProcTaskID)
    
    If ProcTaskID = ProcID
      ProcedureReturn hwnd
    EndIf
    
    hwnd = GetWindow_(hwnd, #GW_HWNDNEXT)
    
  Wend
  
EndProcedure

Prog_ID = RunProgram("notepad.exe", "", "", #PB_Program_Open)

If Prog_ID 
  
  Prog_PID = ProgramID(Prog_ID)
  
  Debug "Prog_ID: "  + Str(Prog_ID)
  Debug "Prog_PID: " + Str(Prog_PID)
  
  Repeat
    Prog_hWnd = ProcID2hWnd(Prog_PID)
    If Prog_hWnd : Break : EndIf
  ForEver
  
  Debug "Prog_hWnd: " + Str(Prog_hWnd)

EndIf
Danke im voraus & Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Bin grade im PSDK am schmökern tun. Was gibt RunProgram() mit #PB_Program_Open nochmal zurück? ThreadID oder ProcessID? Oder gar was anderes?
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

Fluid Byte hat geschrieben:ThreadID oder ProcessID? Oder gar was anderes?
ich vermute, dass das die ThreadID ist. Mit ProgramID(ThreadID) bekomme
ich dann AFAIK die ProzessID zurück (zumindest beim Start von
Notepad.exe). (alles Vermutungen ohne Gewähr auf Richtigkeit)

Bei der Explorer.exe bekomme ich jedoch eine "ProzessID", die im mit dem
ProcessExplorer nicht lokalisieren kann.



Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

ist das nicht auch abhängig von der windows-einstellung..
"[?] ordnerfenster in einem eigenen prozess starten" ?
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Ich glaube, wenn du "Explorer.exe" startest, sendet dieser neue Prozess eine
Nachricht an den bestehenden "Explorer.exe"-Prozess und beendet sich
gleich wieder. Der alte "Explorer.exe"-Prozess öffnet daraufhin ein neues
Fenster.

Ich schätze, wenn du in den Explorer-Optionen einstellst, dass jedes
Ordnerfenster in einem neuen Prozess geöffnet wird, funktioniert auch dein
bisheriger Code.

Aber da du das so sicherlich nicht machen willst, müsstest du herausfinden,
wie sich die Prozesse austauschen und das irgendwie abfangen, falss das
geht.
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

#NULL hat geschrieben:ist das nicht auch abhängig von der windows-einstellung..
"[?] ordnerfenster in einem eigenen prozess starten" ?
Danke für den Tipp! Hört sich erstmal gut an. Habe ich auch ausprobiert.
Funktioniert aber leider nicht (Erklärung siehe unten)
NicTheQuick hat geschrieben:Ich glaube, wenn du "Explorer.exe" startest, sendet dieser neue Prozess eine
Nachricht an den bestehenden "Explorer.exe"-Prozess und beendet sich
gleich wieder. Der alte "Explorer.exe"-Prozess öffnet daraufhin ein neues
Fenster.
das scheint es wohl zu sein. Danke für die Erläuterung! Im INet habe ich
mittlerweile eine ähnliche Erklärung gefunden:
Andreas Born hat geschrieben:Der Explorer ist integraler Bestandteil der Windows-Shell und läuft
(sofern nicht in der Registry anders festgelegt) grundsätzlich und
immer in einem einzigen Prozess. Startest Du nun einen Explorer-Prozess
durch welche Methode auch immer, wird der Aufruf an den (immer)
existierenden Shell-prozess weitergeleitet und die Windows in dem
Shell-prozess angezeigt. Der initial aufgerufene Prozess (dessen PID Du
mittels Shell-Befehl erhälst) wird sofort terminiert. Daher nützt Dir
diese PID garnichts, da "DEIN" Explorer-Window unter Der Shell-PID läuft
(wie alle anderen leider auch).
Das würde auch erklären, dass ich zwar eine Prozess-ID bekomme, diese
aber nicht auffindbar ist, wenn ich im ProcessExplorer nachschaue, weil
dieser Prozess sich ja sofort wieder beendet hat.

Der Lösungsvorschlag von Andreas Born:
Andreas Born hat geschrieben:[...] Eine 100% wasserdichte Lösung fällt mir leider nicht ein.

Bevor Du Deine Explorer-Fenster startest, frägst Du ab, welche
Explorer-fenster bereits existieren und speicherst deren hwnd's in einem
Array. (EnumWindows(), bei jedem Fenster mittels GetClassName() die
Fensterklasse auf "ExploreWClass" überprüfen.)

Nach dem Starten Deines Exp-Fensters tätigst Du dieselbe Abfrage erneut,
und findest so ein zusätzliches Fenster, welches Deines sein sollte. Hat
auch der Benutzer solche Fenster gestartet, dann erhälst Du mehrere
zusätzliche Fenster, sodaß Du die WindowText-Eigenschaft abfragen musst
(GetWindowText), die dann den Pfad des derzeit angezeigten
Verzeichnisses (relativ, oder absolut) zurückliefert. Damit kannst Du
zumindest auf ein Explorer-Fenster zugreifen, welches das gewünschte
Verzeichnis anzeigt.
Das wäre ja schon mal eine Möglichkeit (wenn auch, wie Andreas feststellt,
keine 100%ig sichere).

Grüße ... Kiffi
a²+b²=mc²
Antworten