Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to detect if a program is running? (Local or remote)

Status
Not open for further replies.

TheBugSlayer

Programmer
Sep 22, 2002
887
US
Hello.

I need to determine if an application is already running before I can execute it. Remotely is my interest but if I have a local solution I can take it from there.

I had actually written a VB function to do just that some time. I am just not sure how to use the same APIs in Delphi. I am investigating, in the meantime if anyone can help me I'd appreciate it very much.

Below is a snippet of my VB app:
Code:
Function IsWordRunning() As Boolean
    Dim CurrWnd As Long
    Dim Length As Long
    Dim TaskName As String
    Dim Parent As Long

    IsWordRunning = False
    CurrWnd = GetWindow(frmMain.hwnd, GW_HWNDFIRST)
    While CurrWnd <> 0 'While it's not my app's window
        Parent = GetParent(CurrWnd)
        Length = GetWindowTextLength(CurrWnd)
        TaskName = Space$(Length + 1)
        Length = GetWindowText(CurrWnd, TaskName, Length + 1)
        TaskName = Left$(TaskName, Len(TaskName) - 1)
        If Length > 0 Then
            If InStr(TaskName, "Microsoft Word") > 0 Then
                IsWordRunning = True
                Exit Function
            End If
        End If
        CurrWnd = GetWindow(CurrWnd, GW_HWNDNEXT)
        DoEvents
    Wend
End Function

Thanks for your help.
 
You can use the same algoritm in Delphi, rewriting it in Pascal, of course :).

Anyway, looping with GetWindow is unreliable, it will be better you using FindWindow family or EnumWindows family.

This type of code (GetWindow, FindWindow, EnumWindows and the like) will not work remotelly or across Win2K internal desktops/winstations.

HTH.
buho (A).
 
:)
Buho,
I had actually rewritten the code in Delphi, it compiles and runs fine but GetWindowText is always empty so I never get any task name...

I am investigating with the use of the other functions. Examples are welcome.

Thanks.
 
I believe we have some examples laying around in this forum or in then "WinApi" one. And the 'net is plenty of code using them.

On GetWindowsText not working: are you sure you are using the Pascal PChars/AnsiStrings properly? Try to solve it before rewriting, you'll have a better understanding of what you are doing.

buho (A).
 
Buho, I believe the program lies with the " Pascal PChars/AnsiStrings" as you say. Trying to figure those out...Below is the procedure:

Code:
procedure TForm1.Button1Click(Sender: TObject);
var CurrWnd, Len, Parent : LongInt;
    Mssg : String;
    IsWordRunning : boolean;
    TaskName : PChar;
begin
    IsWordRunning := false;
    CurrWnd := GetWindow(Form1.Handle, GW_HWNDFIRST);
    While CurrWnd <> 0 do begin//While it's not my app's window
        Parent := GetParent(CurrWnd);
        Len := GetWindowTextLength(CurrWnd);
        //TaskName := Space$(Length + 1); FillChar()
        Len := GetWindowText(CurrWnd, TaskName, Len + 1);
        TaskName := Copy(TaskName, 1, Length(TaskName) - 1);
        If Len > 0 Then
            If Pos(TaskName, 'Notepad') > 0 Then begin
                IsWordRunning := True;
                break;
            End;
        CurrWnd := GetWindow(Parent, GW_HWNDNEXT);
    end;
    If IsWordRunning then Mssg := 'Is running.' else Mssg := 'Is not running.';
    ShowMessage(Mssg + '::' + TaskName);
    //GetWindow, FindWindow, EnumWindows
end;
 

You are not assigning space to your PChar. Use an AnsiString instead, they are a little easy to work with.

Code:
var CurrWnd, Len, Parent : LongInt;
    Mssg : String;
    IsWordRunning : boolean;
    // -------------------------
    TaskName : AnsiString;     //
    // -------------------------
begin
    IsWordRunning := false;
    CurrWnd := GetWindow(Form1.Handle, GW_HWNDFIRST);
    While CurrWnd <> 0 do begin//While it's not my app's window
        Parent := GetParent(CurrWnd);
        Len := GetWindowTextLength(CurrWnd);
        // -----------------------------------------------
        SetLength(TaskName, Len + 2);                    //
        GetWindowText(CurrWnd, PChar(TaskName), Len + 1);//
        //------------------------------------------------
        If Len > 0 Then
            If Pos(TaskName, 'Notepad') > 0 Then begin
                IsWordRunning := True;
                break;
            End;
        CurrWnd := GetWindow(Parent, GW_HWNDNEXT);
    end;
    If IsWordRunning then Mssg := 'Is running.' else Mssg := 'Is not running.';
    ShowMessage(Mssg + '::' + TaskName);
end;

BTW, I'm not sure your code is working as expected.

buho (A).
 
Thanks Buho. I had tried something slightly different. The problem is that I don't seem to get any titles for application outside mine...Which handle do I use so that I can loop through all the open applications?

Thanks.
 
I found a very straightforward way:

Code:
function IsRunning(sAppName : PChar) : boolean;
var
    hAppWindow: HWND;
begin
    hAppWindow := FindWindow(sAppName, nil);
    Result := hAppWindow <> 0 ;
end;

Simple as that.

Thanks.
 
Now, to detect an application running remotely is a problem...Any ideas?

I am thinking that if I could run a program on the machines of my interest that tell me what is running at a particular time and broadcast that to my application...
 
Yes, you need local programs telling a central controller what is running, or the central controller asking them.

You can't cross machine boundaries with FindWindow/EnumWindow. Desktop/winstations boundaries neither, BTW, so if you are taking the service path, be aware you need an interactive service.

buho (A).
 
I would like some light on the service option, only if you have time. Thanks a lot.
 
I'm not having time to make a post from scratch, please, help me pointing to what you want to know.

In other words: shoot your questions, BugSlayer, I'll try to do my best. :)

buho (A).

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top