用代码操控另一台电脑

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程序运行

用代码操控另一台电脑相关推荐

  1. 一套键鼠操控多台电脑--Mouse Without Borders 设置教程(转载)

    这篇文字是转载的,地址一套键鼠操控多台电脑–Mouse Without Borders 设置教程 一套键鼠控多机+文件秒传 微软神器<Mouse Without Borders>实战 你或 ...

  2. 一台电脑上配置多个git账号(gitee),向不同git线上仓库提交(命令行/TortoiseGit同时) 代码

    目录 1.一台电脑上实现与多个git在线仓库提交代码的实际场景 2.安装git TortoiseGit 生成SSH key 和 git的.ssh目录 创建并配置config文件 2.1.首先必须先安装 ...

  3. 《纽约客》特写Jeff Dean与Sanjay:谷歌唯二11级工程师,同一台电脑上写代码

    作者:<纽约客> James Somers 翻译:新浪科技 堆堆.李明 量子位 经授权转载 | 公众号 QbitAI 最近,<纽约客>杂志写了一篇长文,描述谷歌唯二11级工程师 ...

  4. 2 位谷歌顶级程序员的激荡人生,曾共用 1 台电脑写代码

    (给程序员的那些事加星标) 转自:机器之心(id:almosthuman2014),英文:纽约客 有很多人认为,Jeff Dean 的存在是谷歌如此强大的原因,谷歌员工都把谷歌搜索惊人的速度归功于他, ...

  5. pycharm + github实现多台电脑代码同步 (win系统)

    在windows上安装git 在Windows上使用Git,可以从Git官网直接下载安装程序 打开安装好的git bash,输入 ssh-keygen -t rsa -C "email&qu ...

  6. git多台电脑代码同步php,如何在多台电脑同步代码

    如果要将github作为你的远程代码托管仓库的话,我一直觉得还是使用git比较好,毕竟图形化的github desktop工具虽然使用起来容易,但是它功能简单,而且还可能会遇到中文乱码或者推送不上去的 ...

  7. 谷歌基情实录:和Jeff Dean在同一台电脑上写代码

    大数据文摘出品 编译:DonFJ.周家乐.李雷.小七.胡笳.jin.钱天培 单丝不成线,孤木不成林,浑身是铁也打不成几根钉子. 谷歌的伟大有一多半要归功于公司中亲密无间.协同工作的程序猿们!向伟大的猿 ...

  8. Jeff Dean的激荡人生:我和Sanjay在同一台电脑上写代码

    选自NewYorker,作者:James Somers,机器之心编译. 有很多人认为,Jeff Dean 的存在是谷歌如此强大的原因,谷歌员工都把谷歌搜索惊人的速度归功于他,他也是神经网络框架 Ten ...

  9. 两台计算机远程同步,如何在多台电脑同步代码

    如果要将github作为你的远程代码托管仓库的话,我一直觉得还是使用git比较好,毕竟图形化的github desktop工具虽然使用起来容易,但是它功能简单,而且还可能会遇到中文乱码或者推送不上去的 ...

最新文章

  1. BF法-字符模式匹配
  2. SQL SERVER 2008查看sql执行的时间
  3. .NET获取机器信息
  4. MySQL 存储引擎(MyISAM、InnoDB、NDBCluster)
  5. [转] 爱情的隐式马尔可夫模型(Love in the Hidden Markov Model)
  6. MOCTF-Web-文件包含
  7. junit4 单元测试框架_超越JUnit –测试框架的替代方案
  8. PHP大数据处理【转】
  9. ux和产品经理_为什么您的产品团队需要UX研究人员
  10. [jQuery基础] jQuery案例 -- 新浪微博
  11. Java thread.join
  12. 第二节:各种路由约束(动态路由、静态路由、组合路由、正则约束、命名空间约束、区域内路由)...
  13. 重庆大学计算机软件,重庆大学计算机辅助设计制造软件采购.DOC
  14. 接口各项性能测试指标
  15. 指数函数e^x和对数函数lnx 导数的求导过程
  16. 定位误差:基准位置公差、基准不重合误差
  17. 【求助】BEXCEL文件如何编辑?
  18. 管理学五(手机的危害,积累与责任、见闻杂谈)
  19. 洛谷 P2495 [SDOI2011]消耗战 虚树
  20. badboy和jmeter的下载安装及使用

热门文章

  1. 阿甘修理机器人cd_剑网3遗失的美好兑换推荐
  2. Android | 玩转AppBarLayout,设置scrollFlags滑动属性详解
  3. XXL-JOB入门教学
  4. html5做qq图标,qq图标代码
  5. [Emoji cheat sheet]写博客时会使用的Emoji可爱表情符号
  6. photoshop如何制作gif动画案例教程
  7. String数组转int数组的几种方法
  8. 刚跟朋友说完想买啥,某宝就给我推荐是咋回事?
  9. 侦探调查罪案---采用程序计算
  10. 如何将MP4视频文件转换成MP3音频格式