Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Process starten und handle bekommen (https://www.delphipraxis.net/33494-process-starten-und-handle-bekommen.html)

perle 8. Nov 2004 10:29


Process starten und handle bekommen
 
Hi zusammen..


ich möchte gerne aus meinem Programm heraus ein Programm unsichtbar starten (SW_HIDE) aber gleichzeitig dessen Handle speichern.

Normalerweise liste ich mit enumwindows alle fenster auf und suche mir das richtige raus, oder benutze FindWindow, scheinbar können unsichtbare Fenster so nicht gefunden werden !?

Bei recherchen bin ich dann auf CreateProcess gestoßen (in dem Zusammenhang, ein Programm zu starten und auf dessen beendigung zu warten, wofür man ja das handle benötigt).

Wenn ich mir dann die Procedur WaitForSingleObject angucke, fällt mir auf , dass dort als erster Parameter scheinbar das besagte Handle übergeben wird, welches in proc.hprocess (proc : TProcessInformation) steht.

wenn ich mir diesen Wert aber in einer Variable (hproc : Cardinal) speichere und dann versuche mit
ShowWindow(hproc,SW_HIDE); das Fenster verschwinden zu lassen tut sich nichts.

Was mache ich also falsch?


hier auch mal der Code, den ich zum testen verwendet hab:

Code:
function ExecAndWait(const Filename, Params: string;
                     WindowState: word): boolean;
var
  SUInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CmdLine: string;
begin
  CmdLine := '"' + Filename + '" ' + Params;
  FillChar(SUInfo, SizeOf(SUInfo), #0);
  with SUInfo do begin
    cb := SizeOf(SUInfo);
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := WindowState;
  end;
  Result := CreateProcess(NIL, PChar(CmdLine), NIL, NIL, FALSE,
                          CREATE_NEW_CONSOLE or
                          NORMAL_PRIORITY_CLASS, NIL,
                          PChar(ExtractFilePath(Filename)),
                          SUInfo, ProcInfo);
  { Wait for it to finish. }
  if Result then begin
    hProc := ProcInfo.hProcess;
    ShowWindow(hproc, SW_HIDE);                   // ich weiss, dass ich den prozess auch gleich mit diesem Windowstate
                                                   // öffnen kann, es war nur zu testzwecken , wie schon gesagt.
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    ExecAndWait(OpenDialog1.FileName,'',SW_SHOW);
end;

ps: nein das wird kein Trojaner, keylogger oder sonstiges in der Art.

alcaeus 8. Nov 2004 11:11

Re: Process starten und handle bekommen
 
Hi perle,

Zitat:

Zitat von perle
Wenn ich mir dann die Procedur WaitForSingleObject angucke, fällt mir auf , dass dort als erster Parameter scheinbar das besagte Handle übergeben wird, welches in proc.hprocess (proc : TProcessInformation) steht.
wenn ich mir diesen Wert aber in einer Variable (hproc : Cardinal) speichere und dann versuche mit
ShowWindow(hproc,SW_HIDE); das Fenster verschwinden zu lassen tut sich nichts.
Was mache ich also falsch?

ein kleines Detail hast du vergessen: du willst nicht den Prozess unsichtbar machen, sondern das Fenster das zum Prozess gehört. Du musst dir also das Handle des Fensters raussuchen, und nicht jenes des Prozesses.
AFAIK kannst du aber mit [dp]"ShellExecute"[/dp] Programme auch mit dem Parameter SW_HIDE starten.

Greetz
alcaeus

Jens Schumann 8. Nov 2004 11:21

Re: Process starten und handle bekommen
 
Hallo,
wenn Du tatsächlich das Fensterhandle benötigst, dann such hier mal nach Hier im Forum suchenWaitForInputIdle

perle 8. Nov 2004 11:22

Re: Process starten und handle bekommen
 
Zitat:

AFAIK kannst du aber mit Suche in der Delphi-PRAXiSShellExecute Programme auch mit dem Parameter SW_HIDE starten.
so habe ich das auch zunächst gemacht, jedoch habe ich das Fenster dann logischerweise weder mit enumwindows noch mit FindWindow gefunden (da es ja nichtmehr angezeigt wird).


wie kann ich denn über an das Handle des Fensters gelangen (auch wenns SW_HIDE ist) ?


LG Yvonne


@Jens Schuhmann : Ich habe mir ein von dir gepostetes Beispiel mal angeschaut, du ermittelst dort innerhalb der WaitForInputIdle - Schleife mit Findwindow das hanlde des Fensters, dies ist aber bei mir nicht möglich, da sich die Caption des Fensters beliebig ändert (zumindest der vordere Teil , also caption = 'hier der variable Teil - konstanter Programmname').
Mit EnumWindows finde ich , wie schon gesagt, das Fenster nicht, wenn ich es vorher schon mit sw_hide gestartet habe.

Sprint 8. Nov 2004 12:36

Re: Process starten und handle bekommen
 
Zitat:

Zitat von perle
wie kann ich denn über an das Handle des Fensters gelangen (auch wenns SW_HIDE ist)?

Ich hab das jetzt mal mit NODEPAD.EXE und EnumWindows ausprobiert. Scheint so, als wenn das bei mir funktionieren würde.
Delphi-Quellcode:
function RunProcess(const FileName: String): HWND;

  function EnumWindowsProc(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
  begin
    TList(lParam).Add(Pointer(hWnd));
    Result := True;
  end;

var
  SI: TStartupInfo;
  PI: TProcessInformation;
  List: TList;
  ProcessId: DWORD;
  I: Integer;
begin

  Result := 0;
  List := TList.Create;
  try
    FillChar(SI, SizeOf(TStartupInfo), 0);
    SI.cb := SizeOf(TStartupInfo);
    // SI.dwFlags := STARTF_USESHOWWINDOW;
    // SI.wShowWindow := SW_HIDE;
    if CreateProcess(nil, PChar(FileName), nil, nil, False, 0, nil, nil, SI, PI) then
    begin
      WaitForInputIdle(PI.hProcess, INFINITE);
      if EnumWindows(@EnumWindowsProc, Longint(List)) then
      begin
        for I := 0 to List.Count - 1 do
        begin
          GetWindowThreadProcessId(Longint(List.Items[I]), ProcessId);
          if PI.dwProcessId = ProcessId then
          begin
            Result := Longint(List.Items[I]);
            Break;
          end;
        end;
      end;
      CloseHandle(PI.hProcess);
      CloseHandle(PI.hThread);
    end;
  finally
    List.Free;
  end;

end;

Edit: Funktioniert bei mir einwandfrei.

perle 8. Nov 2004 14:03

Re: Process starten und handle bekommen
 
ja super , jetzt funktioniert es bei mir auch, vielen lieben Dank dafür.

Helmi 24. Feb 2012 20:47

AW: Process starten und handle bekommen
 
Hallo,

ich muss diesen alten verstaubten Thread auspacken *hust*

Ich möchte den Code im vorletzten Post unter XE2 nutzen.
Nur leider bekomme ich beim Aufruf von "CreateProcess" eine Access Violation um die Ohren geschmissen.
Ich habe geprüft ob die Datei vorhanden ist.

An was könnte das liegen?

himitsu 24. Feb 2012 20:57

AW: Process starten und handle bekommen
 
64 Bit?

Wenn ja, dann werden wohl die Handle/Pointer-Casts mit LongInt nicht mehr ganz funktionieren. :roll:



Lagere eventuell auch mal das EnumWindowsProc probehalber als eigenständige Prozedur aus.


Beim CreateProcess selber kann ich aber keinen Fehler erkennen. :gruebel:

Helmi 24. Feb 2012 21:03

AW: Process starten und handle bekommen
 
nein - 32 Bit

Ich hab mir jetzt mal die Variablen anschaut, die übergeben werden müssen, und da viel mir auf, dass der Dateiname als erstes übergeben werden muss

Also so:

Delphi-Quellcode:
if CreateProcess(PChar(FileName), nil, nil, nil, False, 0, nil, nil, SI, PI) then
Und dann gehts...



[edit]

... doch nicht!

Leider funktioniert dann der Vergleich der ProcessId nicht mehr

Delphi-Quellcode:
         if PI.dwProcessId = ProcessId then
           begin
             Result := Longint(List.Items[I]);
             Break;
           end;
[Edit2]

Das erste Edit war falsch! - es funktioniert doch - nur darf der Process nicht schon laufen

himitsu 24. Feb 2012 22:09

AW: Process starten und handle bekommen
 
Muß nicht der erste Parameter sein.

Ist das erste NIL, dann wird das Zweite als CommandLine verwendet (so wie man es im Start-Menü > Ausführen oder in der Konsole eingeben kann).

Aber, ich vermute mal (hab nachgelesen :angle2: )

Zitat:

Zitat von der zweite Paramweter
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.



Alle Zeitangaben in WEZ +1. Es ist jetzt 21:37 Uhr.
Seite 1 von 2  1 2      

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