我有一个应用程序,开始与一个常规的窗口,并包括一个“隐藏”按钮。单击此按钮后,应用程序将继续运行,并在任务管理器中可见,但不再有任何可见窗口。
我尝试了几种方法来在 Delphi 中以编程方式查找此应用程序:
1.使用GetWindowText
:这不起作用,因为应用程序在隐藏时没有窗口。
- 使用
TProcessEntry32.szExeFile
:这是不可靠的,因为: - 用户可以用任何名称保存可执行文件
- 即使可执行文件具有已知名称,它也不会出现在
TProcessEntry32
列表中 - 使用SQL查询:这也无法通过在任务管理器中可见的名称找到应用程序。
我的问题是:我如何在 Delphi 中创建一个函数来检测这个应用程序是否正在运行,给出了以下约束?
1.可执行文件名未知。
1.应用程序没有可见窗口。
1.它隐藏在系统中,但在任务管理器中可见。
=编辑=
我正在努力的应用程序是为不诚实地操纵用户活动跟踪而设计的。如前所述,它最初显示为窗口,但稍后可以隐藏。即使被隐藏,它也会继续模拟用户活动。如前所述,用户可以更改其名称并启动它,因此在这种情况下唯一的常量是任务管理器中可见的名称。很不幸,它藏起来的时候我找不到它。下面是我目前使用的代码:如果有什么差错请告诉我。
此代码在应用程序可见时工作(隐藏时不工作)
var WinTitle : array[0..256] of Char;
begin
if GetWindowText(Wnd, WinTitle, SizeOf(WinTitle)) > 0 then
begin
if pos('GDollar', WinTitle) > 0 then
PostMessage(Wnd, WM_CLOSE, 0, 0);
end;
Result := True;
end;
procedure TForm1.btn_1Click(Sender: TObject);
begin
EnumWindows(@EnumWindowsProc, 0);
end;
我试过这个-但没有运气(它-显然-痛苦地缓慢)。
procedure TForm1.btn_2Click(Sender: TObject);
var PHandle, FHandle: THandle;
Process:TProcessEntry32;
Done, Next: Boolean;
WinTitle : array[0..256] of Char;
pn : String;
begin
FHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
Process.dwSize := Sizeof(Process);
Next := Process32First(FHandle, Process);
while Next do
begin
pn := GetProcessNameByPID(GetHWndByPID(process.th32ProcessID));
if pos('GDollar', pn) > 0 then
ShowMessage(pn);
Next := Process32Next(FHandle,Process);
end;
CloseHandle(FHandle);
end;
function TForm1.GetHWndByPID(const hPID: THandle): THandle;
type
PEnumInfo = ^TEnumInfo;
TEnumInfo = record
ProcessID: DWORD;
HWND: THandle;
end;
function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
var PID: DWORD;
begin
GetWindowThreadProcessID(Wnd, @PID);
Result := (PID <> EI.ProcessID) or (not IsWindowVisible(WND)) or (not IsWindowEnabled(WND));
if not Result then EI.HWND := WND;
end;
function FindMainWindow(PID: DWORD): DWORD;
var EI: TEnumInfo;
begin
EI.ProcessID := PID;
EI.HWND := 0;
EnumWindows(@EnumWindowsProc, Integer(@EI));
Result := EI.HWND;
end;
begin
if hPID <> 0
then Result:=FindMainWindow(hPID)
else Result:=0;
end;
function TForm1.GetProcessNameByPID(const PID: DWORD): string;
var
objSWbemLocator, objWMIService: OLEVariant;
colItems: OLEVariant;
colItem: OLEVariant;
oEnum: IEnumvariant;
iValue: LongWord;
begin
Result := ''; // Initialize result to empty string
objSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
objWMIService := objSWbemLocator.ConnectServer('localhost','root\cimv2', '','');
colItems := objWMIService.ExecQuery(Format('SELECT * FROM Win32_Process WHERE ProcessId=%d', [PID]), 'WQL', 0);
oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
if oEnum.Next(1, colItem, iValue) = 0 then
begin
Result := colItem.Name;
colItem := Unassigned;
end;
end;
1条答案
按热度按时间nnsrf1az1#
好吧,我必须承认我最初的问题并不精确。原来,我正在搜索的应用程序是由Process 32 First/Process 32 Next列出的;然而,挑战在于根据它的名字找到它。
以下是我的最终代码,供那些可能面临类似情况的人使用。