|
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 |
|