Guten Tag
ich habe seit einiger Zeit das Problem, das ich für ein Programm mit einem dynamischem Fenstertitel die Pid brauchen (um read- und write Prozessmemory zu verwenden).
Ich hab folgende 2 Methoden, die auch ganz gut funktionieren aber bei beiden gibts gewaltige Nachteile, die zwingend raus müssen:
1. Methode: Erkennung über den Exe-Namen (GetId):
Delphi-Quellcode:
function GetID(Const ExeFileName: string; var ProcessId: integer): boolean;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
result := false;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while integer(ContinueLoop) <> 0 do begin
if (StrIComp(PChar(ExtractFileName(FProcessEntry32.szExeFile)), PChar(ExeFileName)) = 0)
or (StrIComp(FProcessEntry32.szExeFile, PChar(ExeFileName)) = 0) then begin
ProcessId:= FProcessEntry32.th32ProcessID;
result := true;
break;
end;
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;
2. Methode: Teil des Windows Fensters, der statisch ist verwenden:
Delphi-Quellcode:
type
PFindWindowStruct = ^TFindWindowStruct;
TFindWindowStruct = record
Caption: string;
ClassName: String;
WindowHandle: THandle;
end;
function EnumWindowsProc(hWindow: hWnd; lParam: LongInt): boolean; stdcall;
var lpBuffer: PChar;
WindowCaptionFound: boolean;
ClassNameFound: boolean;
begin
GetMem(lpBuffer, 255);
result:=true;
WindowCaptionFound:=false;
ClassNameFound:=false;
try
if GetWindowText(hWindow, lpBuffer,255)>0 then
if Pos(PFindWindowStruct(lParam).Caption, StrPas(lpBuffer))>0
then WindowCaptionFound:=true;
if PFindWindowStruct(lParam).ClassName='' then
ClassNameFound:=true
else if GetClassName(hWindow, lpBuffer, 255)>0 then
if Pos(PFindWindowStruct(lParam).ClassName, StrPas(lpBuffer))>0
then ClassNameFound:=true;
if (WindowCaptionFound and ClassNameFound) then begin
PFindWindowStruct(lParam).WindowHandle:=hWindow;
result:=false;
end;
finally
FreeMem(lpBuffer, sizeof(lpBuffer^));
end;
end;
function FindAWindow(WinCaption: string; WinClassName: string): THandle;
var WindowInfo: TFindWindowStruct;
begin
with WindowInfo do begin
caption := WinCaption;
className := WinClassName;
WindowHandle := 0;
EnumWindows(@EnumWindowsProc, LongInt(@WindowInfo));
result := WindowHandle;
end;
end;
Nachteile der 1. Methode: - Fast jeder Nutzer hat einen anderen Exe-Namen, der ja statisch ist
- Diese Methode nutzt im Leerlauf eine gewaltige CPU last (TTimer) und das kann ich auf langsameren
PCs gar nicht gebrauchen
- Somit kommt diese Methode eigentlich nicht mehr in Frage
Nachteile der 2. Methode: - Eigentlich gibt es keinen Nachteil , diese Methode ist sehr ressourcenschonend und bedarf keiner
Vorab definierten .exe, aber eine gewaltiges Problem hat diese Methode, hab die Methode auf mehreren
PCs getested, auf eigentlich allen XP Computern funktioniert sie, aber bei Vista erkennt das Tool
des öfteren das auszulesende Programm obwohl es nicht gestarted ist, wenn man das Programm dann
startet ändert sich dies nicht und das eigentliche Programm, was erkannt werden soll wird nicht
erkannt, ich habe jedoch
herausgefunden (durch systematisches Schließen aller Windows Prozesse), das wenn man den Prozess
explorer.exe schließt und neustarted das Tool wieder alles sauber erkennt
So ist meine Frage, woran kann das liegen (Fehler bei Methode 2) und kann man das Fixen, oder gibt es eventuell sogar eine andere Methode um auf die PID zu kommen?
Danke für eure Hilfe
MfG
Sfaizst