Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi FindWindow per Handle (https://www.delphipraxis.net/176298-findwindow-per-handle.html)

TTF 25. Aug 2013 20:18


FindWindow per Handle
 
Hallo,

ich versuche gerade den Namen eines Prozesses über das Fensterhandle herausfinden.
Ich habe zwar ziemlich lange danach gegoogelt, aber wahrscheinlich mit den falschen Begriffen.

Ich wäre wirklich dankbar, wenn mir jemand sage könnte, wie ich das mache.

Liebe Grüsse

TTF

Zacherl 25. Aug 2013 20:29

AW: FindWindow per Handle
 
Hey, guck dir mal MSDN-Library durchsuchenGetWindowThreadProcessId an :P Damit bekommst du schonmal die ProcessId, mit der du dann alles weitere ermitteln kannst.

TTF 25. Aug 2013 20:54

AW: FindWindow per Handle
 
Vielen Dank für den Tipp, aber ich bin wirklich zu blöd etwas vernünftiges damit anzufangen. Kannst du(oder sonst jemand) es mir bitte genauer erklären?

Zacherl 25. Aug 2013 20:58

AW: FindWindow per Handle
 
Naja, also du hast ja das Fensterhandle. Dann holst du dir zuerst die dazugehörige ProcessId mit:
Delphi-Quellcode:
var
  ThreadId, ProcessId: DWord;
begin
  ThreadId := GetWindowThreadProcessId(WindowHandle, ProcessId);
Danach hast du dann verschiedene Möglichkeiten:
  1. mit MSDN-Library durchsuchenProcess32First / MSDN-Library durchsuchenProcess32Next alle Prozesse enumierieren und die ProcessId vergleichen
  2. MSDN-Library durchsuchenOpenProcess auf die ProcessId anwenden
    1. und anschließend MSDN-Library durchsuchenGetProcessImageFileName oder MSDN-Library durchsuchenQueryFullProcessImageName aufrufen
    2. und anschließend mit MSDN-Library durchsuchenNtQuerySystemInformation den Image Namen direkt aus dem PEB auslesen

TTF 25. Aug 2013 21:35

AW: FindWindow per Handle
 
Ich entschuldige mich aufrichtig für meine Blödheit:stupid: und sage, dass meine Versuche gescheitert sind. dh ich sehe die Funktionen ab GetProcessImageFile nicht mehr.(PSAPI eingebunden)
Deshalb frage ich noch einmal ganz dumm, wie ich das mit GetProcessImageFile und NTQuerySystemInformation mache und bedanke mich, dass du dich trotzdem auf den Level eines Idioten herablässt:lol::P

Zacherl 25. Aug 2013 21:55

AW: FindWindow per Handle
 
Kein Problem, dafür ist das Forum ja da. Folgende Variante sollte ab Windows 2000 funktionieren (auch ohne psapi.dll und mit Unterstützung von 64 bit Prozessen):
Delphi-Quellcode:
{$Z4}
type
  _PROCESSINFOCLASS = (
    ProcessBasicInformation,
    ProcessQuotaLimits,
    ProcessIoCounters,
    ProcessVmCounters,
    ProcessTimes,
    ProcessBasePriority,
    ProcessRaisePriority,
    ProcessDebugPort,
    ProcessExceptionPort,
    ProcessAccessToken,
    ProcessLdtInformation,
    ProcessLdtSize,
    ProcessDefaultHardErrorMode,
    ProcessIoPortHandlers,
    ProcessPooledUsageAndLimits,
    ProcessWorkingSetWatch,
    ProcessUserModeIOPL,
    ProcessEnableAlignmentFaultFixup,
    ProcessPriorityClass,
    ProcessWx86Information,
    ProcessHandleCount,
    ProcessAffinityMask,
    ProcessPriorityBoost,
    ProcessDeviceMap,
    ProcessSessionInformation,
    ProcessForegroundInformation,
    ProcessWow64Information,
    ProcessImageFileName,
    ProcessLUIDDeviceMapsEnabled,
    ProcessBreakOnTermination,
    ProcessDebugObjectHandle,
    ProcessDebugFlags,
    ProcessHandleTracing,
    MaxProcessInfoClass);
  PROCESSINFOCLASS = _PROCESSINFOCLASS;
  PROCESS_INFORMATION_CLASS = PROCESSINFOCLASS;
  TProcessInfoClass = PROCESSINFOCLASS;
{$Z1}

function NtQueryInformationProcess(ProcessHandle: THandle;
  ProcessInformationClass: PROCESSINFOCLASS; ProcessInformation: Pointer;
  ProcessInformationLength: ULONG; ReturnLength: PULONG): LongInt; stdcall; external 'ntdll.dll';

type
  PUNICODE_STRING = ^UNICODE_STRING;
  {$EXTERNALSYM PUNICODE_STRING}
  _UNICODE_STRING = record
    Length: USHORT;
    MaximumLength: USHORT;
    Buffer: PWideChar;
  end;
  {$EXTERNALSYM _UNICODE_STRING}
  UNICODE_STRING = _UNICODE_STRING;
  {$EXTERNALSYM UNICODE_STRING}
  PCUNICODE_STRING = ^UNICODE_STRING;
  {$EXTERNALSYM PCUNICODE_STRING}
  TUnicodeString = UNICODE_STRING;
  PUnicodeString = PUNICODE_STRING;

procedure TForm3.Button1Click(Sender: TObject);
var
  ThreadId,
  ProcessId: DWord;
  hProcess: THandle;
  Data: Pointer;
  Size: ULONG;
begin
  ThreadId := GetWindowThreadProcessId(WindowHandle, ProcessId);
  if (ThreadId <> 0) then
  begin
    hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, ProcessId);
    if (hProcess <> 0) and (hProcess <> INVALID_HANDLE_VALUE) then
    try
      NtQueryInformationProcess(hProcess, ProcessImageFileName, nil, 0, @Size);
      GetMem(Data, Size);
      try
        if (NtQueryInformationProcess(hProcess, ProcessImageFileName, Data, Size, @Size) = 0) then
        begin
          Caption := ExtractFileName(PUNICODE_STRING(Data).Buffer);
        end;
      finally
        FreeMem(Data);
      end;
    finally
      CloseHandle(hProcess);
    end;
  end;
end;
Die Funktion ermittelt allerdings nur den Dateinamen und nicht den kompletten Pfad. Wenn du den ganzen Pfad haben willst, wird es für Systeme < Vista etwas komplizierter.

Alternativ vielleicht noch etwas sauberer über die TlHelp32 API:
Delphi-Quellcode:
procedure TForm3.Button1Click(Sender: TObject);
var
  ThreadId,
  ProcessId: DWord;
  hSnapshot: THandle;
  Process: TProcessEntry32;
begin
  ThreadId := GetWindowThreadProcessId(WindowHandle, ProcessId);
  if (ThreadId <> 0) then
  begin
    hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, ProcessId);
    if (hSnapshot <> 0) and (hSnapshot <> INVALID_HANDLE_VALUE) then
    try
      FillChar(Process, SizeOf(Process), #0);
      Process.dwSize := SizeOf(Process);
      if Process32First(hSnapshot, Process) then
      repeat
        if (Process.th32ProcessID = ProcessId) then
        begin
          Caption := StrPas(PChar(@Process.szExeFile[0]));
          Break;
        end;
      until not Process32Next(hSnapshot, Process);
    finally
      CloseHandle(hSnapshot);
    end;
  end;
end;

TTF 25. Aug 2013 22:22

AW: FindWindow per Handle
 
Danke vielmals für die Hilfe. Es funktioniert prima:). Allerdings würde ich den Code gerne verstehen, deshalb frage ich(letzte Frage:wink:):
Was hat es mit dem Snapshot auf sich?
Also dieser Teil:
Delphi-Quellcode:
...
  hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, ProcessId);
  if (hSnapshot <> 0) and (hSnapshot <> INVALID_HANDLE_VALUE) then
  try
    FillChar(Process, SizeOf(Process), #0);
    Process.dwSize := SizeOf(Process);
...

Zacherl 25. Aug 2013 22:46

AW: FindWindow per Handle
 
Mal ein Auszug aus dem MSDN zur CreateToolhelp32Snapshot API:
Zitat:

Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.
Im Grunde genommen wird beim Aufruf mit TH32CS_SNAPPROCESS eine Liste von allen momentan laufenden Prozessen erstellt. Über Process32First / Process32Next gehst du diese Liste durch und bekommst das aktuelle Element in der ProcessEntry32 Struktur geliefert.

Diese Struktur muss vor der ersten Verwendung initialisiert werden, indem man den zuerst alle Werte mit 0 überschreibt und dann die Größe des Records in dwSize Feld angibt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:15 Uhr.

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