Vb. NET to start and monitor external programs

Source: Internet
Author: User
Tags exit chr command line sin stdin win32
Program

You no longer need to use the WIN32 application programming interface or VB Shell function to start the external application. Because you can use. NET Framework to further simplify the code by doing this operation with the System.Diagnostics.Process class.

Although. NET makes a lot of things more complicated, but it's not the start of an external application. In traditional VB programs, you can use the Shell function to start an application. When you send a data file name, VB opens the data file in the appropriate application. You can use an optional windowstyle parameter to control the window mode of the application that is started. For example, in VB6, the following line of code launches the default text editor (usually Notepad) and opens the file "C:\somepath\somefile.txt":

Returnid = Shell ("C:\somepath\somefile.txt", Vbnormalfocus)

With the Microsoft.VisualBasic.Comaptibility domain name space, the shell feature is still available in the vb.net, and it has been changed, but it is not the best way to start an application in the. NET Framework because the Shell function has some strict restrictions , one of which is to start the program asynchronously, and your own program continues to run after you start the application. So you can't just use it to start a program, and you can only wait until the program exits before you can return to your own program. To do this in traditional VB, you have to turn to the Windows API, which requires an understanding of window handles, process identification numbers, and enumeration of top-level windows.

With. NET, you can make this operation simple. You can use the Process class in the System.Diagnostics domain namespace to start an external program. You can simply use the shared Process.Start method to launch a new process that transmits an executable filename or an extended associated filename of an executable application as a parameter to it. For example, the following code launches the "C:\somepath\somefile.txt" file.

System.Diagnostics.Process.Start ("C:\somepath\somefile.txt")

The Start method has an overloaded version that returns a Process object, so you can get a reference to the startup process and can be used for a variety of purposes:

Dim myprocess as Process = System.Diagnostics.Process.Start
("C:\somepath\somefile.txt")
MessageBox.Show (Myprocess.processname)

At first glance, you seem to lose the ability to control the style of the window (remember the second argument of the Shell function?). ), but that is not the case. In many cases, you don't need to explicitly set the window style, because the default is to start the process in a normal window with focus (Processwindowstyle.normal). But if you want to use a different window style, you can use an overloaded Process.Start method to receive a ProcessStartInfo object argument instead of a simple string. To use it, you first create a ProcessStartInfo object, and then set the process initial value. Two overload methods let you set a filename or a filename and a set of command-line arguments. And the ProcessStartInfo object also has a WindowStyle property, which consists of the values of the System.Diagnostics.Process.WindowStyle enumeration. So you can call the Process.Start method and send a ProcessStartInfo object to control the style of the startup window.

Dim PsInfo as New _
System.Diagnostics.ProcessStartInfo _
("C:\somepath\somefile.txt")
Psinfo.windowstyle = _
System.Diagnostics.ProcessWindowStyle.Normal
Dim myprocess as Process = _
System.Diagnostics.Process.Start (PsInfo)

Because the process class has a StartInfo property, which is a ProcessStartInfo object, another way to produce the same result is to create a process object and set its StartInfo property. When you create a process object in advance, you can simply call its start method without using the shared Start method of the Process class.

Dim myprocess as System.Diagnostics.Process = _
New System.Diagnostics.Process ()
MyProcess.StartInfo.FileName = _
"C:\somepath\somefile.txt"
MyProcess.StartInfo.WindowStyle = _
System.Diagnostics.ProcessWindowStyle.Normal
Myprocess.start

To set process parameters during design time

. NET Framework was shipped with a process component that encapsulates the code during design time. You can find it in the Components section of the toolbar. To use it, drag a process component onto your form, and then expand the StartInfo property in the Properties window, setting the value of StartInfo as shown in the following figure (Figure 1).





Figure 1: You can add a process component to a form that allows you to set properties during design time instead of setting them during run time.

  Monitoring the startup process

So far, you've seen a startup process that uses an asynchronous approach, just like a traditional VB Shell function. In other words, the code in the parent program can continue to execute after the process is started. You need some way to monitor the process being started and figure out when they will quit or are still running. Depending on the specifics of your application, you may need to deal with the problem in a different way.

Start the process and stop your program until it exits.

Start the process, monitor it, and only do something when it's over, and let your program run normally.

Start the process, give it some input, let it process the input, and then force it to exit.

Start the process, and perform certain actions as long as the start process is running or the problem is not occurring during the run. If the process exits or stops, you need to make certain actions.

Start the process and give it some special input, and/or get further processing to produce the output results. For example, you might want to start a command window to programmatically enter some content into this window, and then get and process the output.


  Start a process and wait until it exits

Call the Process.waitforexit method when you wait for the simplest way to end a startup process. This causes the process that is being started to stop executing until the process that is started exits. Unfortunately, when you use this method directly from a Windows Form, it can also cause the form to stop responding to system events, such as paint.

So generally you don't want to use the WaitForExit method from a button to start an external program (although using the WaitForExit method is ideal for starting another process from an application that does not have a visual user interface). For example, a console application is invoked from a asp.net application server. The sample form shown in Figure II has a button called "Launch and WaitForExit" that lets you see what happens when you use this method from a form.


Figure 2: The sample form lets you test and test the various startup processes.

Private Sub Btnwaitforexit_click (_
ByVal sender as System.Object, _
ByVal e As System.EventArgs) _
Handles Btnwaitforexit.click

' Create a new process
Dim myprocess as Process = _
System.Diagnostics.Process.Start ("Sample.txt")

' Wait until it exits
Myprocess.waitforexit ()

' Show results
MessageBox.Show ("Notepad is closed at:" & _
Myprocess.exittime & "." & _
System.Environment.NewLine & "Exit Code:" & _
Myprocess.exitcode)
Myprocess.close ()
End Sub


The previous example illustrates an interesting situation. You still have the ability to access process objects in your code even after the start of the procedure, but in this case most process properties are not available because the process itself no longer exists. You can still read the ExitCode and Exittime properties, which return the values of both integers and datetime types respectively. The DOS command sets an exit code to let you know if there is an error. NET and other Windows applications can set this value by using the return value of the Main method. By default, this value is equal to zero. For DOS commands, a non-0 ExitCode value either indicates an error or indicates that the command process was aborted abnormally.

  To start a process that is not visible

In a visible window, you don't have to start a process; sometimes you just want to run a process and get the output value. The following example converts the current directory to the system directory and then runs a dos dir command with a "*. com" parameter that lists all files with the. com extension in the directory. In Windows XP, the command shell interpreter makes the "&&" operator a command delimiter, so you can place multiple commands on one line. The ">>" operator redirects the output value to a development file. In this case, the code imports the results of the DIA display into the "dirOutput.txt" file in the path specified by the Application.startuppath property.

Dim myprocess as Process = New process ()
Dim S as String
Dim outfile as String = Application.startuppath & _
"\diroutput.txt"
' Get the system path
Dim Sysfolder as String = _
System.Environment.GetFolderPath _
(Environment.SpecialFolder.System)
' Set file name and command line arguments
MyProcess.StartInfo.FileName = "cmd.exe"
MyProcess.StartInfo.Arguments = "/C CD" & _
Sysfolder & "&& dir *.com >>" & Chr (+) & _
OutFile & Chr (+) & "&& exit"
' Start the process in a hidden window
MyProcess.StartInfo.WindowStyle = _
Processwindowstyle.hidden
MyProcess.StartInfo.CreateNoWindow = True
Myprocess.start ()

' If the process cannot be completed in 1 seconds, then destroy it
Myprocess.waitforexit (1000)
If not myprocess.hasexited Then
Myprocess.kill ()
End If

' Show exit time and exit code
MessageBox.Show ("The ' dir ' Command Window was" & _]
"Closed at:" & Myprocess.exittime & "." & _
System.Environment.NewLine & "Exit Code:" & _
Myprocess.exitcode)
Myprocess.close ()


The preceding code returns a exitcode of 0 (0) values. If you want to see an example of a non-0 value ExitCode, you can attach an "X" or other character to the system directory, which makes it illegal. This causes an error to occur and the ExitCode value will be different. Because a process with errors can run all the time, the code waits a few milliseconds before returning to the program that controls the startup, using an overloaded WaitForExit method. The code above waits a second, then calls the Kill method to end the start process, forcing the procedure to exit. Check to see if the DirOutput.txt in your application startup directory exists.

Detect when a process exits

In VB6, you can call the Getmoduleusage () function of the Win32 API to determine when the process ends. In. NET, the appropriate action is to loop continuously after the startup process, check the Process.hasexited property, and call the Application.doevents method to handle other events in your application until the process is complete.

Do as not myprocess.hasexited
Application.doevents
Loop


But the process class gives you a more concise way of determining when a process exits-it can produce a exited event. To make this happen, you need to set the Process.enableraisingevents property to True (the property value is false by default) and create an event handle. For example:

' Allow the process to generate events
Myprocess.enableraisingevents = True

' Add a exited event handle
AddHandler myprocess.exited, _
AddressOf me.processexited

' Start process
Myprocess.start ()

' Event handlers
Friend Sub processexited (ByVal sender as Object, _
ByVal e as System.EventArgs)
Dim myprocess as Process = DirectCast (_
sender, Process)
MessageBox.Show ("The process exited, raising" & _
"The Exited event at:" & Myprocess.exittime & _
"." & System.Environment.NewLine & _
"Exit Code:" & Myprocess.exitcode)
Myprocess.close ()
End Sub


The potential problem with both approaches is that if the startup process hangs or never exits, your application will stop. The solution is to add a timer that periodically checks to see if the startup program is responding.

  Control process input and output

Sometimes, instead of just using a simple command line, you might want to send more complex input information directly to the startup process. In the previous example, the method of importing output into a file is not always the best choice. In many cases, it may be more efficient to direct the output back to your application. For programs that use stdin, stdout, and stderr, such as a console application, you can override the default method, provide a StreamWriter input, and provide a streamreaders to read stdout and stderr output values. When you start the process, you need to set the Redirectstandardinput, Redirectstandardoutput, and Redirectstandarderror properties of the ProcessStartInfo object to True. Then, after the startup process, use the Standardinput, StandardOutput, and StandardError properties of the Process object to assign the input output stream to the StreamReader and StreamWriter objects.

Warning: By default, the framework uses the Win32 ShellExecute function to start the process internally, but when you want to redistribute the input output stream, you must set the Processstartinfo.useshellexecute property to False before the startup process. Note that when you do that, you must either specify the full path to the file, or the file location must be in the environment path. For example, the following code creates an invisible window, obtains a list of directories for the. com file in the system directory, and then displays the results in a message box.

Dim myprocess as Process = New process ()
Dim S as String
MyProcess.StartInfo.FileName = "cmd.exe"
MyProcess.StartInfo.UseShellExecute = False
MyProcess.StartInfo.CreateNoWindow = True
MyProcess.StartInfo.RedirectStandardInput = True
MyProcess.StartInfo.RedirectStandardOutput = True
MyProcess.StartInfo.RedirectStandardError = True
Myprocess.start ()
Dim sIn as StreamWriter = Myprocess.standardinput
Sin.autoflush = True

Dim SOut as StreamReader = Myprocess.standardoutput
Dim sErr as StreamReader = Myprocess.standarderror
Sin.write ("dir c:\windows\system32\*.com" & _
System.Environment.NewLine)
Sin.write ("Exit" & System.Environment.NewLine)
s = sout.readtoend ()
If not myprocess.hasexited Then
Myprocess.kill ()
End If

MessageBox.Show ("The ' dir ' Command Window was" & _
Closed at: "& Myprocess.exittime &". "& _
System.Environment.NewLine & "Exit Code:" & _
Myprocess.exitcode)

Sin.close ()
Sout.close ()
Serr.close ()
Myprocess.close ()
MessageBox.Show (s)


For programs that do not use stdin, you can use the SendKeys method to enter key events. For example, the following code launches Notepad and enters some text.

973 448:

1 2 3
Dim myprocess as Process = New process ()
MyProcess.StartInfo.FileName = "Notepad"
MyProcess.StartInfo.WindowStyle = _
Processwindowstyle.normal
Myprocess.enableraisingevents = True
AddHandler myprocess.exited, _
AddressOf me.sendkeystestexited
Myprocess.start ()

Myprocess.waitforinputidle (1000)
If myprocess.responding Then
System.Windows.Forms.SendKeys.SendWait (_
"This text is entered using the" & _
"System.Windows.Forms.SendKeys method.")
Else
Myprocess.kill ()
End If

You can use the SendKeys method to send any type of value, including the ALT, CTRL, and SHIFT keys, so you can use it to save or load files, exit, or execute other menu-driven commands. However, the SendKeys method sends only typed values to the active window (that is, the window with focus), so if an application loses focus in the process, the problem may occur.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.