2015-09-08 76 views
4

我想將C#對象傳遞給PowerShell,以便我可以爲主UI提供狀態更新。我在這方面看到過幾篇文章,但他們似乎都沒有幫助解決我的問題。將變量從C#傳遞到PowerShell不起作用

Runspace runspace = RunspaceFactory.CreateRunspace(); 
runspace.ThreadOptions = PSThreadOptions.UseCurrentThread; 
runspace.Open(); 

runspace.SessionStateProxy.SetVariable("LogReporter", this.LogReporter); 

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

StringBuilder builder = new StringBuilder(); 
Collection<PSObject> objects = pipeline.Invoke(); 

而在PowerShell腳本我想訪問LogReporter(基本類型:System.Windows.Window)像下面

$RunningInstances= @(Get-ChildItem | Where-Object { $_.InstanceStatus.ToString() -eq "Running" }) 
$LogReporter.ReportProgress($RunningInstances.Count.ToString() + " instances running currently...") 

但是出現在片段中,我的一切是

You cannot call a method on a null-valued expression. 

    at CallSite.Target(Closure , CallSite , Object , Object) 
    at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1) 
    at System.Management.Automation.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame) 
    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) 

我試圖列出$ LogReporter變量的所有成員,但結果是

No object has been specified to the get-member cmdlet. 

這意味着,$LogReporter變量是null。現在的問題是:爲什麼以及如何解決這個問題?

請注意,代碼被略微簡化以提高可讀性,但顯示了必要和失敗的部分。

關於發生什麼問題的任何想法?我需要以某種方式註冊我的LogReporter類型嗎?

我感謝任何幫助!

解決方案

我有一個錯字,並在C#代碼中的變量不匹配一個在PowerShell腳本。我的代碼示例在這裏沒有任何問題。

回答

1

這是完整的工作示例,向您顯示問題。問題不在LogReporter變量中,而是在「$ _。InstanceStatus.ToString()」部分。 InstanceStatus在你的情況下爲null,並且ToString()拋出上面的異常。在下面的代碼中,我剛剛刪除了ToString()調用,並且您看到來自LogReporter的「0個實例正在運行」消息。

class Program 
{ 
    private static void Main(string[] args) { 
     new ScriptRunner().Run(); 
     Console.ReadKey(); 
    }   
} 

class ScriptRunner { 
    public ScriptRunner() { 
     this.LogReporter = new LogReporter(); 
    } 

    public void Run() { 
     Runspace runspace = RunspaceFactory.CreateRunspace(); 
     runspace.ThreadOptions = PSThreadOptions.UseCurrentThread; 
     runspace.Open(); 



     Pipeline pipeline = runspace.CreatePipeline(); 
     pipeline.Commands.AddScript("[email protected](Get-ChildItem | Where-Object {$_.InstanceStatus -eq \"Running\"})"); 
     runspace.SessionStateProxy.SetVariable("LogReporter", this.LogReporter); 
     pipeline.Commands.AddScript("$LogReporter.ReportProgress($RunningInstances.Count.ToString()+\" instances running currently...\")"); 

     StringBuilder builder = new StringBuilder(); 
     Collection<PSObject> objects = pipeline.Invoke();    
    } 

    public LogReporter LogReporter { get; private set; } 

} 

class LogReporter 
{ 
    public void ReportProgress(string msg) 
    { 
     Console.WriteLine(msg); 
    } 
} 
+0

感謝您的回答,但'InstanceStatus'不爲null。子項是BizTalk對象,「InstanceStatus」是枚舉。如果我不嘗試記錄東西,這些腳本按預期工作,但我沒有任何進度消息。 – Scoregraphic

+0

這很奇怪,因爲上面的代碼已經過測試。如果您只執行以下腳本,會發生什麼情況:「$ LogReporter.ReportProgress(\」0個實例正在運行... \「)」「?所以,如果你完全跳過$ RunningInstances = ...行。 – Evk

+0

如果上面的示例適用於您,也是有趣的。 – Evk

相關問題