Click here to Skip to main content
14,835,369 members
Articles / Programming Languages / C#
Article
Posted 8 Mar 2007

Stats

110.3K views
5.4K downloads
57 bookmarked

Manage Processes on Remote Machine

Rate me:
Please Sign up or sign in to vote.
3.57/5 (18 votes)
8 Mar 2007CPOL1 min read
The article describes how to manage processes on a remote machine using WMI
Screenshot - RemoteProcessController.png

Introduction

This article is a very small code snippet that help users to log on to a remote machine and if they have admin rights, then helps to manage the processes.

I have tried to keep the source code as simple as possible and also try to explain it here.

Application Flow

The application flow is very simple:

  1. Get the machine from domain (using active directory)
  2. Select the machine
  3. Give user name and password (either domain or machine specific)
  4. Login to remote machine
  5. On log on, list of all running processes with some details are loaded into datagridview
  6. Select any process to terminate. You can use either button or context menu
  7. If you want to start a new process, then type the name of the process and press Start

Code Walkthrough

Variable Declaration: This is the list of variables used in the program to manage the flow, WMI operations and active directory searching.

C#
// List of domains that will be loaded in a combobox
private string []domains = {"india"};
// User name and password required to login to the selected machine
private string userName;
private string password;
private string machineName;
private string myDomain;
       
// I am using a datatable which contains 7 columns with these column names 
private string[] columnNames = { "Caption", "ComputerName", 
"Description", "Name", "Priority", "ProcessID", "SessionId" };        
// Hashtable to maintain list of machines and related users
private Hashtable hs = new Hashtable();
// Scope of the WMI operations
private ManagementScope myScope;
// Connection options to set user credentials
private ConnectionOptions connOptions;
// Retrieve list of management object based upon specific query
private ManagementObjectSearcher objSearcher;
// Handled management events
private ManagementOperationObserver opsObserver;
// Used to create new process on remote machine
private ManagementClass manageClass;
// Following are active directory objects to search users and computers
private DirectoryEntry entry;
private DirectorySearcher searcher;
private DirectorySearcher userSearcher;
private DataTable dt;
private DataColumn []dc = new DataColumn[7];

Important Functions

This method is used to get all machines available on the domain:

C#
private void btnGetMachines_Click(object sender, EventArgs e)
{
    Cursor.Current = Cursors.WaitCursor;
            
    int index = 0;
    // Create an entry for domain
    entry = new DirectoryEntry("LDAP://" + cmbDomainList.Text);
    // Create a user searcher by using filter
    userSearcher = new DirectorySearcher(entry);
    userSearcher.Filter = ("(objectclass=user)");
    SearchResultCollection src = userSearcher.FindAll();            
    
    // Get all computers
    searcher = new DirectorySearcher(entry);
    searcher.Filter = ("(objectclass=computer)");
            
    try
    {
        // Get the result collection
        SearchResultCollection results = searcher.FindAll();
        foreach (SearchResult sr in results)
        {
            DirectoryEntry de = sr.GetDirectoryEntry();
            // Remove preceding "CN=" character string
            cmdMachinesInDomain.Items.Add(de.Name.Remove(0,3));
            // Also get the users
            DirectoryEntry de1 = src[index++].GetDirectoryEntry();
            cmbUsers.Items.Add(de1.Properties["cn"].Value.ToString());
            if (!hs.ContainsKey(de.Name))
            {
                hs.Add(de.Name.Remove(0, 3), 
                de1.Properties["cn"].Value.ToString());
            }
        }
        cmdMachinesInDomain.SelectedIndex = 0;                
        cmbUsers.SelectedIndex = 0;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        this.Cursor = Cursors.Default;
    }
}

This is a very important function as it actually connects to a remote machine and calls a WMI specific query.

C#
private void ConnectToRemoteMachine()
{            
    int width = dataGridView1.Width;
    int singleColWidth;          
    // Make width of all columns same
    singleColWidth = width / dt.Columns.Count;
    
    userName = txtUserName.Text.Trim();
    password = txtPassword.Text.Trim();
    if (cmdMachinesInDomain.SelectedItem != null)
    {
        machineName = cmdMachinesInDomain.SelectedItem.ToString();
    }
    else if (cmdMachinesInDomain.SelectedText != string.Empty)
    {
        machineName = cmdMachinesInDomain.SelectedText;
    }
    else
    {
        machineName = cmdMachinesInDomain.Text;
    }

    myDomain = cmbDomainList.Text;

    try
    {
        connOptions = new ConnectionOptions();
        connOptions.Impersonation = ImpersonationLevel.Impersonate;
        connOptions.EnablePrivileges = true;
        // Here we can connect to machine by using domain credentials or by using 
        // machine specific credentials
        if (machineName.ToUpper() == Environment.MachineName.ToUpper())
        {
            // Create the management scope with given credentials
            myScope = new ManagementScope(@"\ROOT\CIMV2", connOptions);
        }
        else
        {
            if (chkUseDomain.Checked)
            {
                connOptions.Username = myDomain + "\\" + userName;
            }
            else
            {
                connOptions.Username = machineName + "\\" + userName;
            }
            connOptions.Password = password;
            myScope = new ManagementScope(@"\\" + machineName + 
                @"\ROOT\CIMV2", connOptions);
        }

        myScope.Connect();
        // Query on win32 process
        objSearcher = new ManagementObjectSearcher
        ("SELECT * FROM Win32_Process");
        opsObserver = new ManagementOperationObserver();
        objSearcher.Scope = myScope;
        string[] sep = { "\n", "\t" };
        toolStripStatusLabel1.Text = string.Empty;
        toolStripStatusLabel1.Text = 
        "Authentication successful. Getting processes..";
        dt.Rows.Clear();
        // Get all processes from the machine                
        foreach (ManagementObject obj in objSearcher.Get())
        {
            string caption = obj.GetText(TextFormat.Mof);
            string[] split = caption.Split
            (sep, StringSplitOptions.RemoveEmptyEntries);
            DataRow dr = dt.NewRow();
            // Iterate through the splitter
            for (int i = 0; i < split.Length; i++)
            {
                if (split[i].Split('=').Length > 1)
                {
                    // Extract the right name of the process
                    string []procDetails = split[i].Split('=');
                    procDetails[1] = procDetails[1].Replace(@"""", "");
                    procDetails[1] = procDetails[1].Replace(';', ' ');
                    switch (procDetails[0].Trim().ToLower())
                    {
                        case "caption":
                            dr[dc[0]] = procDetails[1];
                            break;
                        case "csname":
                            dr[dc[1]] = procDetails[1];
                            break;
                        case "description":
                            dr[dc[2]] = procDetails[1];
                            break;
                        case "name":
                            dr[dc[3]] = procDetails[1];
                            break;
                        case "priority":
                            dr[dc[4]] = procDetails[1];
                            break;
                        case "processid":
                            dr[dc[5]] = procDetails[1];
                            break;
                        case "sessionid":
                            dr[dc[6]] = procDetails[1];
                            break;
                    }
                }
            }
            dt.Rows.Add(dr);
        }
        bindingSource1.DataSource = dt.DefaultView;
        foreach (DataColumn col in dt.Columns)
        {
            DataGridViewTextBoxColumn dvc = new DataGridViewTextBoxColumn();
            dvc.ToolTipText = col.ColumnName;
            dvc.Name = col.ColumnName;
            dvc.HeaderText = col.ColumnName;
            dvc.DataPropertyName = col.ColumnName;
            dvc.Width = singleColWidth;
            dataGridView1.Columns.Add(dvc);
        }
        grpStartNewProcess.Enabled = true;
        btnEndProcess.Enabled = true;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        this.Cursor = Cursors.Default;
    }
}

This code snippet starts a new process on the remote machine.

C#
private void btnStartNew_Click(object sender, EventArgs e)
{
    object[] arrParams = {txtNewProcess.Text.Trim()};
    try
    {
        manageClass =
            new ManagementClass(myScope,
        new ManagementPath("Win32_Process"), new ObjectGetOptions());
        manageClass.InvokeMethod("Create", arrParams);
        btnConnect_Click(sender, e);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

Conclusion

This way, we can have WMI used efficiently to manage processes on remote machines.

History

  • 8th March, 2007: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

jdkulkarni
Software Developer (Senior) Symantec Services, Pune
India India
Dear Friends,
I'm from Pune and currently working with Symantec. I'm having 7+ yrs of software development experience and I'm working on .NET since 6+ years.
I'm a Brainbench Certified Software Engineer in C#, ASP.NET, .NET Framework and ADO.NET.

Comments and Discussions

 
QuestionError in SearchResultCollection src = userSearcher.FindAll(); Pin
aakashmca26-Apr-19 0:16
Memberaakashmca26-Apr-19 0:16 
Questionvb.net Code Please :( really need it Pin
Member 1108095222-Sep-14 8:13
MemberMember 1108095222-Sep-14 8:13 
Questionvb.net Code Please Pin
Member 1108095222-Sep-14 8:12
MemberMember 1108095222-Sep-14 8:12 
QuestionThe RPC server is unavailable Pin
Member 1083076819-May-14 22:42
MemberMember 1083076819-May-14 22:42 
QuestionHow to get only running process or applicaton of remote desktop Pin
GetCodeHelp13-May-14 1:53
MemberGetCodeHelp13-May-14 1:53 
QuestionIssue with connection. Pin
Member 1024169824-Sep-13 20:35
MemberMember 1024169824-Sep-13 20:35 
Questionhow to chenge the session ID. Pin
Code-Hunt29-Jul-13 2:06
MemberCode-Hunt29-Jul-13 2:06 
QuestionThe RPC server is unavailable. Pin
Boyka.Zhu4-Sep-12 22:25
MemberBoyka.Zhu4-Sep-12 22:25 
GeneralThe RPC server is unavailable Pin
Member 318804727-Oct-10 16:14
MemberMember 318804727-Oct-10 16:14 
QuestionThe Server is not operational Pin
sksaininet30-Sep-10 17:39
Membersksaininet30-Sep-10 17:39 
AnswerRe: The Server is not operational Pin
Member 782023919-Dec-12 23:09
MemberMember 782023919-Dec-12 23:09 
Generalfind user account on target machine Pin
sepel3-Sep-10 0:41
Membersepel3-Sep-10 0:41 
Questionadd a user column Pin
aleroot3-Nov-08 5:49
Memberaleroot3-Nov-08 5:49 
GeneralNo window Pin
kpb7-Aug-08 6:47
Memberkpb7-Aug-08 6:47 
GeneralAccess is denied Pin
kenix18-Feb-08 21:51
Memberkenix18-Feb-08 21:51 
QuestionConnecting to remotw computer's WMI Pin
wicked weapon26-Sep-07 17:54
Memberwicked weapon26-Sep-07 17:54 
GeneralAccess is denied Pin
hem2730-Jul-07 1:51
Memberhem2730-Jul-07 1:51 
GeneralRPC Server not available Pin
Hakkoos9-Jul-07 6:32
MemberHakkoos9-Jul-07 6:32 
Generalnot work with remote machine. Pin
ANWER QUADRI9-May-07 23:29
MemberANWER QUADRI9-May-07 23:29 
GeneralRe: not work with remote machine. Pin
jdkulkarni13-May-07 18:56
Memberjdkulkarni13-May-07 18:56 
GeneralRe: not work with remote machine. Pin
Member 450778117-Sep-07 12:56
MemberMember 450778117-Sep-07 12:56 
GeneralDouble hop issue Pin
Abstract197921-Mar-07 12:46
MemberAbstract197921-Mar-07 12:46 
GeneralLimiting processes shown Pin
hardsoft21-Mar-07 10:50
Memberhardsoft21-Mar-07 10:50 
Generalwhy Pin
Thanks for all the fish8-Mar-07 5:45
MemberThanks for all the fish8-Mar-07 5:45 
GeneralRe: why Pin
Angelo Cresta8-Mar-07 7:20
professionalAngelo Cresta8-Mar-07 7:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.