Issue dated - 12th January 2004

-


Previous Issues

CURRENT ISSUE
NEWS ANALYSIS
INDIA NEWS
COLUMNS
TECH FORUM

THE C# COLUMN

BETWEEN THE BYTES
TECHNOLOGY
SPECIALS <NEW>
Symantec Report
Security Headquarters
JobsDB
MINDPRINTS
HMA BANKBIZ
EC SERVICES
ARCHIVES/SEARCH
IT APPOINTMENTS
Openings At Jobstreet.com
WRITE TO US
SUBSCRIBE/RENEW
CUSTOMER SERVICE
ADVERTISE
ABOUT US

 Network Sites
  IT People
  Network Magazine
  Business Traveller
  Exp. Hotelier & Caterer
  Exp. Travel & Tourism
  Exp. Pharma Pulse
  Exp. Healthcare Mgmt.
  Express Textile
 Group Sites
  ExpressIndia
  Indian Express
  Financial Express

 
Front Page > TechSpace > Story Print this Page|  Email this page

Tapping processes using WMI – II

In the last article we created a small application wherein we could enter the machine name, user name and password and click the ‘Refresh’ button to view the processes of that machine.

We will now explore the ‘Refresh’ and ‘Terminate Process’ button handlers.

Add the Click event handler for the ‘Refresh’ button. This handler is given below:

private void m_brefresh_Click ( object sender, System.EventArgs e )
{
   string querystring = “Select * from Win32_Process” ;
  
ObjectQuery oq = new ObjectQuery ( querystring ) ;
   ManagementScope ms ;

   if ( m_mname.Text != “” )
   {
      ConnectionOptions co = new ConnectionOptions( ) ;
      
co.Username = m_uname.Text ;
      
co.Password = m_password.Text ;
  
   ms = new ManagementScope ( @”\\” + m_mname.Text + @”\root\cimv2”, co ) ;
   }

   else
     
ms = new ManagementScope ( @”root\cimv2” ) ;

   ManagementObjectSearcher query = new ManagementObjectSearcher ( ms, oq ) ;
   
ManagementObjectCollection querycollection ;

   try
   {
     
querycollection = query.Get( ) ;
  
}

   catch ( Exception ex )
   {
     
MessageBox.Show ( “Access Denied” ) ;
     
return ;
    }

    addprocesses ( querycollection ) ;

}

In this handler, firstly, we create a query to select all the processes running on the system. Then we declare the scope by mentioning the machine name, username and password. The query and scope are then submitted so that the machine specified in the scope can be searched for the information as per the query.

We get the collection of objects as a result of the query. We can pass this collection to the addprocesses( ) function so that it enumerates the collection and add the processes to the list control.

However, if the user does not enter any machine name and clicks the ‘Refresh’ button, then processes of the local machine should get displayed. We have ensured this by checking the value of the ‘Machine Name’ textbox.

Let us now see what classes and methods have we used to do this.

We have firstly used the ObjectQuery class that represents a management query to retrieve the management objects and classes. To mention the management scope, we have used the ManagementScope class.

To the constructor of the ManagementScope class we have passed the management path and options required to access the remote machine. These options include the user name and password in our case. The options are encapsulated in an object of the ConnectionOptions class.

We have then passed the scope and the query objects to the constructor of the ManagementObjectSearcher class. When the Get( ) method of the ManagementObjectSearcher class is called, the given query is executed in the specified scope and a collection of management objects that match the query is returned in a ManagementObjectCollection.

We have called the Get( ) method in a try-catch block to handle the exception thrown by the method if something goes wrong. The collection returned by the Get( ) method is passed to the addprocesses( ) function.

If a machine name is not entered, we have instructed the application to search the root namespace of the local machine for the processes. The rest of the steps remain the same.

Now add the Click event handler for the ‘Terminate Process’ button. This handler is given below:

private void m_bterminate_Click ( object sender, System.EventArgs e )
{
   
if ( m_plist.SelectedItems.Count == 0 )
     
return ;

   ListViewItem lv = m_plist.SelectedItems [ 0 ] ;
   
int pid = Int32.Parse ( lv.SubItems [ 1 ].Text ) ;

   ManagementOperationObserver observer = new ManagementOperationObserver( ) ;

   observer.ObjectReady += new ObjectReadyEventHandler ( terminatehandler ) ;

   string querystring = “Select * from Win32_Process Where ProcessID = “ + pid ;

   ObjectQuery oq = new ObjectQuery ( querystring ) ;

   ManagementScope ms ;

   if ( m_mname.Text != “” )
  
{
     
ConnectionOptions co = new ConnectionOptions( ) ;
     
co.Username = m_uname.Text ;
     
co.Password = m_password.Text ;
     
ms = new ManagementScope ( “\\\\” + m_mname.Text + “\\root\\cimv2”, co ) ;
  
}
   else
     
ms = new ManagementScope ( @”root\cimv2” ) ;

   ManagementObjectSearcher query = new ManagementObjectSearcher ( ms, oq ) ;

   ManagementObjectCollection querycollection = query.Get( ) ;

   foreach ( ManagementObject mo in querycollection )
      
mo.InvokeMethod ( observer, “Terminate”, null ) ;

   while ( success != true );

   m_plist.Items.Remove ( lv ) ;

}

Here, firstly we check whether the user has selected a process to terminate. If the process is not selected we do nothing. To check whether the process is selected or not, we have used the Count property. Since our list control allows single selection, the Count property would return 1 or 0 according to whether the list item is selected or not.

We have obtained the process that the user has selected from the list control using the SelectedItems property. We have also obtained the ID of the selected process by using the SubItems property.

We wish to call the method that terminates the process asynchronously. For this, we have created an object of the ManagementOperationObserver class. This class has an event named ObjectReady. This event occurs when a new object is available. We have passed to it the name of the event handle i.e terminatehandler.

This handler is shown below:

public void terminatehandler ( object sender, ObjectReadyEventArgs e )
{
   
success = true ;
}

Here we have only set the success variable to true to mark the success of the termination process. Add this variable as a private data member of the Form1 class.

We have created a query to select the process having the specified ID. As in the ‘Refresh’ button handler here also we have used the ObjectQuery class object to specify the management query. We have then created an object of the ManagementScope class to specify the scope and submitted the scope and query to the ManagementObjectSearcher class.

By calling the Get( ) method we have obtained the collection of processes matching to the query. This collection holds only one process object since each process has a unique process ID.

The Win32_Process class has a method named Terminate( ) that terminates the process. To invoke the Terminate( ) method we have called the InvokeMethod( ) method on the process object. We have passed the ManagementOperationObserver object to it to manage asynchronous operations and handle management information and events received asynchronously.

We have waited until the method is terminated successfully and then removed the process name from the list control.

You can now run the application and test it by closing a process running on another machine.

akhtar@expresscomputeronline.com

Yashavant Kanetkar, one of the first Express Computer columnists, is an established software expert, speaker and author with several best-sellers to his credit, including titles like “Let Us C” and the “Fundas” series. Contact him at kanetkar@dcubesoft.com
<Back to top>


© Copyright 2003: Indian Express Group (Mumbai, India). All rights reserved throughout the world. This entire site is compiled in
Mumbai by The Business Publications Division of the Indian Express Group of Newspapers.
Please contact our Webmaster for any queries on this site.