用代码操控另一台电脑

用代码操控另一台电脑

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‘是负责对被操控的机器进行控制的类,主要就两个类‘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 }

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 }

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 }

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 = "jiqmming";
22             string remoteMachineUserName = @"yonghuming(include domain)";
23             string remoteMachinePassWord = "mima";
24
25             string myMachineDomain = "yu";
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 }

结果



返回

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

时间: 2024-08-08 13:16:52

用代码操控另一台电脑的相关文章

安卓手机屏幕投射到电脑以及一台电脑控制多台手机技术原理浅析

奥创软件研究院推出的奥创微群控让越来越多的人了解到了电脑控制手机的操作.自奥创软件研究院首家发布电脑批量控制手机的解决方案以来,有很多人开始探讨电脑控制手机技术在实际工作中的应用. 由于市场太大,仅靠奥创软件研究院一家也是做不过来的,现在将手机屏幕投射到到电脑的技术原理,以及一台电脑批量控制多台手机的技术(即所谓的手机反响控制)简单的给大家介绍下,在此抛砖引玉,希望能给大家一些思路上的指导. 说到安卓手机的屏幕投射,就不得不说安卓的adb,ADB的全称为Android Debug Bridge这

【转】同一台电脑关于多个SSH KEY管理

原文链接 http://yijiebuyi.com/blog/f18d38eb7cfee860c117d629fdb16faf.html 使用环境:关于同一台电脑LInux系统下使用多个SSH key 切换使用(或者多用户使用ssh提交代码) 要求,可以创建不同的 PUBLIC KEY ,根据下面步骤设置. (1)比如有aaa,bbb,ccc 三个帐号需要生成不同的 PUBLIC KEY $ ssh-keygen -t rsa Generating public/private rsa key 

去除win8.1这台电脑中的6个库文件夹

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace,备份之后删除 win8.1这台电脑中的6个库文件夹感觉很碍眼,去掉以后把教程分享给大家.教程开始:win+R运行,regedit定位到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace

Ubuntu12和13版本连接ios7设备会出现循环提示“是否信任这台电脑”

Ubuntu12和13版本连接ios7设备会出现循环提示“是否信任这台电脑”,这一问题在ubuntu14.10得到了解决. 以下是ubuntu12.04解决这一问题的方法: 所有方法的实质都是将libimobiledevice这个库升级到1.1.6版本,由于这一版本是非稳定版本,所以机器上默认安装的都是1.1.4稳定版本. 1.网上很多人说可以使用加一个ppa的源,然后update+upgrade的方法进行,但是通常给出的ppa源都会404 notfound.但是这里留下一些ppa源: sudo

Mac下一台电脑管理多个SSH KEY(转)

一.关于ssh是什么?http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html 二.需求:一台电脑上(Mac os)管理多个ssh key,可以任意切换,达到多用户(账号)使用不同ssh提交代码.以下利用gerrit和github账号来做例子. 1)生成ssh key ssh-keygen -t rsa -C "[email protected]" 若一路回车(密码可以不写),这样只会在~/.ssh/ 目录下生成 id_r

ESXI和vsphere的安装配置-实现一台电脑硬件虚拟化为两台

本篇文章包含以下几个部分: 1EXSI软件和vSphere软件的安装 2在vSphere上安装虚拟系统 3对虚拟系统通过配置实现硬件虚拟化,实现硬件直通 1.EXSI安装 通过网上下载EXSI ISO镜像和Vsphere安装软件,选择一台没有安装系统的电脑通过u盘制作启动盘安装EXSI底层系统,安装过程很容易,安装成功后系统界面如下图所示,然后在该见面按下F2进行网络设置,通过IP Configuration选项来设置静态IP,以免IP变动了以后无法正常工作.记住目前的用户以及密码还有设置好的静

如何在同一台电脑使用不同的账号提交到同一个github仓库

最近这段时间使用github,有时在公司办公,想要用git提交代码到自己的github仓库,提交是显示的作者是自己在公司的账户,而不是自己的github账户,这就相当于提交到github的代码不是自己本人提交的,是其他人提交的. 现在的情况是这样的:在公司我们也是使用git来管理代码,我们公司内部有自己的git仓库(B),提交代码时用的账户就是公司的oa账号(A).而我自己有时候在家里做开发的时候,就是用自己注册github账户(C)提交代码到自己账户下的github仓库(D).现在有时候在公司

限制在同一台电脑上只允许有一个用户登录系统

在web应用系统中,出于安全性考虑,经常需要对同一客户端登录的用户数量和一个客户同时在多个客户端登陆进行限制.具体一点就是: 1.在同一台电脑上一次只允许有一个用户登录系统,2.一个用户在同一时间只允许在一个客户端登录. 我最近做的一个系统就遇到了这样的问题,本来系统已经开发完成了,但是安全测评没有通过,就是因为没有做这两个限制.怎么来做这样的限制呢?我在网上找了很久,发现问这个问题的人很多,但是没有找到特别清楚的答案.后来自己摸索着,看了一些书,终于找到解决办法了. 要解决这个问题实际上不难,

怎样在同一台电脑使用不同的账号提交到同一个github仓库

近期这段时间使用github.有时在公司办公,想要用git提交代码到自己的github仓库,提交是显示的作者是自己在公司的账户.而不是自己的github账户.这就相当于提交到github的代码不是自己本人提交的,是其它人提交的. 如今的情况是这种:在公司我们也是使用git来管理代码.我们公司内部有自己的git仓库(B).提交代码时用的账户就是公司的oa账号(A). 而我自己有时候在家里做开发的时候.就是用自己注冊github账户(C)提交代码到自己账户下的github仓库(D). 如今有时候在公