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

如何从 C# 运行 PowerShell 脚本

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (55投票s)

2007年3月31日

CPOL

3分钟阅读

viewsIcon

1016000

downloadIcon

24558

一篇关于从 C# 程序中嵌入和/或启动 PowerShell 脚本的文章。

Screenshot - HowToRunPowerShell_Screen.png

引言

本文包含一个简单的示例,说明如何将 PowerShell 脚本添加到 C# 程序中。用电影中的话来说:“Shell 的力量迫使你!”

背景

随着 2006 年 11 月 Windows PowerShell 1.0 的发布,我们终于有了一个强大的 Windows 命令行 Shell,它甚至可以与常见的 Unix/Linux Shell(如 cshbash)相媲美甚至超越它们。原因是 PowerShell 命令可以读取和写入对象,而不是只能处理文本字符串的传统 Shell。由于 PowerShell 在 .NET 平台上运行,因此使用的对象是 .NET 对象,这使其成为 .NET 程序的理想脚本语言。

必备组件

在编译示例代码之前,您需要准备一些东西。首先,当然,您必须安装 PowerShell 本身,您可以在以下位置找到它:PowerShell 主页。示例程序还引用了一些标准 PowerShell 安装未包含的程序集,因此您必须通过安装 Windows SDK for Windows Server 2008 and .NET Framework 3.5 来获取这些程序集。不用担心:即使后者名称中包含“Server 2008”,它也会安装在 Vista 和 XP 上。

Using the Code

要将 PowerShell 脚本添加到您的程序,您首先必须添加对 System.Management.Automation 程序集的引用。SDK 将此程序集安装在 C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0 目录中。

然后,您必须添加以下 'using' 语句来导入所需的类型

using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

以下代码块显示了执行所有繁重工作的 RunScript 方法。它接受脚本文本,执行它,并将结果作为字符串返回。

private string RunScript(string scriptText)
{
    // create Powershell runspace

    Runspace runspace = RunspaceFactory.CreateRunspace();

    // open it

    runspace.Open();

    // create a pipeline and feed it the script text

    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript(scriptText);

    // add an extra command to transform the script
    // output objects into nicely formatted strings

    // remove this line to get the actual objects
    // that the script returns. For example, the script

    // "Get-Process" returns a collection
    // of System.Diagnostics.Process instances.

    pipeline.Commands.Add("Out-String");

    // execute the script

    Collection<psobject /> results = pipeline.Invoke();

    // close the runspace

    runspace.Close();

    // convert the script result into a single string

    StringBuilder stringBuilder = new StringBuilder();
    foreach (PSObject obj in results)
    {
        stringBuilder.AppendLine(obj.ToString());
    }

    return stringBuilder.ToString();
}

如何让脚本与您的程序交互

在使用 pipeline.Invoke() 调用执行脚本之前,可以通过使用 runspace.SessionStateProxy.SetVariable("someName", someObject) 方法将程序的对象公开给脚本。这将创建一个脚本可以访问的命名变量(获取/设置属性,甚至调用方法)。例如,假设我们将示例的主窗体通过添加如下的 SetVariable() 调用公开给脚本

...
// open it

runspace.Open();
runspace.SessionStateProxy.SetVariable("DemoForm", this);
....

然后,以下脚本将打印窗口的标题

$DemoForm.Text

以下脚本将显示窗口的所有属性和方法

$DemoForm | Get-Member

但是请注意,脚本对您的对象的所有调用都将来自另一个线程上下文,因为 pipeline.Invoke() 似乎启动了自己的工作线程。这意味着您公开的对象必须是线程安全的。

关注点

作为一个额外的功能,我添加了将脚本拖放到表单上的能力,这样您就不必一直将 PowerShell 脚本复制粘贴到文本框中。

有关 PowerShell 的更多信息

历史

  • 2007 年 4 月 1 日:首次发布
  • 2007 年 4 月 4 日:小更新
  • 2008 年 8 月 28 日:修复了 SDK 的链接和我的第二篇 powershell 文章的链接
© . All rights reserved.