From 743dbe417eb6b0cba5ded72bf9552476046b4ca6 Mon Sep 17 00:00:00 2001 From: Philipp Date: Wed, 10 May 2023 07:21:54 +0200 Subject: [PATCH] Added option to set WPF Window or Windows Form as owner of all dialogs initiated by AutoUpdater. (#617) This fixes #584. --- AutoUpdater.NET/AutoUpdater.NET.csproj | 2 +- AutoUpdater.NET/AutoUpdater.cs | 40 ++++++++++++++----- AutoUpdater.NET/DownloadUpdateDialog.cs | 2 +- AutoUpdater.NET/UpdateForm.cs | 4 +- AutoUpdater.NET/Wpf32Window.cs | 16 ++++++++ .../build/Autoupdater.NET.Official.nuspec | 10 ++--- AutoUpdaterTest/AutoUpdaterTest.csproj | 4 +- AutoUpdaterTest/MainWindow.xaml | 1 + AutoUpdaterTest/MainWindow.xaml.cs | 3 ++ README.md | 10 +++++ ZipExtractor/FormMain.cs | 4 +- appveyor.yml | 4 +- 12 files changed, 76 insertions(+), 24 deletions(-) create mode 100644 AutoUpdater.NET/Wpf32Window.cs diff --git a/AutoUpdater.NET/AutoUpdater.NET.csproj b/AutoUpdater.NET/AutoUpdater.NET.csproj index 34f0d4e..8b58a03 100644 --- a/AutoUpdater.NET/AutoUpdater.NET.csproj +++ b/AutoUpdater.NET/AutoUpdater.NET.csproj @@ -51,6 +51,6 @@ - + \ No newline at end of file diff --git a/AutoUpdater.NET/AutoUpdater.cs b/AutoUpdater.NET/AutoUpdater.cs index 11a4658..3077f83 100644 --- a/AutoUpdater.NET/AutoUpdater.cs +++ b/AutoUpdater.NET/AutoUpdater.cs @@ -1,17 +1,20 @@ using System; using System.ComponentModel; using System.Diagnostics; -using System.Drawing; using System.Globalization; using System.IO; using System.Net; using System.Net.Cache; using System.Reflection; using System.Threading; +using System.Windows; using System.Windows.Forms; using System.Xml; using System.Xml.Serialization; using AutoUpdaterDotNET.Properties; +using Application = System.Windows.Forms.Application; +using MessageBox = System.Windows.Forms.MessageBox; +using Size = System.Drawing.Size; using Timer = System.Timers.Timer; namespace AutoUpdaterDotNET; @@ -86,6 +89,8 @@ public static class AutoUpdater private static bool _isWinFormsApplication; + private static IWin32Window _owner; + private static Timer _remindLaterTimer; internal static Uri BaseUri; @@ -243,6 +248,20 @@ public static class AutoUpdater /// public static event ParseUpdateInfoHandler ParseUpdateInfoEvent; + /// + /// Set the owner for all dialogs. + /// + /// WPF Window or Windows Form object to be used as owner for all dialogs. + public static void SetOwner(object obj) + { + _owner = obj switch + { + Form form => form, + Window window => new Wpf32Window(window), + _ => _owner + }; + } + /// /// Start checking for new version of application and display a dialog to the user if update is available. /// @@ -503,7 +522,8 @@ private static bool StartUpdate(object result) if (ReportErrors) { - MessageBox.Show(Resources.UpdateUnavailableMessage, + MessageBox.Show(_owner, + Resources.UpdateUnavailableMessage, Resources.UpdateUnavailableCaption, MessageBoxButtons.OK, MessageBoxIcon.Information); } @@ -525,15 +545,17 @@ private static void ShowError(Exception exception) { if (exception is WebException) { - MessageBox.Show( + MessageBox.Show(_owner, Resources.UpdateCheckFailedMessage, - Resources.UpdateCheckFailedCaption, MessageBoxButtons.OK, MessageBoxIcon.Error); + Resources.UpdateCheckFailedCaption, + MessageBoxButtons.OK, MessageBoxIcon.Error); } else { - MessageBox.Show(exception.Message, - exception.GetType().ToString(), MessageBoxButtons.OK, - MessageBoxIcon.Error); + MessageBox.Show(_owner, + exception.Message, + exception.GetType().ToString(), + MessageBoxButtons.OK, MessageBoxIcon.Error); } } } @@ -662,7 +684,7 @@ public static bool DownloadUpdate(UpdateInfoEventArgs args) try { - return downloadDialog.ShowDialog().Equals(DialogResult.OK); + return downloadDialog.ShowDialog(_owner).Equals(DialogResult.OK); } catch (TargetInvocationException) { @@ -684,7 +706,7 @@ public static void ShowUpdateForm(UpdateInfoEventArgs args) updateForm.Size = UpdateFormSize.Value; } - if (updateForm.ShowDialog().Equals(DialogResult.OK)) + if (updateForm.ShowDialog(_owner).Equals(DialogResult.OK)) { Exit(); } diff --git a/AutoUpdater.NET/DownloadUpdateDialog.cs b/AutoUpdater.NET/DownloadUpdateDialog.cs index 15977cd..d5fc773 100644 --- a/AutoUpdater.NET/DownloadUpdateDialog.cs +++ b/AutoUpdater.NET/DownloadUpdateDialog.cs @@ -260,7 +260,7 @@ private void WebClientOnDownloadFileCompleted(object sender, AsyncCompletedEvent } catch (Exception e) { - MessageBox.Show(e.Message, e.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show(this, e.Message, e.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error); _webClient = null; } finally diff --git a/AutoUpdater.NET/UpdateForm.cs b/AutoUpdater.NET/UpdateForm.cs index fae6e0a..2fed23f 100644 --- a/AutoUpdater.NET/UpdateForm.cs +++ b/AutoUpdater.NET/UpdateForm.cs @@ -96,7 +96,7 @@ private void WebView_CoreWebView2InitializationCompleted(object sender, { if (AutoUpdater.ReportErrors) { - MessageBox.Show(e.InitializationException.Message, e.InitializationException.GetType().ToString(), + MessageBox.Show(this, e.InitializationException.Message, e.InitializationException.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error); } @@ -194,7 +194,7 @@ private void ButtonRemindLaterClick(object sender, EventArgs e) if (AutoUpdater.LetUserSelectRemindLater) { using var remindLaterForm = new RemindLaterForm(); - DialogResult dialogResult = remindLaterForm.ShowDialog(); + DialogResult dialogResult = remindLaterForm.ShowDialog(this); switch (dialogResult) { diff --git a/AutoUpdater.NET/Wpf32Window.cs b/AutoUpdater.NET/Wpf32Window.cs new file mode 100644 index 0000000..ee0535f --- /dev/null +++ b/AutoUpdater.NET/Wpf32Window.cs @@ -0,0 +1,16 @@ +using System; +using System.Windows; +using System.Windows.Interop; +using IWin32Window = System.Windows.Forms.IWin32Window; + +namespace AutoUpdaterDotNET; + +internal class Wpf32Window : IWin32Window +{ + public Wpf32Window(Window wpfWindow) + { + Handle = new WindowInteropHelper(wpfWindow).EnsureHandle(); + } + + public IntPtr Handle { get; } +} \ No newline at end of file diff --git a/AutoUpdater.NET/build/Autoupdater.NET.Official.nuspec b/AutoUpdater.NET/build/Autoupdater.NET.Official.nuspec index 1fa09e1..263dc17 100644 --- a/AutoUpdater.NET/build/Autoupdater.NET.Official.nuspec +++ b/AutoUpdater.NET/build/Autoupdater.NET.Official.nuspec @@ -2,7 +2,7 @@ Autoupdater.NET.Official - 1.8.1.0 + 1.8.2.0 AutoUpdater.NET rbsoft false @@ -17,16 +17,16 @@ autoupdate updater c# vb wpf winforms - + - + - + - + diff --git a/AutoUpdaterTest/AutoUpdaterTest.csproj b/AutoUpdaterTest/AutoUpdaterTest.csproj index 9c505a5..d5b76de 100644 --- a/AutoUpdaterTest/AutoUpdaterTest.csproj +++ b/AutoUpdaterTest/AutoUpdaterTest.csproj @@ -10,11 +10,11 @@ - + - + diff --git a/AutoUpdaterTest/MainWindow.xaml b/AutoUpdaterTest/MainWindow.xaml index 474f4e2..4bd223d 100644 --- a/AutoUpdaterTest/MainWindow.xaml +++ b/AutoUpdaterTest/MainWindow.xaml @@ -4,6 +4,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" + Topmost="True" Title="MainWindow" Height="200" Width="400" ResizeMode="NoResize"> diff --git a/AutoUpdaterTest/MainWindow.xaml.cs b/AutoUpdaterTest/MainWindow.xaml.cs index 15791f3..b247ed5 100644 --- a/AutoUpdaterTest/MainWindow.xaml.cs +++ b/AutoUpdaterTest/MainWindow.xaml.cs @@ -191,6 +191,9 @@ private void ButtonCheckForUpdate_Click(object sender, RoutedEventArgs e) // Uncomment following line if you want to execute different executable after the update. This only works when you use zip file as an update file. AutoUpdater.ExecutablePath = "bin/AutoUpdaterTest.exe"; + // Uncomment following line to set this window as owner of the all dialogs initiated by AutoUpdater. It is necessary to do this if TopMost is set to true in your form or window. + AutoUpdater.SetOwner(this); + AutoUpdater.Start("https://rbsoft.org/updates/AutoUpdaterTest.xml"); } } \ No newline at end of file diff --git a/README.md b/README.md index e98646a..33c941f 100644 --- a/README.md +++ b/README.md @@ -325,6 +325,16 @@ You can specify the size of the update form by using below code. AutoUpdater.UpdateFormSize = new System.Drawing.Size(800, 600); ```` +### Set the owner Form / Window + +To ensure the dialogs showed by the auto updater are visible and always focussed correctly related to an application +Form or Window, it may be necessary to set an owner. You can assign a Form or WPF Window as the owner by following the +example below. + +````csharp +AutoUpdater.SetOwner(yourMainFormOrWpfWindow); +```` + ### Change storage method of Remind Later and Skip options You can change how AutoUpdater.NET saves the Remind Later and Skip values by assigning the PersistenceProvider. If you diff --git a/ZipExtractor/FormMain.cs b/ZipExtractor/FormMain.cs index 091aee8..8f91652 100644 --- a/ZipExtractor/FormMain.cs +++ b/ZipExtractor/FormMain.cs @@ -225,7 +225,7 @@ private void FormMain_Shown(object sender, EventArgs e) foreach (Process lockingProcess in lockingProcesses) { - DialogResult dialogResult = MessageBox.Show( + DialogResult dialogResult = MessageBox.Show(this, string.Format(Resources.FileStillInUseMessage, lockingProcess.ProcessName, filePath), Resources.FileStillInUseCaption, @@ -306,7 +306,7 @@ private void FormMain_Shown(object sender, EventArgs e) _logBuilder.AppendLine(); _logBuilder.AppendLine(exception.ToString()); - MessageBox.Show(exception.Message, exception.GetType().ToString(), + MessageBox.Show(this, exception.Message, exception.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error); } finally diff --git a/appveyor.yml b/appveyor.yml index 1ab2def..9a9e383 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ -version: 1.8.1.{build} +version: 1.8.2.{build} environment: - my_version: 1.8.1 + my_version: 1.8.2 my_secret: secure: vbPRaZLQYpGPr4BrZZ4p6TofpSZMud+FKtlpqjgO8aA= skip_branch_with_pr: true