[PTRun][WindowWalker]Don't hang when closing an unresponsive window (#33167)

* add(windowWalkerComponents): added a "Responding" variable signifying if a process is responding or not

* add(win32NativeMethod): added "SendMessageTimeout" method in the common Win32 namespace

* refactor(windowWalkerWindow): added an implementation of the helper function for closing the window using the newly defined method

refactor(windowWalkerWindow): added a thread to run, whenever "CloseThisWindow" is called

* refactor(resultHelper): used localizable strings for printing the responding text

add(resources): added "Not Responding" localizable text to the resources file

* refactor(resultHelper): refactored the message in case of a "Not Responding" task

* refactor(resultHelper): modified the formatting of the subtitle

* refactor(window): refactored the helper function and removed the unnecessary variable

* refactor(windowProcess): changed the variable name from "Responding" to "IsResponding"

* add: added try-catch to isResponding getter
This commit is contained in:
Vaibhav Sharma 2024-06-09 02:48:13 +05:30 committed by GitHub
parent 126a03e3b0
commit e3f5fba870
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 57 additions and 2 deletions

View File

@ -92,6 +92,11 @@ namespace Microsoft.Plugin.WindowWalker.Components
subtitleText += $" ({window.Process.ProcessID})"; subtitleText += $" ({window.Process.ProcessID})";
} }
if (!window.Process.IsResponding)
{
subtitleText += $" [{Resources.wox_plugin_windowwalker_NotResponding}]";
}
if (WindowWalkerSettings.Instance.SubtitleShowDesktopName && Main.VirtualDesktopHelperInstance.GetDesktopCount() > 1) if (WindowWalkerSettings.Instance.SubtitleShowDesktopName && Main.VirtualDesktopHelperInstance.GetDesktopCount() > 1)
{ {
subtitleText += $" - {Resources.wox_plugin_windowwalker_Desktop}: {window.Desktop.Name}"; subtitleText += $" - {Resources.wox_plugin_windowwalker_Desktop}: {window.Desktop.Name}";
@ -148,7 +153,8 @@ namespace Microsoft.Plugin.WindowWalker.Components
$"Desktop number: {window.Desktop.Number}\n" + $"Desktop number: {window.Desktop.Number}\n" +
$"Desktop is visible: {window.Desktop.IsVisible}\n" + $"Desktop is visible: {window.Desktop.IsVisible}\n" +
$"Desktop position: {window.Desktop.Position}\n" + $"Desktop position: {window.Desktop.Position}\n" +
$"Is AllDesktops view: {window.Desktop.IsAllDesktopsView}"; $"Is AllDesktops view: {window.Desktop.IsAllDesktopsView}\n" +
$"Responding: {window.Process.IsResponding}";
return new ToolTipData(window.Title, text); return new ToolTipData(window.Title, text);
} }

View File

@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Wox.Plugin.Common.VirtualDesktop.Helper; using Wox.Plugin.Common.VirtualDesktop.Helper;
using Wox.Plugin.Common.Win32; using Wox.Plugin.Common.Win32;
@ -234,12 +235,21 @@ namespace Microsoft.Plugin.WindowWalker.Components
NativeMethods.FlashWindow(Hwnd, true); NativeMethods.FlashWindow(Hwnd, true);
} }
/// <summary>
/// Helper function to close the window
/// </summary>
internal void CloseThisWindowHelper()
{
_ = NativeMethods.SendMessageTimeout(Hwnd, Win32Constants.WM_SYSCOMMAND, Win32Constants.SC_CLOSE, 0, 0x0000, 5000, out _);
}
/// <summary> /// <summary>
/// Closes the window /// Closes the window
/// </summary> /// </summary>
internal void CloseThisWindow() internal void CloseThisWindow()
{ {
_ = NativeMethods.SendMessage(Hwnd, Win32Constants.WM_SYSCOMMAND, Win32Constants.SC_CLOSE); Thread thread = new(new ThreadStart(CloseThisWindowHelper));
thread.Start();
} }
/// <summary> /// <summary>

View File

@ -33,6 +33,30 @@ namespace Microsoft.Plugin.WindowWalker.Components
get; private set; get; private set;
} }
/// <summary>
/// Gets a value indicating whether the process is responding or not
/// </summary>
internal bool IsResponding
{
get
{
try
{
return Process.GetProcessById((int)ProcessID).Responding;
}
catch (InvalidOperationException)
{
// Thrown when process not exist.
return true;
}
catch (NotSupportedException)
{
// Thrown when process is not running locally.
return true;
}
}
}
/// <summary> /// <summary>
/// Gets the id of the thread /// Gets the id of the thread
/// </summary> /// </summary>

View File

@ -141,6 +141,15 @@ namespace Microsoft.Plugin.WindowWalker.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to Not Responding.
/// </summary>
public static string wox_plugin_windowwalker_NotResponding {
get {
return ResourceManager.GetString("wox_plugin_windowwalker_NotResponding", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to No.. /// Looks up a localized string similar to No..
/// </summary> /// </summary>

View File

@ -202,4 +202,7 @@
<data name="wox_plugin_windowwalker_SettingSubtitleDesktopName_Description" xml:space="preserve"> <data name="wox_plugin_windowwalker_SettingSubtitleDesktopName_Description" xml:space="preserve">
<value>This information is only shown in subtitle and tool tip, if you have at least two desktops.</value> <value>This information is only shown in subtitle and tool tip, if you have at least two desktops.</value>
</data> </data>
<data name="wox_plugin_windowwalker_NotResponding" xml:space="preserve">
<value>Not Responding</value>
</data>
</root> </root>

View File

@ -81,6 +81,9 @@ namespace Wox.Plugin.Common.Win32
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam); public static extern int SendMessage(IntPtr hWnd, int msg, int wParam);
[DllImport("user32.dll")]
public static extern int SendMessageTimeout(IntPtr hWnd, uint msg, UIntPtr wParam, IntPtr lParam, int fuFlags, int uTimeout, out int lpdwResult);
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject); public static extern bool CloseHandle(IntPtr hObject);