見出し画像

【C#&Python】C#からファイル名を引数として与えてPythonを呼び出すときの不具合対応

【状況】C#からPythonを外部プロセス起動で呼び出し,フルパス表記したファイル名を引数にして渡して動作させたい.しかし,意図通りに引数が渡らなかった.
【対処】ファイル名に空白が入っていると,引数が分割されしまうことが原因であることが分かったので,引数の渡し方を修正.なお,引数を渡して外部プログラムの呼出しをするとき,仕組み上,他の言語の組み合わせでも同じ不具合が起きるはず.

不具合が発生したコード

変数に格納されたスクリプト名(pythonScriptPath)とファイル名(videoFileName)をprocess.StartInfo.Argumentsに代入しています.全体を1セットの「””」で囲んだため,Pythonに渡されたとき,ファイル名の空白でファイル名が分割されて,別々の引数になっていました.
なお,ここではついでに,ファイルパスの区切り文字も「\」(C#)と「/」(Python)で異なるので変換しています.

// 引数の設定
string pythonScriptPath = "test.py"; // 実行するスクリプト(パスを含めてよい)
string videoFileName = "test.mp4";   // 渡すファイル名(パスを含めてよい)

// 外部プロセスを起動してPythonスクリプトを実行
using (Process process = new Process())
{
    // ファイルパスの区切り文字を `/` に置き換える
    pythonScriptPath = pythonScriptPath.Replace("\\", "/");
    videoFileName = videoFileName.Replace("\\", "/");

    process.StartInfo.FileName = "python";            // Pythonの実行ファイルのパス
    process.StartInfo.Arguments = $"{pythonScriptPath} {videoFileName} "; 
    process.StartInfo.UseShellExecute = false;        // シェルを使用しない
    process.StartInfo.RedirectStandardOutput = false; // 標準出力をリダイレクト
    process.StartInfo.CreateNoWindow = false;         // ウィンドウを作成しない

    // プロセスを開始
    process.Start();

    // プロセスの終了を待機
    process.WaitForExit();
}

修正したコード

process.StartInfo.Arguments = $"\"{pythonScriptPath}\" \"{videoFileName }\"";  // 実行するスクリプトと引数を指定

各引数を「”」で囲むことで対応(”の前に\が必要).
(他人が作った)長いファイルパスの中に空白が一つあるのを見つけるのに時間がかかったけど,これでよし♪


この記事が気に入ったらサポートをしてみませんか?