2
0

Add auto-update check and DDC/CI timeout fix
Some checks failed
Build and Release / build (push) Failing after 9h0m41s
Build / build (push) Has been cancelled

- Auto-update checker on startup via Gitea API
- Balloon notification when update available, click to download
- 5-second timeout on DDC/CI commands to prevent hangs
- Simplified version scheme to match release tags
- Workflow auto-updates version in csproj from tag

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-07 11:48:19 -05:00
parent b7597fd4d0
commit 526974da24
5 changed files with 205 additions and 31 deletions

View File

@@ -19,7 +19,7 @@ internal class ConsoleHelper
}
};
public static async Task<string> ExecuteCommand(string command)
public static async Task<string> ExecuteCommand(string command, int timeoutMs = 5000)
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
@@ -27,10 +27,19 @@ internal class ConsoleHelper
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = command;
p.Start();
var output = await p.StandardOutput.ReadToEndAsync();
await p.WaitForExitAsync();
return output;
using var cts = new CancellationTokenSource(timeoutMs);
try
{
var output = await p.StandardOutput.ReadToEndAsync(cts.Token);
await p.WaitForExitAsync(cts.Token);
return output;
}
catch (OperationCanceledException)
{
try { p.Kill(); } catch { }
return string.Empty;
}
}
public static async Task<string> CmdCommandAsync(params string[] cmds) =>
@@ -40,6 +49,11 @@ internal class ConsoleHelper
Command(cmdFileName, cmds);
public static async Task<string> CommandAsync(string fileName, params string[] cmds)
{
return await CommandAsync(fileName, 5000, cmds);
}
public static async Task<string> CommandAsync(string fileName, int timeoutMs, params string[] cmds)
{
var p = CreatProcess(fileName);
p.Start();
@@ -48,14 +62,24 @@ internal class ConsoleHelper
p.StandardInput.WriteLine(cmd);
}
p.StandardInput.WriteLine("exit");
var result = await p.StandardOutput.ReadToEndAsync();
var error = await p.StandardError.ReadToEndAsync();
if (!string.IsNullOrWhiteSpace(error))
result = result + "\r\n<Error Message>:\r\n" + error;
await p.WaitForExitAsync();
p.Close();
Debug.WriteLine(result);
return result;
using var cts = new CancellationTokenSource(timeoutMs);
try
{
var result = await p.StandardOutput.ReadToEndAsync(cts.Token);
var error = await p.StandardError.ReadToEndAsync(cts.Token);
if (!string.IsNullOrWhiteSpace(error))
result = result + "\r\n<Error Message>:\r\n" + error;
await p.WaitForExitAsync(cts.Token);
p.Close();
Debug.WriteLine(result);
return result;
}
catch (OperationCanceledException)
{
try { p.Kill(); } catch { }
return string.Empty;
}
}
public static string Command(string fileName, params string[] cmds)