Check if apps are running

Could someone provide some example code on how to check if any applications are running, let me explain why. I have put together a routine for installing software and before it starts I want to ensure that no other applications are running.
Fitz22Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

LischkeCommented:
Hi Fitz22,

you can actually enumerate all processes currently running on the system, then get their physical executables and if it is an *.exe file then stop the process. BUT....you will very likely also find system processes and kill them although they are needed to keep the system alive. I think you shouldn't even try to assume a particualar system configuration (other than what one can usually expect). YOu better make your setup routine working while other applications are running.

Ciao, Mike
0
mhervaisCommented:
listening
0
Fitz22Author Commented:
Thanks Lischke but the problem is that the first thing my installer does is install or upgrade the BDE now if any applications are open that require the use of the BDE the bdeinst.dll will not work
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

LischkeCommented:
Ah yes, this is something we can work with. You don't need to close ALL running applications but only those which use the BDE (like Delphi, Paradox etc.).

Mmmh, in this case you could try to find the main windows of those programs. Unfortunately, this wouldn't work with applications you don't know (this could be thousands). Another approach I can think of is to try to rename or delete one of the BDE DLLs . If this fails then usually an application is running which uses the DLL (or has crashed and left the DLL in memory). In this case you can ask the user to close the application or to restart the machine if there's no (user) application running.

Ciao, Mike
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Fitz22Author Commented:
Thanks Lischke I'll give that a try and let you know, the one problem I can see just now is you will need to know where the dll's are installed too but I will look into it and hopefully you have just earned yourself 100 points :).
0
MoonCalfCommented:
Have a look at Jaymol's components...there's a component he was writing and changed it to a unit so it just goes in the 'Uses' bit.  It's called TGetApps

http://SecretDelphi.cjb.net
0
wmckieCommented:
You could walk the process list and for each process list the open modules, if a BDE related module is open then either ask the user to close the application or kill the process.

Below is a unit from a quick project I did to investigate processes it might assist you.

Walter McKie

-----------------------------------------------

unit ListWindows;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, TLHelp32;

type
  TWindowsInfo = class(TForm)
    Refresh: TButton;
    StaticText1: TStaticText;
    StaticText2: TStaticText;
    StaticText3: TStaticText;
    WindowList: TMemo;
    ProcessList: TListBox;
    ModuleList: TListBox;
    Window: TCheckBox;
    Parent: TCheckBox;
    Iconic: TCheckBox;
    Visible: TCheckBox;
    Zoomed: TCheckBox;
    Unicode: TCheckBox;
    Caption: TCheckBox;
    Shape: TCheckBox;
    procedure RefreshClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ProcessListClick(Sender: TObject);
  private
    { Private declarations }
    Processes: word;
    ProcessIDs: TStringList;
    Threads: TStringList;
    procedure GetModules(PID: dword);
    procedure GetProcesses;
  public
    { Public declarations }
  end;

var
  WindowsInfo: TWindowsInfo;

implementation

{$R *.DFM}

function GetWindowInfo(Window: hWnd): string;
var
  WindowText: array[0 .. 255] of char; { Holds the text of the window }
  WindowCaption: string;
  Rect: TRect;
begin
  Result := '';
  GetWindowText(Window, WindowText, 255);
  GetWindowRect(Window, Rect);
 
  if IsWindow(Window) and (WindowsInfo.Window.State = cbUnChecked)
    then Exit;
  if IsWindowVisible(Window) and (WindowsInfo.Visible.State = cbUnChecked)
    then Exit;
  if (GetParent(Window) = 0) and (WindowsInfo.Parent.State = cbUnChecked)
    then Exit;
  if IsZoomed(Window) and (WindowsInfo.Zoomed.State = cbUnChecked)
    then Exit;
  if IsIconic(Window) and (WindowsInfo.Iconic.State = cbUnChecked)
    then Exit;
  if IsWindowUnicode(Window) and (WindowsInfo.Unicode.State = cbUnChecked)
    then Exit;
  if (Length(WindowText) <> 0) and (WindowsInfo.Caption.State = cbUnChecked)
    then Exit;
  if ((Rect.Left = Rect.Right) or (Rect.Top = Rect.Bottom)) and (WindowsInfo.Shape.State = cbChecked)
    then Exit;

  Result := Result + '"' + WindowText + '" ' +
            IntToStr(Rect.Left) + ', ' + IntToStr(Rect.Top) + ', ' +
            IntToStr(Rect.Right) + ', ' + IntToStr(Rect.Bottom);
  GetClassName(Window, WindowText, 255);
  Result := Result + ' {' + WindowText + '}';
end;

function EnumerateChWindows(Window: hWnd; Parent: lParam): boolean; stdcall;
var
  WindowInfo: string;
begin
  Result := true;
  WindowInfo := GetWindowInfo(Window);
  if WindowInfo <> ''
    then WindowsInfo.WindowList.Lines.Add(WindowInfo);
end;

function EnumerateWindows(Window: hWnd; ProcessID: lParam): boolean; stdcall;
var
  PID: dword;
  WindowInfo: string;
begin
  Result := true;
  GetWindowThreadProcessID(Window, @PID);
  if PID = dword(ProcessID)
    then
      begin
        WindowInfo := GetWindowInfo(Window);
        if WindowInfo <> ''
          then WindowsInfo.WindowList.Lines.Add(WindowInfo);
      end;
end;

procedure TWindowsInfo.GetModules(PID: dword);
var
  H: THandle;
  ModuleEntry: TModuleEntry32;
begin
  H := CreateToolHelp32Snapshot(TH32CS_SNAPMODULE, PID);
  if H = THandle(-1) then Exit;
  FillChar(ModuleEntry, SizeOf(ModuleEntry), 0);
  with ModuleEntry do
    begin
      dwSize := SizeOf(ModuleEntry);
      if Module32First(H, ModuleEntry)
        then
          repeat
             ModuleList.Items.Add(szModule);
          until not Module32Next(H, ModuleEntry);
    end;
  CloseHandle(H);
end;

procedure TWindowsInfo.RefreshClick(Sender: TObject);
begin
  GetProcesses;
end;

procedure TWindowsInfo.GetProcesses;
var
  H: THandle;
  ProcessEntry: TProcessEntry32;
begin
  ProcessList.Items.Clear;
  ProcessIDs.Clear;
  ModuleList.Items.Clear;
  WindowList.Lines.Clear;
  Processes := 0;
  H := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if H = THandle(-1) then Exit;
  FillChar(ProcessEntry, SizeOf(ProcessEntry), 0);
  with ProcessEntry do
    begin
      dwSize := SizeOf(ProcessEntry);
      if Process32First(H, ProcessEntry)
        then
          repeat
            ProcessIDs.Add(IntToStr(th32ProcessID));
            Threads.Add(IntToStr(cntThreads));
            ProcessList.Items.Add(ExtractFileName(szExeFile) +
                                  ' (' + IntToStr(cntThreads) + ')');
            inc(Processes);
          until not Process32Next(H, ProcessEntry);
    end;
  CloseHandle(H);
end;

procedure TWindowsInfo.FormCreate(Sender: TObject);
begin
  ProcessIDs := TStringList.Create;
  Threads := TStringList.Create;
  GetProcesses;
end;

procedure TWindowsInfo.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  ProcessIDs.Free;
  Threads.Free;
end;

procedure TWindowsInfo.ProcessListClick(Sender: TObject);
var
  ProcessID: longword;
begin
  ModuleList.Items.Clear;
  WindowList.Lines.Clear;
  if ProcessList.ItemIndex > 1
    then ProcessID := StrToInt64(ProcessIDs[ProcessList.ItemIndex]);
  GetModules(ProcessID);
  EnumWindows(@EnumerateWindows, ProcessID);
end;

end.
0
LischkeCommented:
..need to mention this works only on Win9x machines

Ciao, Mike
0
wmckieCommented:
That's true, it should also work on Win2000 when its available.

MS articles Q187913 Q175030 and Q192986 go into more detail and describe the NT equivalents.

Walter
0
Fitz22Author Commented:
Thanks Lischke I'll give that a try and let you know, the one problem I can see just now is you will need to know where the dll's are installed too but I will look into it and hopefully you have just earned yourself 100 points :).
0
Fitz22Author Commented:
Thanks a bunch
0
LischkeCommented:
Yep, thank you too.

Ciao, Mike
0
VlooCommented:
Wmckie, I tryed your program but the only thing that happend was that all processes were found. when i check iconic, and all checkboxes and then i press refresh nothing happens... I did this on Xp and also 98... nothing??? what's tha problem???
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.