c#でPowerShellスクリプトを実行する方法

c# でPowerShellスクリプトを実行する方法を紹介します。

この記事での実行方法は、System.Management.Automationを使用する方法ではなく、Powershell.exe を呼び出して実行します。

実行するソースコード


//using System.Diagnostics;

/// <summary>
/// PowerShellスクリプトを実行する
/// </summary>
/// <param name=ps1FilePath>PowerShellスクリプト(*.ps1)ファイル名</param>
/// <param name=args>引数リスト</param>
/// <param name=stdOut>標準出力</param>
/// <param name=stdErr>標準エラー出力</param>
/// <param name=exitCode>終了コード</param>
public static void ExecPSProcess(string ps1FilePath, List<PowerShellArgs> args, out string stdOut, out string stdErr, out int exitCode)
{
    stdOut = "";
    stdErr = "";
    exitCode = 0;

    try
    {
        string cmdStr = "";
        cmdStr = $"-File {ps1FilePath} ";
        foreach(var item in args)
        {
            cmdStr = cmdStr + $"-{item.argName} {item.argValue}";
        }

        System.Diagnostics.Process process = new System.Diagnostics.Process();
        ProcessStartInfo processStartInfo = new ProcessStartInfo(powershell.exe, cmdStr);

        processStartInfo.CreateNoWindow = true;
        processStartInfo.UseShellExecute = false;

        processStartInfo.RedirectStandardOutput = true;
        processStartInfo.RedirectStandardError = true;

        process = System.Diagnostics.Process.Start(processStartInfo);
        process.WaitForExit();

        stdOut = process.StandardOutput.ReadToEnd();
        stdErr = process.StandardError.ReadToEnd();
        exitCode = process.ExitCode;

        process.Close();

    }
    catch
    {
        throw;
    }
}

以下のコードで、PowerShell.exe の後に続くコマンド文字列を作成します。 -FileスイッチでPowerShellスクリプトファイルパスを指定しています。 スクリプトの引数が格納されているargsforeachでループして、引数を指定するコマンド文字列を作成します。 PowerShellArgsクラスは後述しています。

    string cmdStr = ;
    cmdStr = $-File {ps1FilePath} ;
    foreach(var item in args)
    {
        cmdStr = cmdStr + $"-{item.argName} {item.argValue}";
    }

プロセスオブジェクトを作成して、コマンド文字列を指定します。

    System.Diagnostics.Process process = new System.Diagnostics.Process();
    ProcessStartInfo processStartInfo = new ProcessStartInfo(powershell.exe, cmdStr);

ウィンドウの非表示などを指定します。 プロセスを開始し、標準出力、標準エラー出力、終了コードを取得します。

    processStartInfo.CreateNoWindow = true;
    processStartInfo.UseShellExecute = false;

    processStartInfo.RedirectStandardOutput = true;
    processStartInfo.RedirectStandardError = true;

    process = System.Diagnostics.Process.Start(processStartInfo);
    process.WaitForExit();

    stdOut = process.StandardOutput.ReadToEnd();
    stdErr = process.StandardError.ReadToEnd();
    exitCode = process.ExitCode;

    process.Close();

引数を指定するクラスPowerShellArgsクラス

PowerShellスクリプトに渡す引数は以下のクラスを用いて説明します。 上記で説明した関数では、複数指定されることを考慮し、リスト型にして渡しています。

    /// <summary>
    /// PowerShellスクリプト呼び出し引数クラス
    /// </summary>
    public class PowerShellArgs
    {
        /// <summary>
        /// 引数名称
        /// </summary>
        /// <value></value>
        public string argName {get; set;}

        /// <summary>
        /// 値
        /// </summary>
        /// <value></value>
        public string argValue {get; set;}
    }

実行方法

例えば、以下のようなPowerShellスクリプトを実行するとします。 引数OpenFileNameで指定したファイルを、Visual Studio Codeで開くという動作をします。

Param($OpenFileName)

code $OpenFileName

これを実行するためのExecPSProcess関数を呼び出すコードは以下になります。

string ps1FilePath = @"D:\OpenFileWithCode.ps1";
PowerShellArgs args = new PowerShellArgs();
args.argName = OpenFileName;
args.argValue = @"D:\docs.md";

List<PowerShellArgs> argsList  = new List<PowerShellArgs>();
argsList.Add(args);

string stdout = ;
string stderr = ;
int exitCode = 0;

ExecPSProcess(ps1FilePath, argsList, out stdout, out stderr, out exitCode);

Console.WriteLine(exitCode);
Console.WriteLine(stdout);
Console.WriteLine(stderr);

実行するPowerShellスクリプトファイルパスを指定し、引数を定義します。 引数はリスト型のPowerShellArgsオブジェクトに格納します。

string ps1FilePath = @"D:\OpenFileWithCode.ps1";
PowerShellArgs args = new PowerShellArgs();
args.argName = OpenFileName;
args.argValue = @"D:\docs.md";

List<PowerShellArgs> argsList  = new List<PowerShellArgs>();
argsList.Add(args);

標準出力、標準エラー出力、終了コードを取得する変数を定義し、ExecPSProcessを呼び出します。

string stdout = "";
string stderr = "";
int exitCode = 0;

ExecPSProcess(ps1FilePath, argsList, out stdout, out stderr, out exitCode);

Console.WriteLine(exitCode);
Console.WriteLine(stdout);
Console.WriteLine(stderr);

おすすめ本 c#コードレシピ集

c#コードレシピ集は、「文字列を大文字あるいは小文字に変換したい」や「Taskをキャンセルしたい」など逆引き的にコードの書き方を調べられるレシピ集です。

2021年8月に発売された本で、全部で385個のレシピが収録されています。

ジャンルは日付処理やLINQ、並列処理と非同期処理など幅広く記載されています。

Kindle対応ですので、まずはサンプルをダウンロードして何が書かれているか確認してはいかがでしょうか。

コメント

タイトルとURLをコピーしました