34

一部のC#コードは、引数を使用してPowerShellスクリプトを実行します。Powershellスクリプト内ですべてが正常であったかどうかを知るために、Powershellからリターンコードと文字列を取得したいと思います。

それを行う正しい方法は何ですか-PowershellとC#の両方で

パワーシェル

# Powershell script
# --- Do stuff here ---
# Return an int and a string - how?
# In c# I would do something like this, if this was a method:

# class ReturnInfo
# {
#    public int ReturnCode;
#    public string ReturnText;
# }

# return new ReturnInfo(){ReturnCode =1, ReturnText = "whatever"};

C#

void RunPowershellScript(string scriptFile, List<string> parameters)
    {
        
        RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();

        using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration))
        {
            runspace.Open();
            RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
            Pipeline pipeline = runspace.CreatePipeline();
            Command scriptCommand = new Command(scriptFile);
            Collection<CommandParameter> commandParameters = new Collection<CommandParameter>();
            foreach (string scriptParameter in parameters)
            {
                CommandParameter commandParm = new CommandParameter(null, scriptParameter);
                commandParameters.Add(commandParm);
                scriptCommand.Parameters.Add(commandParm);
            }
            pipeline.Commands.Add(scriptCommand);
            Collection<PSObject> psObjects;
            psObjects = pipeline.Invoke();

            //What to do here?
            //ReturnInfo returnInfo = pipeline.DoMagic();

        }
    }

  class ReturnInfo
  {
      public int ReturnCode;
      public string ReturnText;
  }

Write-Outputを使用し、「最後の2つのpsObjectは私が探している値です」などの規則に依存することで、これを行うことができましたが、非常に簡単に壊れてしまいます。

4

3 に答える 3

35

PowerShellスクリプトでは、必要に応じてハッシュテーブルを作成できます。

[hashtable]$Return = @{} 
$Return.ReturnCode = [int]1 
$Return.ReturnString = [string]"All Done!" 
Return $Return 

C#コードでは、この方法でPsobjectを処理します

 ReturnInfo ri = new ReturnInfo();
 foreach (PSObject p in psObjects)
 {
   Hashtable ht = p.ImmediateBaseObject as Hashtable;
   ri.ReturnCode = (int)ht["ReturnCode"];
   ri.ReturnText = (string)ht["ReturnString"];
 } 

//Do what you want with ri object.

PowerShellv2.0のKeithHillコメントのようにPsCustomobjectを使用する場合:

PowerShellスクリプト:

$return = new-object psobject -property @{ReturnCode=1;ReturnString="all done"}
$return

c#コード:

ReturnInfo ri = new ReturnInfo();
foreach (PSObject p in psObjects)
   {
     ri.ReturnCode = (int)p.Properties["ReturnCode"].Value;
     ri.ReturnText = (string)p.Properties["ReturnString"].Value;
   }
于 2012-04-11T15:08:52.457 に答える
6

CB。の答えは、小さな変更を加えるだけでうまくいきました。(C#とPowerShellに関して)これがどこにも投稿されていないので、投稿したいと思いました。

PowerShellスクリプトで、ハッシュテーブルを作成し、その中に2つの値(ブール値と整数)を格納してから、それをPSObjectに変換しました。

$Obj = @{}

if($RoundedResults -ilt $Threshold)
{
    $Obj.bool = $true
    $Obj.value = $RoundedResults
}
else
{
    $Obj.bool = $false
    $Obj.value = $RoundedResults
}

$ResultObj = (New-Object PSObject -Property $Obj)

return $ResultObj

そして、C#コードでは、CBと同じことをしました。Convert.ToStringしましたが、値を正常に戻すために使用する必要がありました:

ReturnInfo ri = new ReturnInfo();
foreach (PSObject p in psObjects)
   {
     ri.ReturnCode = Convert.ToBoolean(p.Properties["ReturnCode"].Value;)
     ri.ReturnText = Convert.ToString(p.Properties["ReturnString"].Value;)
   }

私は次のStackOverflowの投稿を介してこれに対する答えを見つけました: https ://stackoverflow.com/a/5577500

キーレン・ジョンストーンが言うところ:

(double)valueではなくConvert.ToDouble(value)を使用します。それはオブジェクトを取り、あなたが要求したすべてのタイプをサポートします!:)

于 2014-10-02T16:58:14.257 に答える
1

うわー、いい質問だ!頭のてっぺんからショットを撮ります...

2つの間でデータを渡すために使用する構造を表すクラスをC#で設計できます。PSスクリプトでは、XmlWriterを使用してXML応答を作成し、を使用Write-outputしてXML文字列を吐き出すことができます。

C#側では、標準の出力応答をキャプチャし、XMLを新しい応答クラスに逆シリアル化してから、結果を処理します。XML応答以外のものをstdoutに書き出すことはできないことに注意してください。そうしないと、クラスに逆シリアル化できなくなります。

于 2012-04-11T13:14:55.467 に答える