Visual Basic/External Processes

From Wikibooks, open books for an open world
< Visual Basic
Jump to: navigation, search

It is often the case that a program already exists to do some job so rather than rewrite the program in Visual Basic it is more efficient to run the existing program from Visual Basic. This can work very well for command line programs or scripts written in any language.

The general scheme is to create a string containing the command line, call a function to run it and then wait for the command to complete. There are many refinements that can be made including all sorts of ways of sending data to the new process, reading results from it, pausing it, setting its priority and so on.

The Shell Function [edit]

The simplest way of running an external program is to do something like this:

Shell "cmd /c dir %temp%"

Shell is a built in Visual Basic function that executes a command line and returns a handle to that process. Shell takes an optional argument that controls the window style of the new process (maximized, normal, hidden, etc.).

Unfortunately running another program like this doesn't give you much control over what is happening. In particular, there is no obvious way to find out if the program has completed its work.

Luckily Shell actually does slightly more than launch the program. It also returns the process id. This is the number displayed by Task Managers and can be used to check the status of the process. Unfortunately, as is so often the case with Visual Basic and Windows, there is no built in function nor even a single API function that can use it directly. Therefore, we must write a little more code. First, we must declare a few API functions and constants:

  Option Explicit
 
  Const SYNCHRONIZE = &H100000
  Const INFINITE = &HFFFF    'Wait forever
  Const WAIT_OBJECT_0 = 0    'The state of the specified object is signaled.
  Const WAIT_TIMEOUT = &H102 'The time-out interval elapsed, and the object’s state is nonsignaled.
  
  Private Declare Function OpenProcess Lib "kernel32" _
          (ByVal dwDesiredAccess As Long, _
           ByVal bInheritHandle As Long, _
           ByVal dwProcessId 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
 
  Dim ProcessID As Long
  Dim hProcess As Long

Here is an example of a function that executes a command and waits for it to complete:

  Function ShellWait(CommandLine As String, _
                     TimeOut As Long, _
                     WindowState As VbAppWinStyle) As Boolean
 
    Dim ProcessID As Long
    Dim hProcess As Long
 
    ProcessID = Shell(CommandLine,WindowState)
    If ProcessID <> 0 Then
      'non-zero (True) so Shell worked
      ' Get a process handle for the PID (Wait takes a handle)
      hProcess = OpenProcess(SYNCHRONIZE, False, ProcessID)
      If hProcess <> 0 Then
        ' Got process handle
        ' Wait until process finishes before going on
        If WaitForSingleObject(hProcess, TimeOut) = WAIT_OBJECT_0 Then
          ShellWait = True
        Else
          ShellWait = False
        End If
      Else
        'Failed to get process handle.
        'Perhaps the process terminated very quickly
        'or it might not really have executed at all even though Windows
        ' started a process.
        ShellWait = False
      End If
    Else
      ' PID zero (False) so Shell failed
      ShellWait = False
    End If
  End Function

Call it like this:

  If ShellWait("calc.exe") then
    MsgBox "Success :-)"
  Else
    MsgBox "Failure :-("
  End If

Batch file execution through 'Shell' function: [edit]

It is easy to execute or run the batch file or command through 'shell' function in
visual basic 6.0.

Create a simple batch file for shutdown the system


Step 1: Open Notepad Step 2: Type the following in the file <untitled>

       shutdown -s -f

Step 3: Save the file by "shutdown.bat" in someone location

       (Eg. D:\shutdown.bat)

Shutdown the system through visual basic project

Step 1: New Project Step 2: In form design, Add a command button and change the name like 'shutdown' by using

       the caption property.

Step 3: Double click on the command button

       Then the code window will be displayed on the screen
        Private sub command1_click()
 
        End sub

Step 4: Just add the following between the Private sub .... and End Sub

       shell ("D:\Shudown.bat")

Step 5: Save the Project (if required.) step 6: Run the Project (Press F5)

For Restart and Logoff the system

For Restarting the system, it is easy just make only one change that is in the batch file

   instead of <shutdown -s -f>; change <shutdown -r -f>

For Logging off the system,

   change <shutdown -l -f>

Direct way:

The commands of shutdown, restart and logoff are used directly in the shell function. Example;

Shutdown:

        Private sub command1_click()
        shell ("shutdown -s -f")        
        End sub

Restart:

        Private sub command1_click()
        shell ("shutdown -r -f")        
        End sub

Logoff:

        Private sub command1_click()
        shell ("shutdown -l -f")        
        End sub
[By Ananthakumar Selvaraj, SeA Microsystem]

--Ananthakumar Selvaraj (discusscontribs) 17:50, 3 March 2013 (UTC)[Ananthakumar Selvaraj, SeA Microsystem]

Exercises [edit]

  • Modify the ShellWait example function so that the caller can distinguish between failure to launch the process and timeout.
  • Suggest a reason why this might be a good idea.


Previous: Windows_API Contents Next: Object Oriented Programming