65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 WMI 在 C# 中创建远程进程

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (12投票s)

2008年11月21日

CPOL

3分钟阅读

viewsIcon

188527

downloadIcon

7841

使用 WMI 在 C# 中创建远程进程

引言

对于那些希望通过 WMI 远程执行进程的人来说,这是一个简单的介绍。我相信这篇文章绝不是 Code Project 上的第一篇此类文章,我知道可能还有很多更好的文章。撇开所有这些不谈,我仍然相信这可能对那些刚进入 .NET 世界并正在寻找简单解决方案来远程执行进程的人有所帮助。让我们开始吧。

背景

这并非我个人构思并撰写本文。实际上,我遇到了一个问题,我试图使用 WMI 来远程执行进程,并且遇到了很多困难。经过一些试验和错误以及大量的 Google 搜索,我提出了这个使用 WMI 执行远程进程的原型。这个原型已经在我的硬盘上躺了一段时间了。今天我突然发现了一些时间,想与 The Code Project 社区分享一下。

Using the Code

如果您已经下载了示例代码,您一定已经注意到这是一个简单的命令行应用程序。这里唯一值得一提的技巧是批处理文件的使用。所以,我在这里做的是,获取远程服务器名称,然后创建一个如下所示的批处理文件

sBatFile = @"\\" + remoteMachine + "file://admin$//process.bat">\\admin$\\process.bat; 

因此,如果使用此变量创建文件(当您拥有服务器的管理员访问权限时),该文件将创建在远程服务器的 Windows 目录中。

接下来,程序接收要执行的远程命令并写入此文件。

有趣的部分来了。一旦我们在远程服务器上以 BAT 文件的形式获得了我们的命令,使用 WMI 就会将批处理文件作为新进程在该服务器上执行。这解决了在远程服务器上执行代码的目的。

//
// Any source code blocks look like this
//
if (remoteMachine != string.Empty) 
 sBatFile = @"\\" + remoteMachine + "\\admin$\\process.bat"; 
else 
 Console.WriteLine("Invalid Machine name");  

if (File.Exists(sBatFile)) 
 File.Delete(sBatFile); 
StreamWriter sw = new StreamWriter(sBatFile); 
string _cmd = "DIR > \\\\" + remoteMachine + "\\admin$\\output.txt"; 
Console.Write("Enter the remote Command 
	<eg : Notepad.exe, Dir, Shutdown - r, etc..> : ");
_cmd = Console.ReadLine();
if ( _cmd.Trim()==string.Empty ) 
 Console.WriteLine("No command entered using default command for test :" + _cmd);  

sw.WriteLine(_cmd);
sw.Close(); 

//
//WMI section
//    
ManagemenConnectionOptions connOptions = new ConnectionOptions();
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.EnablePrivileges = true;
tScope manScope = new ManagementScope
	(String.Format(@"\\{0}\ROOT\CIMV2", remoteMachine), connOptions);
manScope.Connect();
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
ManagementClass processClass = new ManagementClass
	(manScope, managementPath, objectGetOptions);
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["CommandLine"] = sBatFile; 
ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
Console.WriteLine("Creation of the process returned: " + outParams["returnValue"]);
Console.WriteLine("Process ID: " + outParams["processId"]); 

有趣的部分是 WMI 部分。

  1. 创建了 ConnectionOptions 对象,并将模拟设置为 Impersonate。这将确保使用当前用户的凭据在远程机器上执行进程。
  2. 通过传递根和 ConnectionOptions 对象来创建了 ManagementScope 对象。 Connect() 实际上建立了与远程机器的连接。
  3. 通过传递 ManagementScope, ManagementPath 对象,创建了类型为 ManagementClass ProcessClass 对象。
  4. processClass 对象上调用了 InvokeMethod 。这实际上通过将 bat 文件名作为参数启动新的 Win32 进程,在远程服务器上创建了新进程。

看起来我已经写了足够的内容来发布这篇文章了:-)。老实说,这甚至还不到我想告诉你的关于 WMI 的 10%。希望我能尝试写一篇关于 WMI 的更好的文章,以便清楚地说明 C# 中的 WMI 对象模型。希望很快就能做到。

关注点

一旦我成功执行了我的第一个 WMI 程序,我就能够理解 WMI 的原始力量。希望这也会引起您对 WMI 的一些兴趣。

历史

  • 2008 年 11 月 21 日:最初发布
© . All rights reserved.