大约有12人正在使用此应用程序,但我们只想允许4通过传统方法关闭应用程序(Alt + F4,文件>退出,关闭)
如果使用任何其他方法(TaskManager,WindowsShutdown)或其中一个允许的用户关闭应用程序,我们需要执行一些清理(关闭一些连接通道)
private void formClosing(object sender, FormClosingEventArgs e)
{
// If a user is allowed to close the application, an empty file (filename)
// will be in the root directory of the application.
if(e.CloseReason == CloseReason.UserClosing && !File.Exists("filename"))
{
e.Cancel = true;
return;
}
// Cleanup
}
如果用户(不允许关闭)尝试通过传统方法关闭应用程序,则尝试使用任务管理器关闭 CloseReason 枚举似乎不会自行重置,从而导致任务管理器弹出提示强制关闭,阻止应用程序清理。
这是一个错误,还是我遗漏了一些东西,在 FormClosing 事件被取消后会重置 CloseReason 。
答案 0 :(得分:6)
Form类有一个名为 closeReason 的内部字段,在生成您在 Closing 事件中检查的事件参数时使用此字段。这个内部字段设置在我可以找到的四个不同的地方。这些是......
1, Form.Close()方法设置closeReason = UserClosing。
这是有道理的,因为手动调用 Form.Close()方法通常是某些用户操作的结果,例如 File-> Exit 菜单选项由用户选择。显然这是一个用户操作。
2, WM_SYSCOMMAND(SC_CLOSE)设置closeReason = UserClosing。
表单的 WndProc 通过将 closeReason 设置为 UserClosing来处理 SC_CLOSE 系统命令并让默认窗口proc执行并关闭应用程序。这是有道理的,因为当用户按下窗口关闭chrome按钮或从右键单击标题栏选择关闭选项时发送 SC_CLOSE 。两者都是用户操作,因此将 closeReason 设置为 UserClosing 似乎是正确的。
3, WndProc使用closeReadon = TaskManagerClosing处理消息WM_CLOSE
(0x10)
WM_CLOSE
以关闭窗口,如果 closeReason 当前等于无,则将其更新为 TaskManagerClosing 。请注意这个问题,只有当它是无时它才会被更新,因为我觉得这对你来说是一个问题。
4, WndProc使用closeReason = WindowsShutDown处理消息0x11和0x16
这不是很有趣,因为您不关心这种情况,但它只是关闭消息的标准处理。
因此,您遇到的核心问题是,当您取消 Closing 事件时, closeReason 在任何时候都不会重置为 None 。因此,如果在取消后发生,则上面的第3点将永远不会正确地将值更新为 TaskManagerClosing 。由于closeReasson是内部字段,因此无法直接更新。但你可以作弊,这是我过去用过的一种方法。在事件处理程序中设置 Cancel = true 时,需要使用反射来访问内部字段,然后将其重置为无。
我没有测试过这段代码但你需要的东西......
PropertyInfo pi = typeof(Form).GetProperty("CloseReason",
BindingFlags.Instance |
BindingFlags.SetProperty |
BindingFlags.NonPublic);
pi.SetValue(this, CloseReason.None, null);
答案 1 :(得分:0)
我认为如果由任务经理(也就是操作系统......他是'大老板')启动你的流程就不能让你的流程停止关闭,你可以否认它就像关闭你的程序一样没有意义)。
接下来最好的事情是记录应用程序的状态,然后使用一些启动选项实例化您的进程的另一个实例,以接管您离开的状态。操作系统会终止您的进程,但您将立即启动另一个进程。
此外,如果用户点击应用程序列表中的TaskManager“go to process”,并从那里结束进程,我认为你根本不会收到任何活动...
如果你有一个在幕后运行的Windows服务并且跟踪一个实例正在运行,那么也许最好。这样,用户可能不会意识到存在这样的过程,因为它不是他们的应用程序,并且您可以使用它来跟踪应用程序关闭。