|
1 | 1 | using System; |
| 2 | +using System.Diagnostics; |
2 | 3 | using System.IO; |
3 | 4 | using System.Linq; |
| 5 | +using System.Net.Http; |
4 | 6 | using System.Runtime.Versioning; |
5 | 7 | using System.Threading.Tasks; |
6 | 8 | using AvaloniaControls.ControlServices; |
@@ -254,12 +256,10 @@ private bool CleanDirectory(string path, TimeSpan? timeout = null) |
254 | 256 |
|
255 | 257 | if (newerGitHubRelease != null) |
256 | 258 | { |
257 | | - if (OperatingSystem.IsLinux()) |
258 | | - { |
259 | | - return (newerGitHubRelease.Url, |
260 | | - newerGitHubRelease.Asset.FirstOrDefault(x => x.Url.ToLower().EndsWith(".appimage"))?.Url); |
261 | | - } |
262 | | - return (newerGitHubRelease.Url, null); |
| 259 | + var downloadUrl = OperatingSystem.IsLinux() |
| 260 | + ? newerGitHubRelease.Asset.FirstOrDefault(x => x.Url.ToLower().EndsWith(".appimage"))?.Url |
| 261 | + : newerGitHubRelease.Asset.FirstOrDefault(x => x.Url.ToLower().EndsWith(".exe"))?.Url; |
| 262 | + return (newerGitHubRelease.Url, downloadUrl); |
263 | 263 | } |
264 | 264 |
|
265 | 265 | return null; |
@@ -296,6 +296,72 @@ public void IgnoreFutureUpdates() |
296 | 296 | settingsService.SaveSettings(); |
297 | 297 | } |
298 | 298 |
|
| 299 | + public async Task<string?> InstallWindowsUpdate(string url) |
| 300 | + { |
| 301 | + var filename = Path.GetFileName(new Uri(url).AbsolutePath); |
| 302 | + var localPath = Path.Combine(Path.GetTempPath(), filename); |
| 303 | + |
| 304 | + logger.LogInformation("Downloading {Url} to {LocalPath}", url, localPath); |
| 305 | + |
| 306 | + var response = await DownloadFileAsyncAttempt(url, localPath); |
| 307 | + |
| 308 | + if (!response.Item1) |
| 309 | + { |
| 310 | + logger.LogInformation("Download failed: {Error}", response.Item2); |
| 311 | + return response.Item2; |
| 312 | + } |
| 313 | + |
| 314 | + try |
| 315 | + { |
| 316 | + logger.LogInformation("Launching setup file"); |
| 317 | + |
| 318 | + var psi = new ProcessStartInfo |
| 319 | + { |
| 320 | + FileName = localPath, |
| 321 | + UseShellExecute = true, |
| 322 | + RedirectStandardOutput = false, |
| 323 | + RedirectStandardError = false, |
| 324 | + RedirectStandardInput = false, |
| 325 | + CreateNoWindow = true |
| 326 | + }; |
| 327 | + |
| 328 | + Process.Start(psi); |
| 329 | + return null; |
| 330 | + } |
| 331 | + catch (Exception e) |
| 332 | + { |
| 333 | + logger.LogError(e, "Failed to start setup file"); |
| 334 | + return "Failed to start setup file"; |
| 335 | + } |
| 336 | + } |
| 337 | + |
| 338 | + private async Task<(bool, string?)> DownloadFileAsyncAttempt(string url, string target, int attemptNumber = 0, int totalAttempts = 3) |
| 339 | + { |
| 340 | + |
| 341 | + using var httpClient = new HttpClient(); |
| 342 | + |
| 343 | + try |
| 344 | + { |
| 345 | + await using var downloadStream = await httpClient.GetStreamAsync(url); |
| 346 | + await using var fileStream = new FileStream(target, FileMode.Create); |
| 347 | + await downloadStream.CopyToAsync(fileStream); |
| 348 | + return (true, null); |
| 349 | + } |
| 350 | + catch (Exception ex) |
| 351 | + { |
| 352 | + logger.LogError(ex, "Download failed"); |
| 353 | + if (attemptNumber < totalAttempts) |
| 354 | + { |
| 355 | + await Task.Delay(TimeSpan.FromSeconds(attemptNumber)); |
| 356 | + return await DownloadFileAsyncAttempt(url, target, attemptNumber + 1, totalAttempts); |
| 357 | + } |
| 358 | + else |
| 359 | + { |
| 360 | + return (false, $"Download failed: {ex.Message}"); |
| 361 | + } |
| 362 | + } |
| 363 | + } |
| 364 | + |
299 | 365 | private async Task CleanUpFolders() |
300 | 366 | { |
301 | 367 | await ITaskService.Run(() => |
|
0 commit comments