using System.IO; using System.IO.Compression; using System.Net.Http; using System.Net.Http.Headers; using System.Text.Json; using System.Windows; namespace TeamsNetphoneLink.WPF { /// /// Interaktionslogik für ExceptionWindow.xaml /// public partial class UpdateWindow : Window { private bool _updateRunning = false; private string _currentVersion; private string _latestVersion; public UpdateWindow(string currentVersion, string latestVersion) { InitializeComponent(); // Step 1: Check for updates _currentVersion = currentVersion; _latestVersion = latestVersion; TitleText.Text = $"Es ist ein Update von {currentVersion} auf {latestVersion} verfügbar"; LoadReleaseNotesAsync(); } private async void LoadReleaseNotesAsync() { try { var notes = await GetReleaseNotes(); Dispatcher.Invoke(() => { ReleaseNotesTextBox.Text = notes; }); } catch (Exception ex) { Dispatcher.Invoke(() => { ReleaseNotesTextBox.Text = $"Failed to load release notes: {ex.Message}"; }); } } // Button zum Schließen private void CloseButton_Click(object sender, RoutedEventArgs e) { this.Close(); } // Button zum Updaten private void UpdateButton_Click(object sender, RoutedEventArgs e) { this._updateRunning = true; this.UpdateButton.IsEnabled = false; this.CloseButton.IsEnabled = false; _ = UpdateApplicationAsync(); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (this._updateRunning) { e.Cancel = true; } } private void StartUpdater(string tempExtractPath) { string appPath = AppDomain.CurrentDomain.BaseDirectory; string updaterPathEXE = Path.Combine(appPath, "TeamsNetphoneLinkUpdater.exe"); string updaterPathDLL = Path.Combine(appPath, "TeamsNetphoneLinkUpdater.dll"); string newUpdaterPathEXE = Path.Combine(tempExtractPath, "TeamsNetphoneLinkUpdater.exe"); string newUpdaterPathDLL = Path.Combine(tempExtractPath, "TeamsNetphoneLinkUpdater.dll"); //Replace the updater if it exists in the new release if (File.Exists(newUpdaterPathEXE)) { File.Copy(newUpdaterPathEXE, updaterPathEXE, true); } if (File.Exists(newUpdaterPathDLL)) { File.Copy(newUpdaterPathDLL, updaterPathDLL, true); } System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo.FileName = updaterPathEXE; p.StartInfo.ArgumentList.Add(appPath); p.StartInfo.ArgumentList.Add(tempExtractPath); p.StartInfo.UseShellExecute = true; // This will start the process in a new shell p.Start(); // Exit the application Application.Current.Shutdown(); } private static void UnzipRelease(string zipPath, string extractPath) { ZipFile.ExtractToDirectory(zipPath, extractPath); } private async Task UpdateApplicationAsync() { try { if (_latestVersion != _currentVersion) { UpdateProgress.Value = 0; // Step 2: Download the new release string downloadUrl = $"https://git.jan.sx/krjan02/TeamsNetphoneLink/releases/download/latest/TeamsNetphoneLink{_latestVersion}.zip"; var tempZipPath = Path.GetTempFileName(); tempZipPath = tempZipPath + ".TEAMSNETPHONEUPDATE"; Console.WriteLine(tempZipPath); await DownloadReleaseAsync(downloadUrl, tempZipPath); // Step 3: Unzip the release var tempExtractPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + "TEAMSNETPHONEUPDATE"); Directory.CreateDirectory(tempExtractPath); UnzipRelease(tempZipPath, tempExtractPath); File.Delete(tempZipPath); // Step 4: Replace Updater.exe and run the updater StartUpdater(tempExtractPath); } } catch (Exception ex) { Dispatcher.Invoke(() => ProgressStatusText.Text = $"Error: {ex.Message}"); } } private async Task GetReleaseNotes() { string apiUrl = $"https://git.jan.sx/api/v1/repos/krjan02/TeamsNetphoneLink/releases/tags/{_latestVersion}"; using (HttpClient client = new HttpClient()) { // Send a GET request to the Gitea API HttpResponseMessage response = await client.GetAsync(apiUrl); response.EnsureSuccessStatusCode(); // Parse the JSON response string jsonResponse = await response.Content.ReadAsStringAsync(); using (JsonDocument doc = JsonDocument.Parse(jsonResponse)) { JsonElement root = doc.RootElement; JsonElement body = root.GetProperty("body"); return body.GetString(); } } } private async Task GetFileSize() { string apiUrl = $"https://git.jan.sx/api/v1/repos/krjan02/TeamsNetphoneLink/releases/tags/{_latestVersion}"; using (HttpClient client = new HttpClient()) { // Send a GET request to the Gitea API HttpResponseMessage response = await client.GetAsync(apiUrl); response.EnsureSuccessStatusCode(); // Parse the JSON response string jsonResponse = await response.Content.ReadAsStringAsync(); using (JsonDocument doc = JsonDocument.Parse(jsonResponse)) { JsonElement root = doc.RootElement; JsonElement assets = root.GetProperty("assets"); // Iterate through the assets to find the file foreach (JsonElement asset in assets.EnumerateArray()) { string name = asset.GetProperty("name").GetString(); if (name == $"TeamsNetphoneLink{_latestVersion}.zip") { long size = asset.GetProperty("size").GetInt64(); return size; } } } } return -1; } private async Task DownloadReleaseAsync(string downloadUrl, string destinationPath) { using (var client = new HttpClient()) { var response = await client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); var totalBytes = await GetFileSize(); var downloadedBytes = 0L; var buffer = new byte[8192]; using (var fileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None)) using (var stream = await response.Content.ReadAsStreamAsync()) { int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { fileStream.Write(buffer, 0, bytesRead); downloadedBytes += bytesRead; // Update progress in the UI Dispatcher.Invoke(() => { ProgressStatusText.Text = $"Update wird heruntergeladen... ({downloadedBytes/1000}kB/{totalBytes/1000}kB)"; UpdateProgress.Value = (double)downloadedBytes / totalBytes * 100; //StatusText.Text = $"Downloading... {DownloadProgress.Value:F2}%"; }); } } } } } }