Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    May 2003
    Posts
    41

    Unanswered: Running Processes

    Is there a way in VBA in access 97 to determine if an application is running on the local machine that is running the VBA module.

    For example - can I determine if msword.exe is running in my VBA script?

  2. #2
    Join Date
    Nov 2003
    Posts
    1,487
    Here is a bit of code from Dev Ashish which will suit your needs. Enjoy

    You can use the fIsAppRunning function to check if an application is running. Pass the Appplication name to this function. An optional argument is passed as True or False if you want to activate the Application. For example, if you want to activate Word if it's found running, try this in the debug window:
    ?fIsAppRunning("Word",True)
    If you just want to know if Word is running or not, you can simply call the function like this:
    ?fIsAppRunning("word")
    Note: New class names can be added to the Select case structure to extend functionality.

    Code:
    'This code was originally written by Dev Ashish.
    'It is not to be altered or distributed,
    'except as part of an application.
    'You are free to use it in any application,
    'provided the copyright notice is left unchanged.
    '
    'Code Courtesy of
    'Dev Ashish
    '
    Private Const SW_HIDE = 0
    Private Const SW_SHOWNORMAL = 1
    Private Const SW_NORMAL = 1
    Private Const SW_SHOWMINIMIZED = 2
    Private Const SW_SHOWMAXIMIZED = 3
    Private Const SW_MAXIMIZE = 3
    Private Const SW_SHOWNOACTIVATE = 4
    Private Const SW_SHOW = 5
    Private Const SW_MINIMIZE = 6
    Private Const SW_SHOWMINNOACTIVE = 7
    Private Const SW_SHOWNA = 8
    Private Const SW_RESTORE = 9
    Private Const SW_SHOWDEFAULT = 10
    Private Const SW_MAX = 10
    
    Private Declare Function apiFindWindow Lib "user32" Alias _
        "FindWindowA" (ByVal strClass As String, _
        ByVal lpWindow As String) As Long
    
    Private Declare Function apiSendMessage Lib "user32" Alias _
        "SendMessageA" (ByVal Hwnd As Long, ByVal Msg As Long, ByVal _
        wParam As Long, lParam As Long) As Long
        
    Private Declare Function apiSetForegroundWindow Lib "user32" Alias _
        "SetForegroundWindow" (ByVal Hwnd As Long) As Long
        
    Private Declare Function apiShowWindow Lib "user32" Alias _
        "ShowWindow" (ByVal Hwnd As Long, ByVal nCmdShow As Long) As Long
        
    Private Declare Function apiIsIconic Lib "user32" Alias _
        "IsIconic" (ByVal Hwnd As Long) As Long
        
    Function fIsAppRunning(ByVal strAppName As String, _
            Optional fActivate As Boolean) As Boolean
        Dim lngH As Long, strClassName As String
        Dim lngX As Long, lngTmp As Long
        Const WM_USER = 1024
        On Local Error GoTo fIsAppRunning_Err
        fIsAppRunning = False
        Select Case LCase$(strAppName)
            Case "excel":       strClassName = "XLMain"
            Case "word":        strClassName = "OpusApp"
            Case "access":      strClassName = "OMain"
            Case "powerpoint95": strClassName = "PP7FrameClass"
            Case "powerpoint97": strClassName = "PP97FrameClass"
            Case "notepad":     strClassName = "NOTEPAD"
            Case "paintbrush":  strClassName = "pbParent"
            Case "wordpad":     strClassName = "WordPadClass"
            Case Else:          strClassName = vbNullString
        End Select
        
        If strClassName = "" Then
            lngH = apiFindWindow(vbNullString, strAppName)
        Else
            lngH = apiFindWindow(strClassName, vbNullString)
        End If
        If lngH <> 0 Then
            apiSendMessage lngH, WM_USER + 18, 0, 0
            lngX = apiIsIconic(lngH)
            If lngX <> 0 Then
                lngTmp = apiShowWindow(lngH, SW_SHOWNORMAL)
            End If
            If fActivate Then
                lngTmp = apiSetForegroundWindow(lngH)
            End If
            fIsAppRunning = True
        End If
    fIsAppRunning_Exit:
        Exit Function
    fIsAppRunning_Err:
        fIsAppRunning = False
        Resume fIsAppRunning_Exit
    End Function

  3. #3
    Join Date
    May 2003
    Posts
    41
    Can I use this to test if any app is running? Like any random .exe? Maybe there is a better way to ask my question in more detail.

    I have a function that runs a shell command. The shell command runs a perl script that creates a text file. The next line in my VB code actually uses the text file. The problem is the perl takes about 45 seconds to run, and the vb continues to the next line immediately after the shell command starts. I want it to wait until the perl finishes running. How do I do that?

  4. #4
    Join Date
    Nov 2003
    Posts
    1,487
    This is what you want......
    Here, we show you how to shell to another program from Access, stop your code while the shelled process operates and then resume your code once the process is finished. To do this you need to use the API functions:

    'WaitforSingleObject' to make the wait state
    'OpenProcess' to launch a shelled process and wait for it to complete.
    'CloseHandle' to close the process.

    Listed below is the code to use:

    1. On the declarations page of your module, add the following functions:
    Code:
    Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal _
         dwAccess As Long, ByVal fInherit As Integer, ByVal hObject _
         As Long) As Long
    Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
          hHandle As Long, ByVal dwMilliseconds As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal _
          hObject As Long) As Long
    2. Try out this test function, which launches any app you want to and waits until it is finished to display a message box (Note an " _ " underscore means line continuation):

    Code:
    Function LaunchApp32 (MYAppname As String) As Integer
     On Error Resume Next
     Const SYNCHRONIZE = 1048576
     Const INFINITE = -1&
     Dim ProcessID&
     Dim ProcessHandle&
     Dim Ret&
    
     LaunchApp32=-1
     ProcessID = Shell(MyAppName, vbNormalFocus)
       If ProcessID<>0 then
           ProcessHandle = OpenProcess(SYNCHRONIZE, True, ProcessID&)
           Ret = WaitForSingleObject(ProcessHandle, INFINITE)
           Ret = CloseHandle(ProcessHandle)
      
           MsgBox "This code waited to execute until " _ 
              & MyAppName & " Finished",64
       Else
            MsgBox "ERROR : Unable to start " & MyAppname
            LaunchApp32=0
       End If
    End Function
    3. It's very important to note that your function must include the code to close the process handle after the shelled application is complete, otherwise you will have a memory leak until you shut down Windows.

    Enjoy

  5. #5
    Join Date
    May 2003
    Posts
    41
    That works great thanks!

    Do you think you could explain it to me so i uderstand what I am coding? Or are there some help file that i can look at?

  6. #6
    Join Date
    May 2003
    Posts
    41
    One more thing - should i put all the rest of my code after all of your code? Or should I put it where you put the MsgBox?

  7. #7
    Join Date
    Nov 2003
    Posts
    1,487
    Place the code in a Module located in the modules section of your database window and make it a Public Function like this:

    Code:
    Public Function LaunchApp32 (MYAppname As String) As Integer
    In the function itself...change:

    Code:
    MsgBox "This code waited to execute until " _ 
              & MyAppName & " Finished",64
    To this:

    Code:
    Exit Function
    Now you can call this function from ANYWHERE within your program (DB) like this:

    Code:
    If LaunchApp32(myAppName) = True Then 
       '....Put your program code here....
       '.................................................
       '.................................................
     End If

  8. #8
    Join Date
    May 2003
    Posts
    41
    Great.

    Do you know where i can get an explanation of the code? I know it works, but i'd like to understand it too

    Thanks.

  9. #9
    Join Date
    Nov 2003
    Posts
    1,487
    Any books on Windows API functions....do a web search for the same ("Windows API Functions"). ALso do a search for API-GUIDE. I believe it's free.

  10. #10
    Join Date
    May 2003
    Posts
    41
    So say I want to run 2 shell programs, and then some code. In that order:

    App1-->App2-->code

    Would this require that i use some embedded if statements. I dont wanna run app2 till app1 is done, and i dont want to run the code till app2 is done.

  11. #11
    Join Date
    Nov 2003
    Posts
    1,487
    Code:
    If LaunchApp32(myFirstAppName) = True Then 
       If LaunchApp32(mySecondAppName) = True Then  
           '....Put your program code here....
           '.................................................
           '.................................................
       End If
     End If
    There you go

  12. #12
    Join Date
    May 2003
    Posts
    41
    I don't know if this is too much to ask but could you explain what the 3 functions in your code do? I have been trying to look them up online but I am having trouble finding good answers. I am obviously new to API functions, so any help you could give would be great.

  13. #13
    Join Date
    Nov 2003
    Posts
    1,487
    To save me a lot of typing...Check out this website.

    http://www.mentalis.org/agnet/apiguide.shtml

    Download the following files and install them into your computer. You will find them very very helpfull:

    API-Guide
    API-Viewer
    API-List

    (download links are located on the left sidebar In the webpage)

    API-Guide gives you explainations to what all the API functions are for, parameter explainations, and lots of samples as to how to use each API function. Happy programming....

  14. #14
    Join Date
    May 2003
    Posts
    41
    I downloaded the driver guide - thanks that was a help. But I am running into a problem. I tested the function you gave me above and it worked great. But when I tried to apply it to a slightly more complicated shell command, the app i ran with the shell command froze just after opening it. I am calling a program called axys32.exe, which creates a text file. When it is called, it is supposed to run a script (hence "taxlots.scr") and return a text file. The 4 variable names after it are 4 paramaters that I need to pass to axys32. This shell command works fine if i use it separate from the LaunchApp32 function. If i call it on its own it runs fine, but I need to wait for it to finish before i run the DoCmd.TransferText line. When I call it from with the LaunchApp32 function, axys32.exe freezes immediately after it opens, and the script never runs. Any ideas?

    Here is the code:

    If LaunchApp32("s:\axys3\axys32.exe taxlots.scr " & _
    acatFilenameUtah & " " & acatFilenameLocal & " " & _
    accountFilename & " " & settledAcatFilename) = True Then

    DoCmd.TransferText acImportDelim, "SettledSpec", "tblDailySettled" _
    , "s:\axys3\taxlots\settledAccounts.txt"

    End If

  15. #15
    Join Date
    Nov 2003
    Posts
    1,487
    Rem the On Error Resume Next located within the LaunchApp32 function and see if a message will inorm you of a problem. Other than that...sheeesh I don't know. Should work fine.

    If the command line for the application you want to run contains file names (within your variables) and those file names are in the Long Name (Joliet) format then try converting them to Short file name format (i.e.: Myfile~1.scr). Shell doesn't like the long file name format.
    Last edited by CyberLynx; 12-12-03 at 01:37.

Posting Permissions

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