2016-02-29 57 views
0

我需要使用PowerShell执行验证,并根据结果在WPF应用程序中执行操作。我知道我可以从PowerShell修改TextBlocks,但是当我尝试从PowerShell中修改WPF变量的值时,什么都不会发生。WPF和PowerShell - 将变量从PS传递到C#或修改值

下面是一个例子。

MainWindow.xaml:

<Window x:Class="Test.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:Test" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="74,76,0,0" TextWrapping="Wrap" Text="false" VerticalAlignment="Top" Height="177" Width="371"/> 
    </Grid> 
</Window> 

MainWindow.xaml.cs:

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Management.Automation; 
using System.Management.Automation.Runspaces; 
using System.Text.RegularExpressions; 
using System.IO; 

namespace Test 
{ 
    public partial class MainWindow : Window 
    { 
     private bool exists = false; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      // Setup PowerShell Environment 
      Runspace runSpace = RunspaceFactory.CreateRunspace(); 
      runSpace.ThreadOptions = PSThreadOptions.UseCurrentThread; 
      runSpace.Open(); 
      runSpace.SessionStateProxy.SetVariable("exists", exists); 
      PowerShell ps = PowerShell.Create(); 
      ps.Runspace = runSpace; 
      string check = "$exists = true"; 
      ps.AddScript(check); 
      // Execute 
      ps.Invoke(); 
      runSpace.Close(); 

      if (exists == true) 
      { 
       textBlock.Text = "It is true!"; 
      } 
     } 
    } 
} 

我如何修改C#/ WPF变量在PowerShell中做一些验证后?这甚至有可能吗?

我不想为临时变量创建随机文本块/标签/文本框。

+0

TRUE;在PowerShell中没有任何特殊含义,尝试改变'check'字符串' “$存在= $真”' –

+0

试了一下。不起作用。 也试过使用:[System.Boolean] :: true,它也不起作用。 感谢您的答复。 –

+1

运行脚本以获取值后使用'GetVariable'。 –

回答

0

首先,exists是一个值类型。要从PowerShell更新exists,您必须通过引用PowerShell脚本来传递它。我可能是错的,但这似乎不太可能。即使有可能我仍然不会推荐它。像这样操纵状态似乎很糟糕。我认为更好的方法是将要验证的数据传递给PowerShell脚本,并将验证结果返回给C#。您可以根据该结果在C#中修改您的变量状态。

这里是你的代码稍加修改的版本,我在LinqPad跑与输出:

var exists = true; 
Runspace runSpace = RunspaceFactory.CreateRunspace(); 
runSpace.ThreadOptions = PSThreadOptions.UseCurrentThread; 
runSpace.Open(); 

PowerShell ps = PowerShell.Create(); 
ps.Runspace = runSpace; 
string validation = @" 
    # Perform some validation. 

    # For the purposes of this demonstration I am going to pretend 
    # that validation failed and set 'result' to false. 
    $result = $false 

    # Return 'result' 
    $result 
"; 
ps.AddScript(validation); 

// Write the state of `exists` to the console before invoking PowerShell. 
Console.WriteLine("exists: " + exists.ToString()); 

// Execute 
var result = ps.Invoke(); 

// Update exists based on the result of the validation. 
exists = bool.Parse(result[0].ToString()); 

// Or you can use 'GetVariable' to get the result back from PowerShell: 
// exists = bool.Parse(runSpace.SessionStateProxy.GetVariable("result").ToString()); 

// Write the state to the console after invoking PowerShell. 
Console.WriteLine("exists: " + exists.ToString()); 

,这里是写入到控制台结果:

存在:真
存在:False

+0

这听起来像个好主意。但是,它给了我的信息: “错误\t CS1061 \t'bool'没有包含'Dump'的定义,也没有扩展方法'Dump'接受类型'bool'的第一个参数可以找到(你是否缺少使用指令或程序集引用?)“ –

+1

@JorgePabón'Dump'是一种LinqPad扩展方法。我只是假设每个人都熟悉LinqPad现在的真棒;)我更新了我的示例,更好地演示了我正在描述的内容并删除了'Dump'。 –

+0

试过这样...有一个奇怪的编译错误。 –

0

使用Mike的建议我设法从PS获得变量,甚至不必映射它。像这样:

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Management.Automation; 
using System.Management.Automation.Runspaces; 
using System.Text.RegularExpressions; 
using System.IO; 

namespace Test 
{ 
    public partial class MainWindow : Window 
    { 
     public bool itExists = false; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      // Setup PowerShell Environment 
      Runspace runSpace = RunspaceFactory.CreateRunspace(); 
      runSpace.ThreadOptions = PSThreadOptions.UseCurrentThread; 
      runSpace.Open(); 
      PowerShell ps = PowerShell.Create(); 
      ps.Runspace = runSpace; 
      string check = "$itExists = $TRUE"; 
      ps.AddScript(check); 
      // Execute 
      ps.Invoke(); 

      var result = runSpace.SessionStateProxy.PSVariable.GetValue("itExists").ToString(); 

      runSpace.Close(); 

      itExists = result.Equals("True"); 

      if (itExists) 
      { 
       textBlock.Text = "It is true!"; 
      } 
     } 
    } 
}