2016-02-29 61 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!"; 
      } 
     } 
    } 
}