博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用代码操控另一台电脑
阅读量:6655 次
发布时间:2019-06-25

本文共 14348 字,大约阅读时间需要 47 分钟。

用代码操控另一台电脑

2015-03-11

 

做测试时,往往要配置测试机器,如果能用代码自动化实现,那是最好不过的。

据我所知,有三种方法[1]

  1. socket通讯即可完成
  2. 用psexec,(psexec是pstools中的一个程序)
  3. 用ManagementClass类

第1.2.中方法,都需要在被操控的机器上安装接受信息的程序。所以我采用第3.种方法,只需在一台机器上操控即可。

设计


使用ManagementClass类,只需知道被操控机器的用户名、密码即可,可对不在同一域中的机器进行操控

源代码:

设计思路:

  • step 1: create sub direcotry on remtoeMachine
  • step 2: create a share folder on remoteMachine
  • step 3: get full control of share folder
  • step 4: copy tool to share folder
  • step 5: start tool with argument to do special operation on remote machine

实现 


Class Library 'MachineControl.dll'

'MachineControl.dll':(引用到了System.Management.dll)是负责对被操控的机器进行控制的类,主要就两个类'WindowsShare', 'ExecuteCommand':

Class 'WindowsShare':该类负责在被操控的机器上创建share folder,设置权限

1 using System.Management;  2 using System.Security.Principal;  3 using System.Collections.Generic;  4 using System;  5   6 namespace MachineControl  7 {  8     public class WindowsShare  9     { 10         public enum MethodStatus : uint 11         { 12             Success = 0,     //Success             13             AccessDenied = 2,     //Access denied           14             UnknownFailure = 8,     //Unknown failure             15             InvalidName = 9,     //Invalid name            16             InvalidLevel = 10,     //Invalid level             17             InvalidParameter = 21,     //Invalid parameter        18             DuplicateShare = 22,     //Duplicate share            19             RedirectedPath = 23,     //Redirected path            20             UnknownDevice = 24,     //Unknown device or directory            21             NetNameNotFound = 25     //Net name not found      22         } 23         public enum ShareType : uint 24         { 25             DiskDrive = 0x0,     //Disk Drive            26             PrintQueue = 0x1,     //Print Queue         27             Device = 0x2,     //Device       28             IPC = 0x3,     //IPC            29             DiskDriveAdmin = 0x80000000,     //Disk Drive Admin      30             PrintQueueAdmin = 0x80000001,     //Print Queue Admin          31             DeviceAdmin = 0x80000002,     //Device Admin         32             IpcAdmin = 0x80000003     //IPC Admin        33         } 34         public enum AccessMaskTypes 35         { 36             FullControl = 2032127, Change = 1245631, 37             ReadOnly = 1179817 38         } 39         #region field and property 40         private ManagementObject _winShareObject; 41         private WindowsShare(ManagementObject obj) { _winShareObject = obj; } 42         public ManagementObject ManagementObject { get { return _winShareObject; } } 43         public uint AccessMask { get { return Convert.ToUInt32(_winShareObject["AccessMask"]); } }         44         public bool AllowMaximum { get { return Convert.ToBoolean(_winShareObject["AllowMaximum"]); } } 45         public string Caption{ get { return Convert.ToString(_winShareObject["Caption"]); } }         46         public string Description { get { return Convert.ToString(_winShareObject["Description"]); } } 47         public DateTime InstallDate { get { return Convert.ToDateTime(_winShareObject["InstallDate"]); } } 48         public uint MaximumAllowed 49         { 50             get { return Convert.ToUInt32(_winShareObject["MaximumAllowed"]); } 51         }        public string Name { get { return Convert.ToString(_winShareObject["Name"]); } }        public string Path { get { return Convert.ToString(_winShareObject["Path"]); } }        public string Status { get { return Convert.ToString(_winShareObject["Status"]); } }        public ShareType Type { get { return (ShareType)Convert.ToUInt32(_winShareObject["Type"]); } }        public MethodStatus Delete() { object result = _winShareObject.InvokeMethod("Delete", new object[] { }); uint r = Convert.ToUInt32(result); return (MethodStatus)r; } 52         #endregion 53         #region static method 54         public static MethodStatus Create(string path, string name, ShareType type, uint? maximumAllowed, string description, string password) 55         { 56             ManagementClass mc = new ManagementClass("Win32_Share"); 57             ManagementBaseObject shareParams = mc.GetMethodParameters("Create"); 58             shareParams["Path"] = path;  59             shareParams["Name"] = name; 60             shareParams["Type"] = (uint)type; 61             shareParams["Description"] = description; 62             if (maximumAllowed != null) 63                 shareParams["MaximumAllowed"] = maximumAllowed; 64             if (!String.IsNullOrEmpty(password)) 65                 shareParams["Password"] = password; 66             ManagementBaseObject result = mc.InvokeMethod("Create", shareParams, null); 67             return (MethodStatus)(result.Properties["ReturnValue"].Value); 68         } 69  70         public static MethodStatus CreateShareFolder(string FolderPath, string ShareName, ShareType type, string Description, string remoteMachine, string userName, string passWord) 71         { 72  73             ManagementClass mc = new ManagementClass(string.Format(@"\\{0}\root\cimv2:Win32_Share", remoteMachine)); 74             mc.Scope.Options.Username = userName; 75             mc.Scope.Options.Password = passWord; 76  77             // Get the parameter for the Create Method for the folder 78             ManagementBaseObject shareParams = mc.GetMethodParameters("Create"); 79             // Assigning the values to the parameters 80             shareParams["Description"] = Description; 81             shareParams["Name"] = ShareName; 82             shareParams["Path"] = FolderPath; 83             shareParams["Type"] = (int)type; 84             // Finally Invoke the Create Method to do the process 85             ManagementBaseObject result = mc.InvokeMethod("Create", shareParams, null); 86             return (MethodStatus)(result.Properties["ReturnValue"].Value); 87  88         } 89  90         public static IList
GetAllShareFolders(string remoteMachine, string userName, string passWord) 91 { 92 IList
result = new List
(); 93 ManagementClass mc = new ManagementClass(string.Format(@"\\{0}\root\cimv2:Win32_Share", remoteMachine)); 94 mc.Scope.Options.Username = userName; 95 mc.Scope.Options.Password = passWord; 96 97 ManagementObjectCollection moc = mc.GetInstances(); 98 99 foreach (ManagementObject mo in moc)100 {101 WindowsShare share = new WindowsShare(mo);102 result.Add(share);103 }104 return result;105 }106 107 public static IList
GetAllShares()108 {109 IList
result = new List
();110 ManagementClass mc = new ManagementClass("Win32_Share"); 111 ManagementObjectCollection moc = mc.GetInstances(); 112 foreach (ManagementObject mo in moc)113 {114 WindowsShare share = new WindowsShare(mo);115 result.Add(share);116 } 117 return result;118 }119 public static WindowsShare GetShareByName(string name)120 {121 name = name.ToUpper();122 IList
shares = GetAllShares();123 foreach (WindowsShare s in shares)124 if (s.Name.ToUpper() == name)125 return s; return null;126 }127 public static WindowsShare GetShareByName(string remoteMachine, string userName, string passWord,string name)128 {129 name = name.ToUpper();130 IList
shares = GetAllShareFolders(remoteMachine, userName, passWord);131 foreach (WindowsShare s in shares)132 if (s.Name.ToUpper() == name)133 return s; return null;134 }135 public static WindowsShare GetShareByPath(string path)136 {137 path = path.ToUpper();138 IList
shares = GetAllShares();139 foreach (WindowsShare s in shares)140 if (s.Path.ToUpper() == path)141 return s; return null;142 }143 #endregion144 #region method145 public MethodStatus SetPermission(string domain, string userName, AccessMaskTypes amtype)146 {147 NTAccount account = new NTAccount(domain, userName); 148 SecurityIdentifier sid = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));149 byte[] sidArray = new byte[sid.BinaryLength]; sid.GetBinaryForm(sidArray, 0);150 ManagementObject trustee = new ManagementClass(new ManagementPath("Win32_Trustee"), null);151 trustee["Domain"] = domain; 152 trustee["Name"] = userName; 153 trustee["SID"] = sidArray; 154 ManagementObject adminACE = new ManagementClass(new ManagementPath("Win32_Ace"), null); 155 adminACE["AccessMask"] = (int)amtype; adminACE["AceFlags"] = 3;156 adminACE["AceType"] = 0; 157 adminACE["Trustee"] = trustee; 158 ManagementObject secDescriptor = new ManagementClass(new ManagementPath("Win32_SecurityDescriptor"), null);159 secDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT 160 secDescriptor["DACL"] = new object[] { adminACE };161 object result = _winShareObject.InvokeMethod("SetShareInfo", new object[] 162 { Int32.MaxValue, this.Description, secDescriptor }); 163 uint r = Convert.ToUInt32(result); return (MethodStatus)r;164 }165 #endregion166 }167 }
View Code

Class 'ExecuteCommand' :该类负责在被操控的机器上执行cmd命令

1 using System.Management; 2 using System.Security.Principal; 3 using System.Collections.Generic; 4 using System; 5  6 namespace MachineControl 7 { 8     public class ExecuteCommand 9     {10         public static void Execute(string remoteMachine, string username, string password, string cmd)11         {12             ConnectionOptions connOptions = new ConnectionOptions13             {14                 Impersonation = ImpersonationLevel.Impersonate,15                 EnablePrivileges = true,16                 Username = username,17                 Password = password18             };19 20             ManagementScope scope = new ManagementScope(@"\\" + remoteMachine + @"\root\cimv2", connOptions);21             scope.Connect();22 23             ObjectGetOptions options = new ObjectGetOptions();24 25             // Getting the process class and the process startup class26             ManagementPath processClassPath = new ManagementPath("Win32_Process");27 28             ManagementClass processClass = new ManagementClass(scope, processClassPath, options);29 30             // Settings the parameters for the Create method in the process class31             ManagementBaseObject inArgs = processClass.GetMethodParameters("Create");32             inArgs["CommandLine"] = cmd;33 34             // Invoking the method35             ManagementBaseObject returnValue = processClass.InvokeMethod("Create", inArgs, null);36             if ((uint)(returnValue.Properties["ReturnValue"].Value) != 0)37                 throw new Exception("Folder might be already in share or unable to share the directory");38         }39     }40 }
View Code

Tool 'Tool.exe'

'Tool.exe':是要拷贝到被操控的机器上的工具,它带有参数,可根据不同参数的命令行进行操控

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5  6 namespace Tool 7 { 8     class Program 9     {10         static void Main(string[] args)11         {12             if (args.Length == 1)13             {14                 if (args[0] == @"/?")15                     Console.WriteLine("if arg = 'Creat', Create a txt file; if arg ='Delete', Delete the txt file.");16                 else if (args[0].ToUpper() == "CREATE")17                     System.IO.File.Create(@"c:\qm\CreateWithTool.txt");18                 else if (args[0].ToUpper() == "DELETE")19                     System.IO.File.Delete(@"c:\qm\CreateWithTool.txt");20             }21         }22     }23 }
View Code

Client 'Client.exe'

'Client.exe':是操控端代码

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Net; 6 using System.Net.Sockets; 7 using System.Threading; 8 using System.Management; 9 10 using MachineControl;11 12 namespace Client13 {14     class Program15     {16         static bool isConnected = false;17         static void Main(string[] args)18         {19             string shareFolderDirectory = @"c:\qm";20             string shareFolderName = "qm";21             string remoteMachine = "machineName";22             string remoteMachineUserName = @"yonghuming(inclue domain)";23             string remoteMachinePassWord = "password";24 25             string myMachineDomain = "yuming";26             string myMachineUserName = "yonghuming";27             string toolName = "Tool.exe";28             string cmdCreateFolder = string.Format(@"cmd /c md {0}", shareFolderDirectory);29             string cmdExecuteTool = string.Format(@"{0}\{1} {2}", shareFolderDirectory, toolName, "create");30 31             //step 1: create sub direcotry on remtoeMachine           32             ExecuteCommand.Execute(remoteMachine, remoteMachineUserName, remoteMachinePassWord, cmdCreateFolder);33 34             //step 2: create a share folder on remoteMachine35             WindowsShare.MethodStatus status = WindowsShare.CreateShareFolder(shareFolderDirectory, shareFolderName, WindowsShare.ShareType.DiskDrive, "ShareFolder", remoteMachine, remoteMachineUserName, remoteMachinePassWord);36             if (WindowsShare.MethodStatus.Success != status)37             {38                 Console.WriteLine(string.Format("Can't create shareFolder, the status is'{0}'.", status.ToString()));39             }40 41             WindowsShare ws = WindowsShare.GetShareByName(remoteMachine, remoteMachineUserName, remoteMachinePassWord, shareFolderName);42             //step 3: get full control of share folder43             ws.SetPermission(myMachineDomain, myMachineUserName, WindowsShare.AccessMaskTypes.FullControl);44 45             //step 4: copy tool to share folder46             System.IO.File.Copy(Environment.CurrentDirectory + @"\" + toolName, @"\\" + remoteMachine + @"\" + shareFolderName + @"\" + toolName);47 48             //step 5: start tool with argument to do special operation on remote machine49             ExecuteCommand.Execute(remoteMachine, remoteMachineUserName, remoteMachinePassWord, cmdExecuteTool);50         }51 52     }53 }
View Code

 

结果


执行到step 3: get full control of share folder时,

 

执行到step 5: start tool with argument to do special operation on remote machine时,'Tool.exe'会根据命令"c:\qm\Tool.exe create",创建‘CreateWithTool.txt’

 

参考:

[1]

转载于:https://www.cnblogs.com/Ming8006/p/4332076.html

你可能感兴趣的文章
The Commercial Open-Source Monitoring Landscape
查看>>
剑指offer:构建乘积数组
查看>>
C++ 的intialization list 和assignment
查看>>
mysqli
查看>>
字符串逆序输出
查看>>
Java对象及其引用 (1)
查看>>
spark中RDD和DataFrame之间的转换
查看>>
STAR法则
查看>>
兼容所有浏览器的复制方法
查看>>
iOS tableView自定义删除按钮
查看>>
2014年(实际上是2014界毕业生)互联网IT公司产品、技术类人员工资待遇
查看>>
List的foldLeft、foldRight、sort操作代码实战之Scala学习笔记-28
查看>>
svn revert说明
查看>>
plsql快捷开发
查看>>
移植x264到vs2008之二
查看>>
初探AIR for“.NET研究” Android开发
查看>>
(转)matlab与C混合编程之中级篇
查看>>
pip安装错误,用镜像
查看>>
如何在open xml excel 中存储自定义xml数据?
查看>>
301和302跳转的区别
查看>>