user896166
user896166

Reputation:

Delphi, Windows: Best way to find whether web-browser is running?

What is the best way to find whether a web-browser is running?

Using Delphi XE2 and on Windows, I need to find whether the following web-browsers are currently running:

A) Mozilla Firefox B) Apple Safari C) Google Chrome

If found, the process will be terminated because the home page of the web-browser needs to be changed programmatically by modifying the web-browser configuration files (which is either not possible or could result in unpredictable results if done when the web-browser is running).

Does the output from the EnumWindows API function contain sufficient information needed to handle the above task? If yes, then are the window class names for each of the above web-browsers documented anywhere? If no, then which method is most reliable?

TIA.

Upvotes: 1

Views: 1989

Answers (1)

RRUZ
RRUZ

Reputation: 136431

Terminate a process without the user permission is not good practice, instead you must ask to the user if he wants terminate the app (in this case the web browser).

Now back to your question, you can detect if a app(webbroser) is running checking for the process name (firefox.exe, chrome.exe , safari.exe) using the CreateToolhelp32Snapshot method.

uses
  Windows,
  tlhelp32,
  SysUtils;

function IsProcessRunning(const ListProcess: Array of string): boolean;
var
  hSnapshot : THandle;
  lppe : TProcessEntry32;
  I : Integer;
begin
  result:=false;
  hSnapshot     := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if hSnapshot <> INVALID_HANDLE_VALUE then
  try
    lppe.dwSize := SizeOf(lppe);
    if Process32First(hSnapshot, lppe) then
      repeat
        for I := Low(ListProcess) to High(ListProcess) do
        if  SameText(lppe.szExeFile, ListProcess[i])  then
          Exit(True);
      until not Process32Next(hSnapshot, lppe);
  finally
    CloseHandle(hSnapshot);
  end;
end;

and use like so

  IsProcessRunning(['firefox.exe','chrome.exe','safari.exe'])

Now if you want a more reliable way you can search for the class name of the Window (using the FindWindowEx method) and then the PID of the process owner of the handle (using GetWindowThreadProcessId), from here you can use the PID of the process to resolve the name of exe.

{$APPTYPE CONSOLE}

uses
  Windows,
  tlhelp32,
  SysUtils;

function GetProcessName(const th32ProcessID: DWORD): string;
var
  hSnapshot : THandle;
  lppe : TProcessEntry32;
begin
  result:='';
  hSnapshot     := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if hSnapshot <> INVALID_HANDLE_VALUE then
  try
    lppe.dwSize := SizeOf(lppe);
    if Process32First(hSnapshot, lppe) then
      repeat
        if  lppe.th32ProcessID=th32ProcessID  then
          Exit(lppe.szExeFile);
      until not Process32Next(hSnapshot, lppe);
  finally
    CloseHandle(hSnapshot);
  end;
end;

function IsWebBrowserRunning(const ClassName, ExeName :string) : Boolean;
var
  hWindow : THandle;
  dwProcessId: DWORD;
begin
  result:=False;
  hWindow:= FindWindowEx(0, 0, PChar(ClassName), nil);
  if hWindow<>0 then
  begin
    dwProcessId:=0;
    GetWindowThreadProcessId(hWindow, dwProcessId);
    if dwProcessId>0 then
      exit(Sametext(GetProcessName(dwProcessId),ExeName));
  end;
end;


begin
  try
   if IsWebBrowserRunning('MozillaWindowClass','firefox.exe') then
    Writeln('Firefox is Running');

   if IsWebBrowserRunning('{1C03B488-D53B-4a81-97F8-754559640193}','safari.exe') then
    Writeln('Safari is Running');

   if IsWebBrowserRunning('Chrome_WidgetWin_1','chrome.exe') then
    Writeln('Chrome is Running');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.

Upvotes: 7

Related Questions