目前處於待離職狀態,原先所有的工作都在進行交接,過程當中不乏有很多先前整理的和動手嘗試實現的功能;我的主頁中已經列出來一部分內容,有興趣的可以前往看一看。
接下來的內容主要介紹另外一個工具,用於對遠程主機進行遠程控制、進程管理、服務管理以及WMI相關信息顯示等;其中仍然存在部分問題還沒有得到有效的解決,希望曾經參與過或者有關相關經驗的前輩能夠指導一下。
一、很搓很搓的主界面
1、配置菜單里面包括遠程主機連接配置信息的添加和編輯,界面如下:
2、功能菜單里面包括對遠程主機遠程控制、遠程管理、服務管理和WMI信息查詢;
3、添加完成后,功能菜單會進行相應的變化,如下圖:
二、主要功能實現部分
遠程主機配置信息
public class RemoteMachine { /// <summary> /// 桌面名稱 /// </summary> public string DesktopName { get { return this._DesktopName ?? this.Server; } set { this._DesktopName = value; } } private string _DesktopName = null; /// <summary> /// 遠程桌面的IP地址或者域名 /// </summary> public string Server { get; set; } /// <summary> /// 用戶名 /// </summary> public string UserName { get; set; } /// <summary> /// IP /// </summary> public string Domain { get; set; } /// <summary> /// 登錄密碼 /// </summary> public string Password { get; set; } /// <summary> /// 允許查詢進程 /// </summary> public bool ShowProcess { get { return _ShowProcess; } set { _ShowProcess = value; } } private bool _ShowProcess = true; /// <summary> /// 允許遠程 /// </summary> public bool RemoteAble { get { return _RemoteAble; } set { _RemoteAble = value; } } private bool _RemoteAble = true; /// <summary> /// 允許查詢服務 /// </summary> public bool ShowService { get { return _ShowService; } set { _ShowService = value; } } private bool _ShowService = true; /// <summary> /// 共享磁盤驅動器 /// </summary> public bool RedirectDrives { get { return _RedirectDrives; } set { _RedirectDrives = value; } } private bool _RedirectDrives = true; /// <summary> /// 共享打印機 /// </summary> public bool RedirectPrinters { get { return _RedirectPrinters; } set { _RedirectPrinters = value; } } private bool _RedirectPrinters = false; /// <summary> /// 共享端口 /// </summary> public bool RedirectPorts { get { return _RedirectPorts; } set { _RedirectPorts = value; } } private bool _RedirectPorts = false; /// <summary> /// 色彩深度 /// </summary> public Colors ColorDepth { get { return _ColorDepth; } set { _ColorDepth = value; } } private Colors _ColorDepth = Colors.Color24; public override string ToString() { return string.Format("{0}:{1}", this.DesktopName, this.Server); } public void Save(IniFile iniFile) { Save(this, iniFile); } public void Delete(IniFile iniFile) { string section = string.Format("Remote({0})", this.DesktopName); iniFile.DeleteSection(section); } public void Load(IniFile iniFile, string desktopName) { string section = string.Format("Remote({0})", desktopName); this.DesktopName = desktopName; this.Server = iniFile.ReadString(section, "Server", ""); this.UserName = iniFile.ReadString(section, "UserName", ""); this.Domain = iniFile.ReadString(section, "Domain", ""); this.Password = iniFile.ReadString(section, "Password", ""); this.RemoteAble = iniFile.ReadInt(section, "RemoteAble", 0) == 1; this.ShowProcess = iniFile.ReadInt(section, "ShowProcess", 0) == 1; this.ShowService = iniFile.ReadInt(section, "ShowService", 0) == 1; this.RedirectDrives = iniFile.ReadInt(section, "RedirectDrives", 0) == 1; this.RedirectPrinters = iniFile.ReadInt(section, "RedirectPrinters", 0) == 1; this.RedirectPorts = iniFile.ReadInt(section, "RedirectPorts", 0) == 1; this.ColorDepth = (Colors)iniFile.ReadInt(section, "ColorDepth", 0); } public static RemoteMachine Load(string desktopName, IniFile iniFile) { string section = string.Format("Remote({0})", desktopName); RemoteMachine mac = new RemoteMachine(); mac.DesktopName = desktopName; mac.Server = iniFile.ReadString(section, "Server", ""); mac.UserName = iniFile.ReadString(section, "UserName", ""); mac.Domain = iniFile.ReadString(section, "Domain", ""); mac.Password = iniFile.ReadString(section, "Password", ""); mac.RemoteAble = iniFile.ReadInt(section, "RemoteAble", 0) == 1; mac.ShowProcess = iniFile.ReadInt(section, "ShowProcess", 0) == 1; mac.ShowService = iniFile.ReadInt(section, "ShowService", 0) == 1; mac.RedirectDrives = iniFile.ReadInt(section, "RedirectDrives", 0) == 1; mac.RedirectPrinters = iniFile.ReadInt(section, "RedirectPrinters", 0) == 1; mac.RedirectPorts = iniFile.ReadInt(section, "RedirectPorts", 0) == 1; mac.ColorDepth = (Colors)iniFile.ReadInt(section, "ColorDepth", 0); return mac; } public static void Save(RemoteMachine machine, IniFile iniFile) { string section = string.Format("Remote({0})", machine.DesktopName); iniFile.WriteString(section, "DesktopName", machine.DesktopName); iniFile.WriteString(section, "Server", machine.Server); iniFile.WriteString(section, "UserName", machine.UserName); iniFile.WriteString(section, "Domain", machine.Domain); iniFile.WriteString(section, "Password", machine.Password); iniFile.WriteInt(section, "RemoteAble", machine.RemoteAble ? 1 : 0); iniFile.WriteInt(section, "ShowProcess", machine.ShowProcess ? 1 : 0); iniFile.WriteInt(section, "ShowService", machine.ShowService ? 1 : 0); iniFile.WriteInt(section, "RedirectDrives", machine.RedirectDrives ? 1 : 0); iniFile.WriteInt(section, "RedirectPrinters", machine.RedirectPrinters ? 1 : 0); iniFile.WriteInt(section, "RedirectPorts", machine.RedirectPorts ? 1 : 0); iniFile.WriteInt(section, "ColorDepth", (int)machine.ColorDepth); } public static List<RemoteMachine> Load(IniFile iniFile) { string[] infos = iniFile.ReadAllSectionNames(); if (infos != null) { List<RemoteMachine> macs = new List<RemoteMachine>(); foreach (string info in infos) { string section = info.Substring(7, info.Length - 8); RemoteMachine mac = RemoteMachine.Load(section, iniFile); macs.Add(mac); } return macs; } return null; } } public enum Colors : int { Color8 = 8, Color16 = 16, Color24 = 24, Color32 = 32 }
1、遠程控制功能
工具內實現的遠程控制功能需要引用AxInterop.MSTSCLib.dll和Interop.MSTSCLib.dll文件,具體代碼如下:
public partial class DesktopForm : Form, IRemote { private AxMsRdpClient4 rdpc = null; public RemoteMachine Machine { get; set; } public DesktopForm(RemoteMachine machine) { InitializeComponent(); Text = string.Format("【遠程】{0}", machine.DesktopName); this.Machine = machine; } private void DesktopForm_Load(object sender, EventArgs e) { this.rdpc = new AxMsRdpClient4() { Dock = DockStyle.Fill }; this.rdpc.OnDisconnected += rdpc_OnDisconnected; this.Controls.Add(this.rdpc); this.SetRdpClientProperties(this.Machine); Connect(); } private void rdpc_OnDisconnected(object sender, IMsTscAxEvents_OnDisconnectedEvent e) { } public bool Connect() { try { rdpc.Connect(); return true; } catch (Exception ex) { MessageBox.Show(ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } } public void Disconnect() { try { if (rdpc.Connected == 1) rdpc.Disconnect(); } catch (Exception ex) { MessageBox.Show(ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } private void SetRdpClientProperties(RemoteMachine machine) { rdpc.Server = machine.Server; rdpc.UserName = machine.UserName; rdpc.Domain = machine.Domain; if (!string.IsNullOrEmpty(machine.Password)) rdpc.AdvancedSettings5.ClearTextPassword = machine.Password; rdpc.AdvancedSettings5.RedirectDrives = machine.RedirectDrives; rdpc.AdvancedSettings5.RedirectPrinters = machine.RedirectPrinters; rdpc.AdvancedSettings5.RedirectPorts = machine.RedirectPorts; rdpc.ColorDepth = (int)machine.ColorDepth; rdpc.Dock = DockStyle.Fill; } }
通過使用RemoteMachine參數實例化並進行遠程控制;
RemoteMachine mac = item.Tag as RemoteMachine; using (DesktopForm df = new DesktopForm(mac)) { df.ShowDialog(); }
2、進程、服務管理等(WMI方式,需要引人System.Management.dll類庫,以進程管理為例,ProcessInfo類包含的屬性信息可查詢MSDN,其他類似)
public partial class ProcessForm : Form, IRemote { private ManagementScope scope = null; private ManagementClass managementClass = null; private string path = null; public RemoteMachine Machine { get; set; } public ProcessForm(RemoteMachine machine) { InitializeComponent(); Text = string.Format("【進程】{0}", machine.DesktopName); this.Machine = machine; this.path = "\\\\" + this.Machine.Server + "\\root\\cimv2:Win32_Process"; this.managementClass = new ManagementClass(this.path); ConnectionOptions options = null; if (this.Machine.Server != "." && this.Machine.UserName != null && this.Machine.UserName.Length > 0) { options = new ConnectionOptions(); options.Username = this.Machine.UserName; options.Password = this.Machine.Password; //options.EnablePrivileges = true; //options.Impersonation = ImpersonationLevel.Impersonate; //options.Authority = "ntlmdomain:domain"; } this.scope = new ManagementScope("\\\\" + this.Machine.Server + "\\root\\cimv2", options); this.managementClass.Scope = this.scope; } private DataGridView dataGrid; private ContextMenuStrip contextMenu; private ProcessInfo[] processes; private void ProcessForm_Load(object sender, EventArgs e) { this.contextMenu = new ContextMenuStrip(); ToolStripItem item = this.contextMenu.Items.Add("停止"); item.Click += item_Click; this.dataGrid = new DataGridView() { Dock = DockStyle.Fill, ContextMenuStrip = this.contextMenu, SelectionMode = DataGridViewSelectionMode.FullRowSelect, AllowUserToAddRows = false, AllowUserToDeleteRows = false, ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize, ReadOnly = true, RowHeadersWidth = 21 }; this.Controls.Add(this.dataGrid); ReLoad(); } private void ReLoad() { this.dataGrid.DataSource = null; this.processes = null; if (Connect()) { processes = GetProcess(); DataTable table = ProcessInfo.ConvertTo(processes); BindData(table); } } private void item_Click(object sender, EventArgs e) { if (this.dataGrid.SelectedRows.Count == 1) { try { UInt32 processId = Convert.ToUInt32(this.dataGrid.SelectedRows[0].Cells[0].Value); string processName = this.dataGrid.SelectedRows[0].Cells[1].Value.ToString(); if (processName != null && MessageBox.Show(string.Format("是否停止\"{0}\"進程?", processName), "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { ProcessInfo process = Array.Find(processes, (pro) => { return pro.Name == processName && pro.ProcessId == processId; }); KillProcess(process); ReLoad(); } } catch (Exception ex) { MessageBox.Show(ex.Message, "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } } } public bool Connect() { try { scope.Connect(); } catch (Exception ex) { MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); } return scope.IsConnected; } public void Disconnect() { } public void BindData(DataTable table) { this.dataGrid.DataSource = table; } public ProcessInfo[] GetProcess() { ManagementObjectCollection queryCollection = this.managementClass.GetInstances(); List<ProcessInfo> processes = new List<ProcessInfo>(); foreach (ManagementObject m in queryCollection) { ProcessInfo process = new ProcessInfo(m); processes.Add(process); } return processes.ToArray(); } public void KillProcess(ProcessInfo process) { ObjectQuery query = new ObjectQuery(string.Format("select * from Win32_Process where ProcessId={0}", process.ProcessId)); ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); ManagementObjectCollection queryCollection = searcher.Get(); foreach (ManagementObject m in queryCollection) { string[] args = new string[] { "0" }; object obj = m.InvokeMethod("Terminate", args); Console.WriteLine(obj.ToString()); return; } } }
也可通過該工具查看本機進程,具體配置如下圖所示:
計算機名/地址以“.”代替,此時不需要驗證用戶名密碼,所以此時用戶名和密碼任意設置;
完成后點擊“功能”->“進程”->“localhost”查看進程信息
選中一行后鼠標右鍵點擊“停止”后通過調用KillProcess來終止該進程;
此處附上源碼