Export (0) Print
Expand All
Around the World with Visual Basic
Asynchronous Method Execution Using Delegates
Building a Progress Bar that Doesn't Progress
Calling All Operators
Create a Graphical Editor Using RichTextBox and GDI+
Creating A Breadcrumb Control
Creating a Five-Star Rating Control
Creating and Managing Secondary Threads
Data Binding Radio Buttons to a List
Deploying Assemblies
Designing With Custom Attributes
Digital Grandma
Doing Async the Easy Way
Extracting Data from .NET Assemblies
Implementing Callbacks with a Multicast Delegate
Naming and Building Assemblies in Visual Basic .NET
Programming Events of the Framework Class Libraries
Programming I/O with Streams in Visual Basic .NET
Reflection in Visual Basic .NET
Remembering User Information in Visual Basic .NET
Advanced Basics: Revisiting Operator Overloading
Scaling Up: The Very Busy Background Compiler
Synchronizing Multiple Windows Forms
Thread Synchronization
Updating the UI from a Secondary Thread
Using Inheritance in the .NET World
Using the ReaderWriterLock Class
Visual Basic: Simplify Common Tasks by Customizing the My Namespace
What's My IP Address?
Windows Forms Controls: Z-order and Copying Collections
Expand Minimize

Diagnose This: Launching and Controlling System Processes with Visual Basic 6 and the .NET Framework

Visual Studio .NET 2003
 

Scott Swigart
Swigart Consulting LLC

April 2006

Applies to:
   Visual Basic 6
   .NET Framework

Summary: This article explains how to use the Process class (in the System.Diagnostics section of the .NET Framework Class Library) from a Visual Basic 6 application, to launch and control system processes. (10 printed pages)

Contents

Introduction
Tom, I Can Write That App in One Line of Code
Using the Process Class from Visual Basic 6
Your Very Own Task Manager
Running the Sample
Conclusion

Click here to download the code sample for this article.

Introduction

Continuing with the Visual Basic Fusion theme of "There's nothing in .NET that you can't access from Visual Basic 6," I want to take some time to dig into the functionality provided by the .NET Framework System.Diagnostics classes. In particular, I want to take a look at the very useful Process class, which lets you launch and control system processes, and show you how you can use this class from a Visual Basic 6 application.

Tom, I Can Write That App in One Line of Code

Have you ever noticed how .NET demonstrations often degrade to "And all that with just one line of code!" It's almost like the coding version of "Name that Tune." In some ways, it's become a cliché.

Well, I'm a sucker for clichés, so take a look at the application in Figure 1, which shows extensive information about all the processes that are currently running.

Click here for larger image

Figure 1. Visual Basic .NET application that shows running process information (Click on the image for a larger picture)

And all that with just one line of code! (See Listing 1.)

Listing 1. Visual Basic .NET code to display process information

DataGrid1.DataSource = Process.GetProcesses()

The .NET Framework contains a class called Process. This class exposes functions that let you start processes, stop processes, and get information about running processes. The GetProcesses function returns an array of information about all the currently running processes. Visual Basic .NET supports databinding grids directly to arrays, and so all you have to do is set the DataSource property of the grid to the results returned from GetProcesses, and you get all the process information displayed in a grid.

Using the Process Class from Visual Basic 6

Like most of the classes in the .NET Framework, the Process class is not directly available to a Visual Basic 6 application. Instead, you can expose the functionality of this class by creating a simple wrapper in Visual Basic .NET.

Listing 2 shows the code for the wrapper.

Listing 2. Visual Basic .NET wrapper class

Imports System.Diagnostics

Public Class ProcessWrapper

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "C655826A-F52C-4DE8-91DF-61B6C439B839"
    Public Const InterfaceId As String = "2205598A-B161-421A-A6FF-2741418F2817"
    Public Const EventsId As String = "9A7918EE-E3BA-41C8-A514-04B8D18DE605"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

    Public Function Start(ByVal command As String) As ProcessInfo
        Dim p As Process = Process.Start(command)
        Return New ProcessInfo(p)
    End Function

End Class

This class was created by using the COM Class template in Visual Studio 2003, as follows:

  1. Start Visual Studio 200, click the File menu, and click New Project.
  2. Under Templates, select Class Library.
  3. In the Name text box, enter NetFrameworkWrappers, and click OK (see Figure 2).

    Figure 2. Creating a new project

  4. Click the Project menu, and then click Add New Item.
  5. Under Templates, select COM Class. This allows you to create a class from Visual Basic .NET that will expose itself as a COM object.
  6. In the Name text box, enter ProcessWrapper.vb, and then click OK (see Figure 3).

    Figure 3. Adding ProcessWrapper.vb

  7. At the top of the file, add the following line of code:
    Imports System.Diagnostics
    
    
  8. Add the following method to the class:
    Public Function Start(ByVal command As String) As ProcessInfo
        Dim p As Process = Process.Start(command)
        Return New ProcessInfo(p)
    End Function
    
    
  9. Click the Build menu, and then click Build Solution. This will compile the class and register it as a COM object.

At this point, you can just add a reference to NetFrameworkWrappers from a Visual Basic 6 application, and start using the ProcessWrapper class (see Listing 3).

Listing 3. Using the ProcessWrapper class from Visual Basic 6

Dim p As NetFrameworkWrappers.ProcessWrapper
Set p = New NetFrameworkWrappers.ProcessWrapper
p.Start ("calc.exe")

The Process class also exposes a GetProcesses method that will return information about every process running on the system. The return value of GetProcesses is an array of Process classes, and therefore it is not directly consumable by Visual Basic 6. I created a wrapper for this as well. The ProcessInfo wrapper class wraps the Process class to surface information in a way that's directly consumable by Visual Basic 6. I can then create an array of ProcessInfo classes, and return to my Visual Basic 6 code as shown in Listing 4.

Listing 4. Wrapping the results of GetProcesses so that it can be used from Visual Basic 6

Public Sub GetProcesses(ByRef procInfos() As ProcessInfo)
    Dim processes() As Process = Process.GetProcesses
    ReDim procInfos(processes.Length - 1)
    For i As Integer = 0 To processes.Length - 1
        procInfos(i) = New ProcessInfo(processes(i))
    Next
End Sub

You can see that this calls GetProcesses to retrieve an array of Process classes for each running process. I then loop through each one, and convert it to a ProcessInfo class that was specifically designed to be consumable by Visual Basic 6. For example, the TotalProcessorTime property of the Process class used the .NET TimeSpan data type. This will not show up on the Visual Basic 6 side, and therefore the ProcessInfo class instead returns this information simply as a string.

Your Very Own Task Manager

I've created a Visual Basic 6 sample application (see Figure 4) that uses the Process wrappers to let you control all the processes on your machine. You can launch processes, change a process priority, and even kill a process.

Figure 4. Visual Basic 6 Process Manager

When the form loads, it calls the GetProcesses wrapper and places all the processes in a ListView control (see Listing 5).

Listing 5. Loading the Visual Basic 6 form with process information

Public Sub LoadList()
    ListView1.ListItems.Clear
        
    Dim p As NetFrameworkWrappers.ProcessWrapper
    Set p = New NetFrameworkWrappers.ProcessWrapper
    p.GetProcesses procs
    
    Dim i As Integer
    For i = 0 To UBound(procs) - 1
        Dim subItem As ListItem
        Set subItem = ListView1.ListItems.Add(, , procs(i).ProcessName)
        subItem.SubItems(1) = procs(i).Id
        subItem.SubItems(2) = procs(i).BasePriority
        subItem.SubItems(3) = procs(i).PriorityClass
        subItem.SubItems(4) = procs(i).PriorityBoostEnabled
        subItem.SubItems(5) = procs(i).MainWindowTitle
        subItem.SubItems(6) = procs(i).MainWindowHandle
        subItem.SubItems(7) = FormatNumber(procs(i).VirtualMemorySize / 1048576, 2) & " MB"
        subItem.SubItems(8) = FormatNumber(procs(i).PeakVirtualMemorySize / 1048576, 2) & " MB"
        subItem.SubItems(9) = FormatNumber(procs(i).WorkingSet / 1048576, 2) & " MB"
        subItem.SubItems(10) = FormatNumber(procs(i).PeakWorkingSet / 1048576, 2) & " MB"
        subItem.SubItems(11) = procs(i).Responding
        subItem.SubItems(12) = procs(i).TotalProcessorTime
        subItem.SubItems(13) = procs(i).UserProcessorTime
        subItem.SubItems(14) = procs(i).HasExited
    Next

End Sub

The LoadList method is used whenever the ListView needs to be repopulated with process information. It simply calls ProcessWrapper.GetProcesses, passing in an empty array of ProcessInfo classes. When the method returns, the array is populated, and the method simply loops through the results and adds them to the list view. Some values—for example, memory usage statistics—are formatted along the way, so that they are more readable.

The application contains a field where you can enter a process name and launch it (see Listing 6).

Listing 6. Launching a process from the Visual Basic 6 application

Private Sub cmdLaunch_Click()
    Dim p As NetFrameworkWrappers.ProcessWrapper
    Set p = New NetFrameworkWrappers.ProcessWrapper
    p.Start (txtProcessLaunch)
    LoadList
End Sub

The application also lets you kill a process (see Listing 7).

Listing 7. Killing a process from the Visual Basic 6 application

Private Sub mnuKill_Click()
    CurrentProc.Kill
    LoadList
End Sub

Note   I don't think there's ever been an example of killing a process that didn't come with the warning that you really shouldn't go just killing processes willy-nilly. So consider yourself warned.

Finally, you can change the priority of a running process (see Listing 8).

Listing 8. Changing the priority of a process from the Visual Basic 6 application

Private Sub mnuSetPriority_Click()
    Set frmModifyProcess.CurrentProc = CurrentProc
    If frmModifyProcess.ShowDialog = vbOK Then
        CurrentProc.PriorityClass = frmModifyProcess.PriorityClass
        LoadList
    End If
End Sub

This simply displays another form that prompts the user to select a process priority. When the user selects a priority and clicks OK (see Figure 5), the form closes, and the information is returned. The process priority can be set simply by setting the PriorityClass property of the ProcessInfo class. This passes the information to the Visual Basic .NET component, which changes the string back into the appropriate enumeration, and changes the process priority.

Figure 5. Selecting a new process priority from the Visual Basic 6 application

Running the Sample

Included with this article is the Visual Basic 6 and Visual Basic .NET code for working with processes. To run the sample, complete the following procedures.

If you do not have Visual Studio 2005 installed, you need to download the (free) Microsoft .NET Framework, and the (free) Visual Basic Express:

At this point, you can download and run the sample:

  1. Download and unzip the code for this article.
  2. Within the zip file, you will find a file called Build and Register.bat. Double-click this to build and register the Visual Basic .NET COM component.
  3. In the ProcController folder, you will find the Visual Basic 6 sample application.

Conclusion

Once again, you have seen that you can use powerful functionality in the Microsoft .NET Framework easily from a Visual Basic 6 application in order to get things done. The class used in this article was the Process class, one of the many classes in the System.Diagnostics section of the Framework Class Library.

 

About the Author

Scott Swigart spends his time consulting, authoring, and speaking about emerging and converging technologies. Scott has worked with a wide range of technologies over his career, beginning with Commodore 64 programming at the age of 12, writing hardware diagnostics for UNIX systems in C++, and building Windows desktop and Web applications. Over the years, Scott has worked with component development, XML technologies, .NET, Web services, and other languages, platforms, and paradigms. With this experience, Scott has seen how technology evolves over time, and he is focused on helping organizations get the most out of the technology of today while preparing for the technology of tomorrow. Scott is also a Microsoft MVP, and co-author of numerous books and articles. Scott can be reached at scott@swigartconsulting.com.

Show:
© 2014 Microsoft