WMI Programming with Visual Basic.NET: Managing the OS, continued

In my previous article, part three of this series, we looked at some examples of accessing OS and hardware related information through WMI and VB.NET. In this article, we will look into managing the OS using WMI methods.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 8
July 12, 2005
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement


You can download the zip of the entire Visual Studio.NET solution (developed for this article) here.

The first part of my series gives you the details for creating a Visual Studio.NET solution for WMI, right from scratch.  It will not be repeated anymore in any of the future articles in this series.

Can we operate (or manage) using WMI classes?

In all of the previous parts of this series, I mostly concentrated on retrieving information (locally or remotely).  We didn’t operate (or manage) that information. We just fetched and displayed the information on the form. 

Certain classes of WMI provide some methods for operating on WMI objects. I should admit that we will not be able to do each and every operation that WIN32 API does. But, mostly we can serve our needs just by using WMI (instead of complicating ourselves with WIN32 API). 

Since we now understand that we can manage the Windows operating system using some WMI objects, we need to know a bit of theory about its implementation. All of my examples (in previous parts of this series) until now were working only with certain properties of the respective WMI class. But, some of the WMI classes were already designed with certain methods to operate on the respective objects.  To invoke those methods programmatically, the class “ManagementObject” exposes a method called “InvokeMethod.”  Using this method, we can call any method of any WMI class (which has methods to execute) programmatically.

Whenever a method gets executed dynamically (programmatically), we should certainly check (in general) for its result (whether executed successfully or not). When any WMI methods gets executed through “InvokeMethod”, it returns an object of type “ManagementBaseObject”, which contains all of the parameters sent out (in this case return values or returned properties). We can know the status of the WMI method execution through this object easily by fetching its properties (or return values). 

I don’t want to discourage you with only theory. The following sections will show you the practical implementation of the theory stated above.

Retrieving the list of all services

As I wanted to implement the theory stated in the previous section, I am considering an example for controlling the list of services through WMI. So, before going into “real” controlling of services, first of all, we need to display the list of services to the user so that he can select a service and control it. The following code fragment fetches all the services of OS and adds them to the list box.

Me.lstServices.Items.Clear()

       DimsearcherAsNewManagementObjectSearcher("SELECT * FROM Win32_service ")

       DimoItemsAsManagementObjectCollection = searcher.Get()

       DimoItemAsManagementObject

       ForEachoItemInoItems

           Me.lstServices.Items.Add(oItem("DisplayName"))

       Next

I don’t want to get into the details of the above fragment, as the same was very clearly explained in my previous part of this series (part three).  But, make sure that we are trying to fetch all the services from the WMI class “Win32_Service”.

When you execute the above code, you should be able to see all the list services populated into the list box as follows (Fig 1):

How to know the state of a service

Every service generally starts when the OS starts and stops automatically when the OS shuts down (unless the respective service is configured differently). But we can also pause, resume or stop the service manually (based on the user's credentials and type of service).  Now the question is, how can you know the state of a service, whether running or stopped or paused or resumed or what?

There exists a property called “state” within the “Win32_Service” class. This holds the current state of the service object selected. The following code fragment show you how to fetch that property:

Me.lblState.Text = ""

       Me.lblState.Refresh()

 

       DimserviceNameAsString=Me.lstServices.SelectedItem.
ToString

       DimsearcherAsNewManagementObjectSearcher("SELECT * FROM Win32_service WHERE DisplayName='" & serviceName & "'")

       DimoItemsAsManagementObjectCollection = searcher.Get()

       Dimar(0)AsObject

        oItems.CopyTo(ar, 0)

       DimoitemAsManagementObject = ar(0)

       Me.lblState.Text = oitem("State")

The first two lines will actually clear the previous message.  If you carefully observe the above program, you'll see that I used the SELECT statement of WQL (explained in part two of my series) along with a WHERE clause based on the service name selected within the listbox.  So, it is confirmed that we will get only one object of “Win32_service” (unless more services exist with the same name). 

Since there exists only one service with that name (assumed), I created an array with only one element (zero yields to single location) and copying the service object to the array (only one gets copied).  After that, I assign that array element to “oItem” of type “ManagementObject”, where we can get the state of the service.  Consider my apologies, as I could not find a better solution than this method of retrieving a single object from “ManagementObjectCollection”.  I would be very glad if anyone could investigate and give me a better solution. 

And finally I am assigning the current status of “state” to the label.  The following figure (Fig 2) shows you the status of “Indexing Service” (at the bottom of the window) selected within the listbox (on my system).

How to modify (manage) the state of a service

This section actually manipulates (manages) the state of the service selected from the listbox. The “Win32_service” class mainly has the following methods to change the state of the service:

  • StartService

  • StopService

  • PauseService

  • ResumeService

Of course, there exist a few more too, but we shall concentrate on only the first two methods. The implementations of the last two methods are very similar to those of the first two methods. Recalling from the first section, we need to work with “InvokeMethod” of the class “ManagementObject” and receive the results in the form of an object of type “ManagementBaseObject” class. The following is the code fragment which tries to “stop” the service selected from the listbox:

DimserviceNameAsString=Me.lstServices.SelectedItem.
ToString

        DimsearcherAsNewManagementObjectSearcher("SELECT * FROM Win32_service WHERE DisplayName='" & serviceName & "'")

       DimoItemsAsManagementObjectCollection = searcher.Get()

       Dimar(0)AsObject

        oItems.CopyTo(ar, 0)

       DimoitemAsManagementObject = ar(0)

 

       ' Execute the method

       DimoutParamsAsManagementBaseObject = oitem.InvokeMethod("StopService",Nothing,Nothing)

       DimobjAsObject= outParams("ReturnValue")

       Ifobj.ToString = "0"Then

            MessageBox.Show("Succesfully stopped..")

            lstServices_SelectedIndexChanged(Nothing,Nothing)

       Else

            MessageBox.Show("Could not Stop, Returned code:" & obj.ToString)

       EndIf

The above fragment stops the service. To start the service, just replace “StopService” in the above program with “StartService” and modify the messages being displayed using “MessageBox.Show” statements. You could see a message box showing “Succesfully stopped” as shown in the following figure (Fig 3).

The next section gives a detailed explanation about the previous code fragment.

How the above program works

I already explained (in previous sections) up until the initialization of object ‘oItem’ with ‘ar(0)’. Proceeding further, we have a comment ‘Execute the method’. From that comment we are actually working with the service to change its state. Let me explain each statement separately.

       DimoutParamsAsManagementBaseObject = oitem.InvokeMethod("StopService",Nothing,Nothing)

The above statement calls the method ‘StopService’ which exists in the ‘Win32_Service’ class of WMI (through ‘InvokeMethod’ routine) and returns the result into ‘outParams’ of type ‘ManagementBaseObject’.  The first ‘Nothing’ informs that there exist no input parameters to the method ‘StopService’. The second ‘Nothing’ states that no other options (like time to execute, etc.) are necessary to execute it and considers all the defaults.

DimobjAsObject= outParams("ReturnValue")

The above statement retrieves the ‘ReturnValue’ of the operation. A zero results in success. A non zero results in failure.

Ifobj.ToString = "0"Then

            MessageBox.Show("Succesfully stopped..")

            lstServices_SelectedIndexChanged(Nothing,Nothing)

       Else

            MessageBox.Show("Could not Stop, Returned code:" & obj.ToString)

       EndIf

This is very straightforward. It just displays the proper message based on the return value and finally updates the status using the following statement:

lstServices_SelectedIndexChanged(Nothing,Nothing)

The above statement gets the code fragment explained in the second section of this article, which actually fetches the latest status of the selected service.

How will I know the proper description of the error?

In the previous program, when we “stop” the service, if it is successfully stopped, we receive zero as the returned value. I stated that a non-zero value gets returned if unsuccessful. Using this value,  we can figure out why it failed to “stop” (or “start” as well). The following table gives the list of return values and descriptions for both methods “StopService” and “StartService”.

Return code

Description

0

Success

1

Not Supported

2

Access Denied

3

Dependent Services Running

4

Invalid Service Control

5

Service Cannot Accept Control

6

Service Not Active

7

Service Request Timeout

8

Unknown Failure

9

Path Not Found

10

Service Already Running

11

Service Database Locked

12

Service Dependency Deleted

13

Service Dependency Failure

14

Service Disabled

15

Service Logon Failure

16

Service Marked For Deletion

17

Service No Thread

18

Status Circular Dependency

19

Status Duplicate Name

20

Status Invalid Name

21

Status Invalid Parameter

22

Status Invalid Service Account

23

Status Service Exists

24

Service Already Paused

By using the “Select..Case” statement with the return code, we can display properly using the definitions from the above table.  Even though I copied the above table from WMI SDK documentation, I thought it was worthwhile to include the table as part of this article to provide you with complete information.

blog comments powered by Disqus
VISUAL BASIC.NET ARTICLES

- Basic Form Properties and Modality in VB.NET
- Multiple Document Interfaces in Visual Basic
- Visual Basic for Beginners
- ASP.NET Image to PDF with VB.Net
- MySQL in ASP.NET: Mono using VB.NET
- AsyncFileUpload File Type and File Size Vali...
- Visual Studio: Adding Functionality and Style
- Clocks and Countdowns
- User-defined Functions using Visual Basic Ap...
- Understanding Object Binding in VBA
- Mastering the Message Box
- Testing a Windows Forms Application
- Using Visual Basic.NET Features to Code a Wi...
- Correcting Code in a Windows Forms Applicati...
- Write Readable Code and Comments for Windows...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 3 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials