用代码操控另一台电脑 软件测试 测试机配置

用代码操控另一台电脑

2015-03-11

设计

实现

结果

 

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

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

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

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

设计


返回

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

源代码:ControlRemoteMachine.zip

设计思路:

  • 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<WindowsShare> GetAllShareFolders(string remoteMachine, string userName, string passWord)
 91         {
 92             IList<WindowsShare> result = new List<WindowsShare>();
 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<WindowsShare> GetAllShares()
108         {
109             IList<WindowsShare> result = new List<WindowsShare>();
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<WindowsShare> 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<WindowsShare> 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<WindowsShare> shares = GetAllShares();
139             foreach (WindowsShare s in shares)
140                 if (s.Path.ToUpper() == path)
141                     return s; return null;
142         }
143         #endregion
144         #region method
145         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         #endregion
166     }
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 ConnectionOptions
13             {
14                 Impersonation = ImpersonationLevel.Impersonate,
15                 EnablePrivileges = true,
16                 Username = username,
17                 Password = password
18             };
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 class
26             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 class
31             ManagementBaseObject inArgs = processClass.GetMethodParameters("Create");
32             inArgs["CommandLine"] = cmd;
33 
34             // Invoking the method
35             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 Client
13 {
14     class Program
15     {
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 remoteMachine
35             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 folder
43             ws.SetPermission(myMachineDomain, myMachineUserName, WindowsShare.AccessMaskTypes.FullControl);
44 
45             //step 4: copy tool to share folder
46             System.IO.File.Copy(Environment.CurrentDirectory + @"\" + toolName, @"\\" + remoteMachine + @"\" + shareFolderName + @"\" + toolName);
47 
48             //step 5: start tool with argument to do special operation on remote machine
49             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] 局域网内一台机器控制另一台机器上的.EXE程序运行

版权声明:本文为Ming8006原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Ming8006/p/4332076.html