@chromize

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

processで生成したファイルにアクセスできない。

解決したいこと

C#のProcessでffmpegを起動し、生成した動画がプログラム起動中はロックがかかってアクセスできない。

WPFで動画編集ツールをつくっています。
記事を投稿する機能の実装中にエラーが発生しました。
解決方法を教えて下さい。

発生している問題・エラー

エンコード処理の高速化のため、マルチスレッドで分割した動画を生成し
その後結合する処理があります。
分割した動画を結合しようとすると以下のようなエラーが返ってきて
終了してしまいます。

C:/output/tempVideo1.mp4'
stderr=C:\output\list.txt: Invalid data found when processing input

また、対象の動画をエクスプローラから開こうとすると
0xc00d36c4というエラーが返ってきます。

このことからProcesが終了後もファイルを握ったままになっているのではないかと予想しました。
プログラム終了後は普通に動画が視聴できます。

該当するソースコード

            //プロセスの生成
            {
            Process proc = new Process();
            proc.StartInfo.FileName = @"C:\ffmpeg\bin\ffmpeg.exe";
            proc.StartInfo.Arguments = //ffmpegのコマンド;

            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardInput = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.ErrorDialog = true;

            using (var ctoken = new CancellationTokenSource())
            {
                proc.EnableRaisingEvents = true;
                // コールバックの設定
                proc.OutputDataReceived += (sender, ev) =>
                {
                    Console.WriteLine($"stdout={ev.Data}");
                };
                proc.ErrorDataReceived += (sender, ev) =>
                {
                    Console.WriteLine($"stderr={ev.Data}");
                };
                proc.Exited += (sender, ev) =>
                {
                    //ctoken.Cancel();
                };
                proc.Disposed += (sender, ev) =>
                {
                    Console.WriteLine($"disposed");
                };
            }
            try
            {
                //プロセススタート
                proc.Start();

                // 出力読出し開始
                proc.BeginErrorReadLine();
                proc.BeginOutputReadLine();

                for (int i = 0; i < 10000; i++)
                {
                    //ループ処理()
                }

                //出力読出し終了
                proc.CancelErrorRead();
                proc.CancelOutputRead();
                
                //プロセス終了
                proc.Dispose();
                proc.Refresh();
                proc.Close();
                proc = new Process();
                }

上記処理をTask.Runで呼び出しています。

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。
procをcloseだけだと足りないのでは?と思いdispose/refresh/instanceの再宣言等も行いましたが変化はありませんでした。

0 likes

1Answer

プロセスを意図して終了させる場合は process.Kill() を使用します。
もし、勝手にプロセスが終了するのであれば、WaitForExit で終了を待機します。

Close はリソースの解放用のメソッドでプロセスを止めるものではないです。
(Dispose 内でも呼ばれます。)

1Like

Your answer might help someone💌