Windows VistaVisual Studio .NET 2003Windows 2003Visual Studio 2005Windows 2000高级Windows XP.NET 2.0C# 2.0开发Visual StudioWindows.NETC#
管理远程计算机上的进程






3.57/5 (18投票s)
本文介绍了如何使用 WMI 来管理远程计算机上的进程。

引言
这篇文章提供了一个非常小的代码片段,帮助用户登录到远程机器,如果他们拥有管理员权限,则可以帮助管理进程。
我尽量使源代码尽可能简单,并在此处尝试解释它。
应用程序流程
应用程序流程非常简单
- 从域获取机器(使用Active Directory)
- 选择机器
- 提供用户名和密码(可以是域或机器特定的)
- 登录到远程机器
- 登录后,所有正在运行的进程及其一些详细信息将被加载到
datagridview
中 - 选择任何进程以终止。您可以使用按钮或上下文菜单
- 如果想启动新进程,则输入进程名称并按“开始”
代码演练
变量声明:这是程序中用于管理流程、WMI 操作和 Active Directory 搜索的变量列表。
// 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];
重要函数
此方法用于获取域中所有可用的机器
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;
}
}
这是一个非常重要的函数,因为它实际上连接到远程机器并调用特定的 WMI 查询。
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;
}
}
此代码片段在远程机器上启动新进程。
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());
}
}
结论
这样,我们可以有效地使用 WMI 来管理远程机器上的进程。
历史
- 2007年3月8日:初始发布