远程执行程序的.NET工具

在许多IT环境中,可能需要从一台计算机远程执行安装在另一台服务器上的程序。这通常涉及到一些特定的应用程序或工具,它们可能只在特定的服务器上可用。本文将介绍如何使用.NET创建一个工具,以便从客户端计算机远程执行这些程序。

准备工作

在开始之前,需要确保客户端计算机使用的域账户已经添加到远程服务器的“本地用户和组”中的管理员组中。此外,远程服务器至少需要运行Windows XP Pro、Server 2003或更新版本的Windows操作系统,并且需要安装.NET2.0或更高版本。

创建.NET工具

目标是创建一个.NET可执行文件,称为“Process”,它将允许在远程服务器上运行现有的非托管应用程序。这个过程涉及到编写一个批处理文件,该文件能够在客户端运行一些命令行应用程序,但其中一些程序仅安装在远程服务器上。

.NET Framework中的Process类是一个非常强大的工具,它允许启动和管理外部进程。为了掌握这个类,需要了解一些基本的技术。

下面是一个示例,展示了如何在名为"CO007-PL-0025"的网络系统上运行RunRemote.exe。Process.exe被复制到CO007-PL-0025并使用RunRemote.exe远程启动的服务来执行。Process.exe接受命令行参数,其中第一个参数是要运行的exe的名称,其余参数是应用于exe的参数。

Process.exe cmd.exe /C "dir \"C:\*.*\""

在这个例子中,Process运行cmd.exe,并带有参数:/C表示运行指定的命令然后终止,dir是cmd shell命令,用于显示文件列表,"C:\*.*"是文件路径。任何包含空格的参数都必须用引号括起来,否则引号是可选的。

Process.cs代码非常简洁,但当与RunRemote.exe一起使用时非常强大。只需要引用System.dll(版本2.0),并且需要使用以下四个命名空间:

using System; using System.Diagnostics; using System.IO; using System.Threading;

以下是源代码的其余部分:

namespace ProcessCmd { class Program { static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Purpose: Use with RunRemote to shell execute any remote exe"); Console.WriteLine("Usage: RunRemote <\\server> Process [arg1 arg2 ...]"); System.Environment.ExitCode = 1; return; } Process p = new Process(); p.StartInfo.FileName = args[0]; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = false; int nArgs = args.Length; if (nArgs > 1) p.StartInfo.Arguments = args[1]; for (int i = 2; i < nArgs; ++i) { p.StartInfo.Arguments = String.Concat(p.StartInfo.Arguments, " ", args[i]); } p.Start(); StreamReader so = p.StandardOutput; while (!p.HasExited) { Thread.Sleep(100); if (!so.EndOfStream) { Console.WriteLine(so.ReadLine()); } } Console.WriteLine(p.StandardOutput.ReadToEnd()); Console.Write("\nReturn value = "); Console.WriteLine(p.ExitCode); Console.Write("\n"); if (!p.StandardError.EndOfStream) { Console.WriteLine("StdError: " + p.StandardError.ReadToEnd()); Console.Write("\n"); } if (p.ExitCode == 0) Console.WriteLine(String.Concat("Completed: ", p.StartInfo.FileName, " ", p.StartInfo.Arguments)); Console.Write("\n"); System.Environment.ExitCode = p.ExitCode; } } }

代码的第一部分检查命令行参数是否满足要求。如果不满足,将设置退出错误代码并返回。下一部分设置System.Diagnostics.Process类与ProcessStartInfo属性。FileName设置要启动的应用程序(在arg[0]中找到)。UseShellExecute设置为false以启用标准输出和错误流的重定向。RedirectStandardOutput和RedirectStandardError允许通过Process类StandardOutput流重定向标准输出和错误流。CreateNoWindow默认为false,需要允许Ctrl+c来终止进程。Arguments属性将剩余的命令行参数附加到此属性。然后启动由FileName指向的进程。如果需要,系统路径环境变量将用于查找exe。

在进程运行时,从标准输出读取行并使用Console.WriteLine()写出。Thread.Sleep(100)防止“忙等待”循环状态。Process处理exe输出的方式是为了将输出发送回客户端系统的RunRemote。一旦启动的进程退出,任何标准错误中的数据将被输出,最终结果状态消息将被写出。

关于在远程机器上推送和运行.NET代码

正如可能已经猜到的,这个项目在很大程度上依赖于Jim Wiese的项目,可以在这里找到:Push and Run.NET。这是没有对源代码进行任何修改就可以为所用的少数项目之一。如果想获得源代码,可以从“Push and Run…”文章中获得。

软件防火墙

如果计算机不在域中,或者每台机器上都有软件防火墙,那么这可能会非常困难。必须打开TCP 135上的DCOM端口等。以下是一些关于启用防火墙设置以启动远程服务的文章链接:

  • 通过Windows防火墙连接
  • 保护远程WMI连接

在撰写本文时,能够在两个Windows 7(Ultimate/Pro)系统上的标准工作组网络设置中使其工作。需要在每个系统上都有一个具有管理员权限的用户,并且用户名和密码相同。使用域用户帐户在服务器上工作非常容易。当然,需要访问一个在服务器上具有本地管理员权限的帐户,并且两个系统将默认使用相同的帐户。

没有在带有XP Pro的家庭网络上测试过,但认为它会工作。不认为XP Home会工作。当尝试时,admin$共享被阻止了。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485