Determine if application is running with Excel Determine if application is running with Excel vba vba

Determine if application is running with Excel


You can check this more directly by getting a list of open processes.

This will search based on the process name, returning true/false as appropriate.

Sub exampleIsProcessRunning()      Debug.Print IsProcessRunning("MyProgram.EXE")    Debug.Print IsProcessRunning("NOT RUNNING.EXE")End SubFunction IsProcessRunning(process As String)    Dim objList As Object    Set objList = GetObject("winmgmts:") _        .ExecQuery("select * from win32_process where name='" & process & "'")    If objList.Count > 0 Then        IsProcessRunning = True    Else        IsProcessRunning = False    End IfEnd Function


Here's how I brought the search window to front:

Private Const SW_RESTORE = 9Private Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As LongPrivate Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As LongPrivate Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As LongPrivate Sub btnSearch_Click()    Dim x As Variant    Dim Path As String    If IsProcessRunning("MyProgram.exe") = False Then        Path = "C:\Tmp\MyProgram.exe"        x = Shell(Path, vbNormalFocus)    Else        Dim THandle As Long        THandle = FindWindow(vbEmpty, "Window / Form Text")        Dim iret As Long        iret = BringWindowToTop(THandle)        Call ShowWindow(THandle, SW_RESTORE)    End IfEnd Sub

Now if the window was minimized and the user clicks the search button again, the window will simply pop up.


Just want to point out that the Window Text may change when documents are open in the application instance.

For example, I was trying to bring CorelDRAW to focus and everything would work fine so long as there wasn't a document open in Corel, if there was, I would need to pass the complete name to FindWindow() including the open document.

So, instead of just:

FindWindow("CorelDRAW 2020 (64-Bit)")

It would have to be:

FindWindow("CorelDRAW 2020 (64-Bit) - C:\CompletePath\FileName.cdr")

As that is what would be returned from GetWindowText()

Obviously this is an issue as you don't know what document a user will have open in the application, so for anyone else who may be coming here, years later, who may be experiencing the same issue, here's what I did.

Option ExplicitPrivate ModulePrivate Const EXE_NAME As String = "CorelDRW.exe"Private Const WINDOW_TEXT As String = "CorelDRAW 2020" ' This is common with all opened documentsPrivate Const GW_HWNDNEXT = 2Private Const SW_RESTORE = 9Private Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As LongPrivate Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As LongPrivate Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As LongPrivate Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As LongPublic Sub FocusIfRunning(parAppName as String, parWindowText as String)    Dim oProcs As Object    Dim lWindowHandle As Long    Dim sWindowText As String    Dim sBuffer As String    ' Create WMI object and execute a WQL query statement to find if your application    ' is a running process. The query will return an SWbemObjectSet.    Set oProcs = GetObject("winmgmts:").ExecQuery("SELECT * FROM win32_process WHERE " & _                            "name = '" & parAppName & "'")    ' The Count property of the SWbemObjectSet will be > 0 if there were    ' matches to your query.    If oProcs.Count > 0 Then        ' Go through all the handles checking if the start of the GetWindowText()        ' result matches your WindowText pre-file name.        ' GetWindowText() needs a buffer, that's what the Space(255) is.        lWindowHandle = FindWindow(vbEmpty, vbEmpty)        Do While lWindowHandle            sBuffer = Space(255)            sWindowText = Left(sBuffer, GetWindowText(lWindowHandle, sBuffer, 255))            If Mid(sWindowText, 1, Len(parWindowText)) Like parWindowText Then Exit Do            ' Get the next handle. Will return 0 when there are no more.            lWindowHandle = GetWindow(lWindowHandle, GW_HWNDNEXT)        Loop        Call ShowWindow(lWindowHandle , SW_RESTORE)    End IfEnd SubPrivate Sub btnFocusWindow_Click()    Call FocusIfRunning(EXE_NAME, WINDOW_TEXT)End Sub

Hopefully somebody gets use from this and doesn't have to spend the time on it I did.