You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确关闭调用youtube-dl下载Twitch流的控制台程序

问题:终止youtube-dl进程后生成.part文件无法正常使用

按下控制台按键后,youtube-dl及ffmpeg进程被终止,但生成的文件为.part后缀,无法正常使用。预期应生成可用的.mp4文件,但未实现。

测试代码

string url = "https://www.twitch.tv/ricoy";
string outputPath = @"D:\ruta_del_archivo_salida.mp4";

ProcessStartInfo startInfo = new ProcessStartInfo
{
    FileName = "youtube-dl",
    Arguments = $"-f best -o \"{outputPath}\" \"{url}\"",
    //RedirectStandardOutput = true,
    UseShellExecute = false,
    CreateNoWindow = true
};

using (Process process = new Process())
{
    process.StartInfo = startInfo;
    process.Start();

    //var output = process.StandardOutput.ReadToEnd();
    //process.WaitForExit();

    Console.Read();
    KillProcessAndChildren(process.Id);
}

static void KillProcessAndChildren(int pid)
{
    // Cannot close 'system idle process'.
    if (pid == 0)
    {
        return;
    }
    ManagementObjectSearcher searcher = new ManagementObjectSearcher
            ("Select * From Win32_Process Where ParentProcessID=" + pid);
    ManagementObjectCollection moc = searcher.Get();
    foreach (ManagementObject mo in moc)
    {
        KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
    }
    try
    {
        Process proc = Process.GetProcessById(pid);
        proc.Kill();
    }
    catch (ArgumentException)
    {
        // Process already exited.
    }
}

解决方案

问题出在你直接强制杀死进程时,youtube-dl还没来得及完成文件收尾工作——它会先把下载内容写到临时的.part文件里,等下载完成后才会重命名为你指定的.mp4文件,强制终止会打断这个流程。

方案1:等待下载完成后自动退出

把代码中注释掉的process.WaitForExit();取消注释,同时删掉Console.Read();和KillProcessAndChildren(process.Id);。这样程序会自动等待youtube-dl完成下载,它会正常完成文件收尾,生成可用的.mp4文件。修改后的核心代码:

using (Process process = new Process())
{
    process.StartInfo = startInfo;
    process.Start();

    // 等待下载进程完成
    process.WaitForExit();
}

方案2:手动触发终止但保留可用文件

不要直接用Kill()强制终止,而是给youtube-dl发送正常的终止信号(比如Ctrl+C),让它有机会处理临时文件。可以通过Windows API实现:

首先添加API导入:

using System.Runtime.InteropServices;

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetConsoleCtrlHandler(IntPtr handlerRoutine, bool add);

然后替换原有的终止逻辑:

using (Process process = new Process())
{
    process.StartInfo = startInfo;
    process.Start();

    Console.Read();

    // 先禁用当前进程的Ctrl+C响应,避免自己被终止
    SetConsoleCtrlHandler(IntPtr.Zero, true);
    // 向目标进程组发送Ctrl+C信号
    GenerateConsoleCtrlEvent(0, (uint)process.Id);
    // 等待进程正常退出,完成文件收尾
    process.WaitForExit();
    // 恢复当前进程的Ctrl+C响应
    SetConsoleCtrlHandler(IntPtr.Zero, false);
}

这种方式下,youtube-dl收到终止信号后,会完成当前的写入操作,把.part文件重命名为目标.mp4后再退出,生成的文件就能正常使用了。


内容的提问来源于stack exchange,提问作者ElPavlillo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:30:30