delphi 查找指定名称但没有任何窗口的运行应用程序

68bkxrlz  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(119)

我有一个应用程序,开始与一个常规的窗口,并包括一个“隐藏”按钮。单击此按钮后,应用程序将继续运行,并在任务管理器中可见,但不再有任何可见窗口。
我尝试了几种方法来在 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;
nnsrf1az

nnsrf1az1#

好吧,我必须承认我最初的问题并不精确。原来,我正在搜索的应用程序是由Process 32 First/Process 32 Next列出的;然而,挑战在于根据它的名字找到它。
以下是我的最终代码,供那些可能面临类似情况的人使用。

procedure KillUnwantedApp;
type
  PEnumInfo = ^TEnumInfo;
  TEnumInfo = record
    PID: DWORD;
    WindowTitle: string;
  end;
var FHandle : THandle;
    Process : TProcessEntry32;
    Next : Boolean;

    function EnumWindowsProc(Wnd: HWND; Info: PEnumInfo): BOOL; stdcall;
    var WindowPID: DWORD;
        Title: array[0..255] of Char;
    begin
      Result := True;

      GetWindowThreadProcessId(Wnd, @WindowPID);
      if WindowPID = Info^.PID then
      begin
        if GetWindowText(Wnd, Title, SizeOf(Title)) > 0 then
        begin
          Info^.WindowTitle := Title;
          Result := False;
        end;
      end;
    end;

    function GetWindowTitleFromPID(PID: DWORD): string;
    var Info: TEnumInfo;
    begin
      Info.PID := PID;
      Info.WindowTitle := '';
      EnumWindows(@EnumWindowsProc, LPARAM(@Info));
      Result := Info.WindowTitle;
    end;

    function TerminateProcessByPID(PID: DWORD; ExitCode: DWORD = 0): Boolean;
    var hProcess: THandle;
    begin
      Result := False;
      hProcess := OpenProcess(PROCESS_TERMINATE, False, PID);
      if hProcess <> 0 then
      begin
        try
          Result := TerminateProcess(hProcess, ExitCode);
        finally
          CloseHandle(hProcess);
        end;
      end;
    end;

begin
  FHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  Process.dwSize := Sizeof(Process);
  Next := Process32First(FHandle, Process);
  while Next do
  begin
    if pos('searched_application_name', GetWindowTitleFromPID(Process.th32ProcessID)) > 0 then
      TerminateProcessByPID(Process.th32ProcessID);

    Next := Process32Next(FHandle,Process);
  end;
  CloseHandle(FHandle);
end;

相关问题