diff --git a/src/Ytdlp.NET/Ytdlp/Ytdlp.Execute.cs b/src/Ytdlp.NET/Ytdlp/Ytdlp.Execute.cs index 792eafd..90637a7 100644 --- a/src/Ytdlp.NET/Ytdlp/Ytdlp.Execute.cs +++ b/src/Ytdlp.NET/Ytdlp/Ytdlp.Execute.cs @@ -33,17 +33,33 @@ public async Task ExecuteRawAsync(string arguments, var sanitizedArgs = string.Join(" ", tokens.Select(EscapeArgument)); var runner = CreateRunner(); + + // ── Wire runner events → Ytdlp public events ────────────────────────── + void OnErrorMessageHandler(object? s, string msg) => ErrorMessage?.Invoke(this, msg); + void OnCommandCompletedHandler(object? s, CommandCompletedEventArgs e) => CommandCompleted?.Invoke(this, e); + + runner.ErrorReceived += OnErrorMessageHandler; + runner.CommandCompleted += OnCommandCompletedHandler; + bool captureFullOutput = (onLineReceived == null); - return await runner.ExecuteAsync( - arguments: arguments, // Now we know it's "cleaner" - auth: _auth, - adobePass: _adobePass, - onLineReceived: onLineReceived, - ct: ct, - tuneProcess: tuneProcess, - captureFullOutput: captureFullOutput - ); + try + { + return await runner.ExecuteAsync( + arguments: arguments, // Now we know it's "cleaner" + auth: _auth, + adobePass: _adobePass, + onLineReceived: onLineReceived, + ct: ct, + tuneProcess: tuneProcess, + captureFullOutput: captureFullOutput + ); + } + finally + { + runner.ErrorReceived -= OnErrorMessageHandler; + runner.CommandCompleted -= OnCommandCompletedHandler; + } } /// diff --git a/src/Ytdlp.NET/Ytdlp/Ytdlp.Probe.cs b/src/Ytdlp.NET/Ytdlp/Ytdlp.Probe.cs index eda6842..9d8ea79 100644 --- a/src/Ytdlp.NET/Ytdlp/Ytdlp.Probe.cs +++ b/src/Ytdlp.NET/Ytdlp/Ytdlp.Probe.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; @@ -426,12 +427,21 @@ public async Task> GetSubtitlesAsync(string url, Cancellatio /// Returns if the process fails, is cancelled, or produces no output. /// private async Task RunProbeAsync(string arguments, CancellationToken ct = default, bool tuneProcess = true) - { + { + var runner = CreateRunner(); + + // ── Wire runner events → Ytdlp public events ────────────────────────── + void OnErrorMessageHandler(object? s, string msg) => ErrorMessage?.Invoke(this, msg); + void OnCommandCompletedHandler(object? s, CommandCompletedEventArgs e) => CommandCompleted?.Invoke(this, e); + + runner.ErrorReceived += OnErrorMessageHandler; + runner.CommandCompleted += OnCommandCompletedHandler; + try { ct.ThrowIfCancellationRequested(); - - var result = await CreateRunner().ExecuteAsync( + + var result = await runner.ExecuteAsync( arguments, onLineReceived: null, ct: ct, @@ -452,6 +462,11 @@ public async Task> GetSubtitlesAsync(string url, Cancellatio _logger.Log(LogType.Error, $"Probe failed: {ex.Message}"); return null; } + finally + { + runner.ErrorReceived -= OnErrorMessageHandler; + runner.CommandCompleted -= OnCommandCompletedHandler; + } }