winforms 在C#中运行外部进程和更新UI元素的问题

7cjasjjr  于 2023-08-07  发布在  C#
关注(0)|答案(1)|浏览(140)

我目前正在开发一个C#应用程序,需要使用Process.Start()运行一个外部进程,并根据该进程的输出更新UI元素。然而,我面临着一个奇怪的问题,即UI更新只发生一次,尽管该过程应该执行多次。

验证码:

private void pic()
{
    MessageBox.Show("just runs once?!");
    using (Process process = new Process())
    {
        process.StartInfo.FileName = "C:/Users/lenovo/Desktop/ffmpeg.exe";
        process.StartInfo.Arguments = $"-i {"C:/Users/lenovo/Desktop/New folder/video.mp4"} -vf \"select=eq(n\\,{master_frame})\" -vframes 1";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.Start();
        pictureBox1.Invoke((MethodInvoker)(() =>
        {
            pictureBox1.Image?.Dispose();
            pictureBox1.Image = Image.FromFile("output.jpg");
        }));
    }
}

private async void panel1_MouseUp(object sender, MouseEventArgs e)
{
    move = true;
    await Task.Run(() =>
    {
        while (move)
        {
            pic();
            MessageBox.Show(master_frame.ToString()); // Runs multiple times one by one
            master_frame++;
        }
    });
}

字符串

问题:

我面临的问题是pic()方法只执行一次,它执行一个外部进程并更新一个PictureBox控件。但是,我希望它根据panel1_MouseUp事件处理程序中的while循环运行多次。

预期行为:

我希望在while循环中重复调用pic()方法,每次都执行外部进程,并使用输出图像更新PictureBox。此外,我希望显示master_frame变量的消息框显示多次,每次迭代都递增其值。

实际行为:

目前,pic()方法只运行一次,PictureBox控件的UI更新也只发生一次。但是,消息框正确地显示了多次,表明循环正在按预期执行。

附加信息:

我已经通过在应用程序外部手动运行外部进程来验证外部进程是否正确执行。代码中使用的文件路径是正确的,并且所需的文件存在于指定的位置。我还确认了释放鼠标按钮时panel1_MouseUp事件正确触发。如果您能提供任何关于为什么pic()方法没有被多次调用以及为什么UI更新没有在每次迭代中发生的帮助或见解,我们将不胜感激。谢谢你,谢谢

8yoxcaq7

8yoxcaq71#

我在pictureBox1.Image = Image.FromFile("output.jpg")这行找不到任何逻辑。
当你不写完整的路径到文件像"output.jpg",然后应用程序需要它从工作目录,在你的情况下,这是你的程序的exe文件。如果它没有给予你一个错误,那么有一个名为"output.jpg"的文件。我认为你的问题的原因是你的过程没有改变它,结果是你的pictureBox 1在每次迭代中都显示相同的图像。确保为ffmpeg编写了正确的命令。在控制台中尝试它,如果您得到正确的结果,您将确保问题不在命令中。我不知道如何使用ffmpeg,但你的行“-i {videoPath} -vf“select=eq(n\,{master_frame})”-vframes 1”似乎无法正常工作。我在控制台中单独尝试了它,得到了错误“必须指定至少一个输出文件”。
PS C:\Users\User\Downloads\ffmpeg-2023-06-27-git-9b6d191a66-full_build\bin> .\ffmpeg.exe -i C:\Users\User\Downloads\Youre_God_damn_right.mp4 -vf "select=eq(n\,{5})" -vframes 1
必须至少指定一个输出文件
我也可以建议你尝试遵循架构(不确定while循环是否可以停止)

public partial class TestForm : Form
{
    public TestForm()
    {
        InitializeComponent();
        RunProcessOnce();
    }

    private int master_frame = 0;

    private string ffmpegPath = @"C:\Users\User\Downloads\ffmpeg-2023-06-27-git-9b6d191a66-full_build\bin\ffmpeg.exe";
    private string videoPath = @"C:\Users\User\Downloads\Youre_God_damn_right.mp4";
    private void RunProcessOnce()
    {
        using (var process = new Process())
        {
            process.StartInfo.FileName = ffmpegPath;
            process.StartInfo.Arguments = $"-i {videoPath} -vf \"select=eq(n\\,{master_frame})\" -vframes 1";
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.CreateNoWindow = true;
            process.Start();
        }
    }

    private Task? ImageUpdateTask;
    private bool loop = false;

    //button start
    private void button1_Click(object sender, EventArgs e)
    {
        loop = true;
        ImageUpdateTask = Task.Run(() =>
        {
            while (loop)
            {
                RunProcessOnce();
                pictureBox1.Invoke((MethodInvoker)(() =>
                {
                    pictureBox1.Image?.Dispose();
                    pictureBox1.Image = Image.FromFile("output.jpg");
                }));
                MessageBox.Show(master_frame.ToString()); // Runs multiple times one by one
                master_frame++;
            }
        });
    }
}

字符串

相关问题