Results 1 to 16 of 16

Thread: Application Running

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Sep 2000
    Location
    Jacksonville
    Posts
    23

    Arrow

    Is there some way in VB or by use of some API to test if some application is already running?
    Thanks!

  2. #2
    Serge's Avatar
    Join Date
    Feb 1999
    Location
    Scottsdale, Arizona, USA
    Posts
    2,744
    Yep, there is:
    Code:
    Private Sub Form_Load()
        If App.PrevInstance Then
            MsgBox "Application is already running."
            End 
        End If
    End Sub
    This will ensure only one copy of application.

  3. #3
    Guest

    I think he means a different application? [NT]

    ..

  4. #4
    Serge's Avatar
    Join Date
    Feb 1999
    Location
    Scottsdale, Arizona, USA
    Posts
    2,744
    Knowing application's Caption or a Class is enough to get it to work:
    Code:
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    
    Private Sub Command1_Click()
        If FindWindowEx(0, 0, vbNullString, "CaptionOfTheProgram") Then
            MsgBox "Application is running."
        End If
    End Sub

  5. #5
    _______ HeSaidJoe's Avatar
    Join Date
    Jun 1999
    Location
    Canada
    Posts
    3,946

    <?>

    Serge...would you take a quick look at the post I put up for Aaron..(Yonatan A Quick Glance Please)...now you...just need to know what to look for so I can dig deeper until I get it working.
    Tested my line and it's ok as well using the telephony in the sdk.

    Wayne
    "A myth is not the succession of individual images,
    but an integerated meaningful entity,
    reflecting a distinct aspect of the real world."

    ___ Adolf Jensen

  6. #6
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    I would rather use the FindWindow API, and not FindWindowEx, if using zero as the first two parameters.
    And, here's how to find ClassNames (better than captions): Use a program called Spy++. It comes with Visual Studio.

  7. #7
    Serge's Avatar
    Join Date
    Feb 1999
    Location
    Scottsdale, Arizona, USA
    Posts
    2,744
    Yonatan, using FindWindowEx will not slow down the process, therefore doesn't make any difference. Using Ex function instead is just a habbit of mine.



    If you don't have SPY++, then you can use this small routine I wrote a while back to see all windows that are running with their ClassNames, Captions and hWnds. Start a new project. Add a ListView and a module to your project. Copy this code to a module:

    Module Code:
    Code:
    Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
    
    Public Function EnumWinProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
        Dim strClassName As String
        Dim strCaption As String
        Dim lCaptionLength As Long
        Dim lRet As Long
        Dim lstItem As ListItem
        
        
        strClassName = Space(255)
        lRet = GetClassName(hwnd, strClassName, Len(strClassName))
        Set lstItem = Form1.ListView1.ListItems.Add(, , hwnd)
        If lRet Then
            lstItem.SubItems(1) = Left(strClassName, lRet)
        End If
        
        lCaptionLength = GetWindowTextLength(hwnd)
        strCaption = Space(lCaptionLength)
        lRet = GetWindowText(hwnd, strCaption, lCaptionLength)
        If lRet Then
            lstItem.SubItems(2) = Left(strCaption, lRet)
        End If
        
        EnumWinProc = 1
    End Function
    Then copy this code to your Form:

    Form Code:
    Code:
    Private Sub Form_Load()
        Dim hdrHeader As ColumnHeader
        
        With ListView1
            .View = lvwReport
            Set hdrHeader = .ColumnHeaders.Add(, , "hWnd")
            Set hdrHeader = .ColumnHeaders.Add(, , "Class", 2000)
            Set hdrHeader = .ColumnHeaders.Add(, , "Caption", 4000)
            .FullRowSelect = True
        End With
        
        Call EnumWindows(AddressOf EnumWinProc, 0)
    End Sub
    Running the project will list all running windows (including hidden) with their hWnd, Class and Caption.

    [Edited by Serge on 09-26-2000 at 11:29 AM]

  8. #8
    Guest
    You can also determine if an exe is running by knowing it's exe:

    Code:
    Private Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long
    
    Public Declare Function Process32First Lib "kernel32" ( _
             ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
    
    Public Declare Function Process32Next Lib "kernel32" ( _
       ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
    
    Public Declare Function CloseHandle Lib "Kernel32.dll" _
       (ByVal Handle As Long) As Long
    
    Public Declare Function OpenProcess Lib "Kernel32.dll" _
      (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, _
          ByVal dwProcId As Long) As Long
    
    Public Declare Function EnumProcesses Lib "psapi.dll" _
       (ByRef lpidProcess As Long, ByVal cb As Long, _
          ByRef cbNeeded As Long) As Long
    
    Public Declare Function GetModuleFileNameExA Lib "psapi.dll" _
       (ByVal hProcess As Long, ByVal hModule As Long, _
          ByVal strModuleName As String, ByVal nSize As Long) As Long
    
    Public Declare Function EnumProcessModules Lib "psapi.dll" _
       (ByVal hProcess As Long, ByRef lphModule As Long, _
          ByVal cb As Long, ByRef cbNeeded As Long) As Long
    
    Public Declare Function CreateToolhelp32Snapshot Lib "kernel32" ( _
       ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
    
    Public Declare Function GetVersionExA Lib "kernel32" _
       (lpVersionInformation As OSVERSIONINFO) As Integer
    
    Public Type PROCESSENTRY32
       dwSize As Long
       cntUsage As Long
       th32ProcessID As Long           ' This process
       th32DefaultHeapID As Long
       th32ModuleID As Long            ' Associated exe
       cntThreads As Long
       th32ParentProcessID As Long     ' This process's parent process
       pcPriClassBase As Long          ' Base priority of process threads
       dwFlags As Long
       szExeFile As String * 260       ' MAX_PATH
    End Type
    
    Public Type OSVERSIONINFO
       dwOSVersionInfoSize As Long
       dwMajorVersion As Long
       dwMinorVersion As Long
       dwBuildNumber As Long
       dwPlatformId As Long           '1 = Windows 95.
                                      '2 = Windows NT
    
       szCSDVersion As String * 128
    End Type
    
    Public Const PROCESS_QUERY_INFORMATION = 1024
    Public Const PROCESS_VM_READ = 16
    Public Const MAX_PATH = 260
    Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
    Public Const SYNCHRONIZE = &H100000
    'STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF
    Public Const PROCESS_ALL_ACCESS = &H1F0FFF
    Public Const TH32CS_SNAPPROCESS = &H2&
    Public Const hNull = 0
    
    Public Enum ePlatform
        eWin95_98 = 1
        eWinNT = 2
    End Enum
    
    Public gDBType As String
    
    Public Function IsApplicationRunning(pEXEName As String) As Boolean
    
        On Error Resume Next
        
        Select Case getVersion()
            Case eWin95_98
                Dim lProc As Long, strName As String
                Dim hSnap As Long, proc As PROCESSENTRY32
                
                hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
                If hSnap = hNull Then Exit Function
                proc.dwSize = Len(proc)
                ' Iterate through the processes
                lProc = Process32First(hSnap, proc)
                Do While lProc
                    strName = StrZToStr(proc.szExeFile)
                    If InStr(UCase(strName), UCase(pEXEName)) Then
                        IsApplicationRunning = True
                        Exit Function
                    End If
                    lProc = Process32Next(hSnap, proc)
                Loop
        Case eWinNT
            Dim cb As Long
            Dim cbNeeded As Long
            Dim NumElements As Long
            Dim lProcessIDs() As Long
            Dim cbNeeded2 As Long
            Dim lNumElements2 As Long
            Dim lModules(1 To 200) As Long
            Dim lRet As Long
            Dim strModuleName As String
            Dim nSize As Long
            Dim hProcess As Long
            Dim i As Long
            
            'Get the array containing the process id's for each process object
            cb = 8
            cbNeeded = 96
            Do While cb <= cbNeeded
                cb = cb * 2
                ReDim lProcessIDs(cb / 4) As Long
                lRet = EnumProcesses(lProcessIDs(1), cb, cbNeeded)
            Loop
            NumElements = cbNeeded / 4
            For i = 1 To NumElements
                'Get a handle to the Process
                hProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
                Or PROCESS_VM_READ, 0, lProcessIDs(i))
                'Got a Process handle
                If hProcess <> 0 Then
                    'Get an array of the module handles for the specified
                    'process
                    lRet = EnumProcessModules(hProcess, lModules(1), 200, _
                            cbNeeded2)
                    'If the Module Array is retrieved, Get the ModuleFileName
                    If lRet <> 0 Then
                        strModuleName = Space(MAX_PATH)
                        nSize = 500
                        lRet = GetModuleFileNameExA(hProcess, lModules(1), _
                        strModuleName, nSize)
                        strModuleName = Left(strModuleName, lRet)
                        'Check for the client application running
                        If InStr(UCase(strModuleName), UCase(pEXEName)) Then
                            IsApplicationRunning = True
                            Exit Function
                        End If
                        'List1.AddItem Left(strModuleName, lRet)
                    End If
                End If
                'Close the handle to the process
                lRet = CloseHandle(hProcess)
            Next
        End Select
    End Function
    
    Function StrZToStr(pString As String) As String
       StrZToStr = Left$(pString, Len(pString) - 1)
    End Function
    
    Public Function getVersion() As ePlatform
       Dim osinfo As OSVERSIONINFO
       Dim lRetVal As Integer
       
       osinfo.dwOSVersionInfoSize = 148
       osinfo.szCSDVersion = Space$(128)
       lRetVal = GetVersionExA(osinfo)
       getVersion = osinfo.dwPlatformId
    End Function
    
    
    If IsApplicationRunning("C:\program.exe") Then
        MsgBox "Application is running."
    Else
        MsgBox "Application is not running."
    End If

  9. #9
    Guest
    Originally posted by Serge
    Using Ex function instead is just a habbit of mine.
    A good habit if I do say so myself. I use functions with Ex because they usually mean it's an extension to a former function.

  10. #10
    Frenzied Member monte96's Avatar
    Join Date
    Sep 2000
    Location
    Somewhere in AZ
    Posts
    1,379
    Matthew, that code looks suspiciously like this one...

    http://forums.vb-world.net/showthrea...threadid=16450
    oOOo--oOOo
    __/\/\onte96
    oOOo--oOOo
    Senior Programmer/Analyst
    MCP
    [email protected]
    [email protected]


    Your results may vary.. some restrictions may apply.. pricing and participation may vary.. not available in all states.. professional driver closed course..quantities limited..

  11. #11
    Guest
    That's because it is. I copied that code into my code library, like a lot of people have, and then I just retrieved it, but I forgot where I got it from, thanks for reminding me .
    Are you going to yell at me for that?
    Because it is not like I stole the code or anything, nor did I say I made it.
    I just gave the code and I told what it does.

  12. #12
    Frenzied Member monte96's Avatar
    Join Date
    Sep 2000
    Location
    Somewhere in AZ
    Posts
    1,379
    Not yelling... just thought it was ironic that you answered a question that Serge was answering with Serge's code...
    oOOo--oOOo
    __/\/\onte96
    oOOo--oOOo
    Senior Programmer/Analyst
    MCP
    [email protected]
    [email protected]


    Your results may vary.. some restrictions may apply.. pricing and participation may vary.. not available in all states.. professional driver closed course..quantities limited..

  13. #13
    Guest
    Just to let you know, I also found the same code on http://www.planet-source-code.com . Where do you suppose that came from?

    And Serge did not say he wrote it. If he did say he wrote it, than I'd put something like this in the title:

    Code:
    'Author: Serge
    'Origin: http://forums.vb-world.net/showthrea...threadid=16450 
    'Purpose: Determine if an app is running
    'Version: VB5+
    If it makes you feel better, the above code was written by Serge.

  14. #14
    New Member
    Join Date
    Sep 2000
    Posts
    2
    Sargum,
    Here's the code to check if an app is running

    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

    Private Sub Command1_Click()

    Dim hApp As Long
    'Replace Calculator with the title of the App you want to check
    hApp = FindWindow(vbNullString, "Calculator")
    If hApp <> 0 Then
    'App is running
    Print "App is running"
    Else
    'App is not running
    Print "App is not running"
    End If

    End Sub


    Check it out!

  15. #15
    Serge's Avatar
    Join Date
    Feb 1999
    Location
    Scottsdale, Arizona, USA
    Posts
    2,744
    The function was written by me with a little help of MSDN online.
    Also, all functions that I provide on this forum written by me again with a little help of MSDN online. It is amazing what you can find there.

    Sometimes people ask questions that they already have the answer for in MSDN. All it takes is just to press F1.


    If I post an answer for something I didn't write, I usually provide a link instead.

    Regards,

  16. #16
    Guest
    I am truly sorry Serge. Whenever I provide the code, your name will always be mentioned. I am sorry for my previous mistakes. I will not do something like that again. I am really sorry!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width