我正在尝试制作一个非常小的应用程序,它仅位于状态栏中,响应键盘快捷键并具有上下文菜单。每当通过选项选择或用户单击关闭此菜单时,都会调用应用程序 OnExit 方法。
我通过在 .NET7 上创建一个新的 WPF 应用程序制作了一个最小版本,删除了MainWindow.xaml
,并删除了 中对它的引用App.xaml
,然后这是 中的完整代码App.xaml.cs
:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
namespace CLP_MVP;
public partial class App : System.Windows.Application
{
private readonly NotifyIcon _taskbarIcon = new();
private readonly ContextMenu _contextMenu = new();
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
_taskbarIcon.Icon = ResourceIcons.clp;
_taskbarIcon.Visible = true;
_contextMenu.Items.Add(new MenuItem() { Header = "Test" });
_taskbarIcon.Click += OpenMenu;
}
private void OpenMenu(object? sender, EventArgs e)
=> _contextMenu.IsOpen = true;
protected override void OnExit(ExitEventArgs e)
=> base.OnExit(e);
}
我点击离开时得到了不一致的结果(我希望在这里有任何见解),但我添加了一个菜单项,其中包含未处理的点击事件,该事件有效地关闭了菜单。
通过框架的调用堆栈是:
> CLP_MVP.dll!CLP_MVP.App.OnExit(System.Windows.ExitEventArgs e) Line 25 C#
PresentationFramework.dll!System.Windows.Application.DoShutdown() Line 1582 C#
PresentationFramework.dll!System.Windows.Application.ShutdownImpl() Line 2210 C#
PresentationFramework.dll!System.Windows.Application.ShutdownCallback(object arg) Line 2198 C#
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Line 103 C#
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Line 36 C#
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() Line 540 C#
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(object obj) Line 215 C#
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 183 C#
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 172 C#
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() Line 412 C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() Line 2095 C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(nint hwnd, int msg, nint wParam, nint lParam, ref bool handled) Line 2304 C#
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(nint hwnd, int msg, nint wParam, nint lParam, ref bool handled) Line 295 C#
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Line 429 C#
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Line 103 C#
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Line 36 C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Line 1339 C#
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(nint hwnd, int msg, nint wParam, nint lParam) Line 341 C#
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Line 2138 C#
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Line 2407 C#
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Line 1695 C#
CLP_MVP.dll!CLP_MVP.App.Main() Line 53 C#
对此的任何帮助或想法将不胜感激。我认为这与应用程序生命周期的早期终止有关。由于没有“可见”元素(除了来自不同框架的状态栏图标),应用程序处理程序只是终止执行以避免僵尸进程。如果这个假设是正确的,我将不胜感激关于如何避免这种情况的任何想法。
我尝试过使用Hardcodet.Wpf.TaskbarNotification
,结果完全相同。
默认情况下,WPF 应用程序将在所有窗口关闭时调用隐式关闭。尝试
ShutdownMode="OnExplicitShutdown"
在 App.Xaml 文件中进行设置。https://learn.microsoft.com/en-us/dotnet/api/system.windows.application.shutdownmode
请务必添加手动关闭的方法。