我的应用程序大部分时间都没有显示任何形式,当用户关闭系统时,我需要它自行关闭。
所以我创建了a question,那里的答案,SystemEvents.SessionEnding似乎有效。
起初。
这是我的Program.Main()
方法:
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
#region Pre-launch stuff
// Are we upgrading from an older version? We need to grab our old settings!
if (Properties.Settings.Default.UpgradeSettings)
{
Properties.Settings.Default.Upgrade();
Properties.Settings.Default.UpgradeSettings = false;
Properties.Settings.Default.Save();
}
// Visual styles
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
#if !DEBUG
// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandling.Application_ThreadException);
// Set the unhandled exception mode to force all Windows Forms errors to go through our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(ErrorHandling.CurrentDomain_UnhandledException);
#endif
// Since we have no forms open we need to watch for the shutdown event; otherwise we're blocking it
SystemEvents.SessionEnding += new SessionEndingEventHandler(SystemEvents_SessionEnding);
// ...
// ...
// ...
Application.Run();
}
方法SystemEvents_SessionEnding
运行一个调用Exit()
的方法,该方法依次运行:
public static void Exit()
{
MessageBox.Show("test");
try
{
IconHandler.SuperNotifyIcon.Dispose();
}
finally
{
Application.Exit();
}
}
然而,我的应用程序有时会关闭。我在那里添加的消息框没有显示出来。
我无法弄清楚这种简单,简单的执行路径如何失败。但确实如此,这对我和我的应用程序的用户来说都是一个主要的刺激因素。
有什么想法吗?想要四处游荡?
修改
根据corvuscorax的回答,我尝试添加一个表单,但它表现得很奇怪 - 起初,我在表单的代码中有这个:
ShowInTaskbar = false;
WindowState = FormWindowState.Minimized;
Shown += (sender, e) => Hide();
修改了Program.Exit()
方法以关闭该表单,该表单也会在FormClosing
事件中运行处理代码。
结果是禁用ShowInTaskbar
停止表单收到HWND_BROADCAST
消息。我现在已经注释掉了这一行,但即便如此,我发现关闭阻塞正在发生。一旦我点击了我制作的按钮以显示表格并试图再次关闭,它就顺利完成了。
答案 0 :(得分:1)
您的代码是否有消息泵?
您需要在应用程序的每个用户界面线程中使用消息泵,以便分派和处理针对您的应用程序的任何Windows消息。即使您从未在屏幕上显示表单,如果该线程是用户界面线程,仍然会发送其他系统消息需要调度和处理。
在典型的WinForms应用程序中,消息泵在此调用中......
Application.Run(new MyForm());
...仅在MyForm实例关闭后退出。在你的情况下,似乎你永远不会调用Application.Run方法或类似的东西。在这种情况下你不处理Windows消息。那么,当您没有显示表单时,您的处理循环是什么?
答案 1 :(得分:1)
我建议不要有任何形式。
只需执行一个普通的WinForms应用程序并将主窗体设置为隐藏,您就可以像往常一样使所有的消息处理工作。
附录
作为这样做的额外好处,您还可以在开发时免费获得控制台 - 通过不隐藏主窗体,您可以拥有简单的输出视图,模拟输入,触发按钮操作,各种有用东西。
附录2
以下是我通常创建隐形主窗体的方法。在表单构造函数中,添加:
if (!Debugger.IsAttached)
{
// Prevent the window from showing up in the task bar AND when Alt-tabbing
ShowInTaskbar = false;
FormBorderStyle = FormBorderStyle.FixedToolWindow;
// Move it off-screen
StartPosition = FormStartPosition.Manual;
Location = new Point(SystemInformation.VirtualScreen.Right+10, SystemInformation.VirtualScreen.Bottom+10);
Size = new System.Drawing.Size(1, 1);
}
这将在未在调试器中运行时隐藏窗口。