VB.NET总是给出一个closereason作为userclosing

xienkqul  于 2023-06-07  发布在  .NET
关注(0)|答案(2)|浏览(129)

无论winforms应用程序如何关闭,FormClosing事件总是将closereason报告为“userclosing”
我的应用程序需要记录它是如何关闭的。由于FormClosing事件中的FormClosingEventArgs支持枚举的结束值,例如

  • Windows关闭
  • 任务管理器关闭
  • 用户关闭
  • MdiFormClosing

在窗体关闭时简单地记录该值是有意义的。但是...不管我怎么关闭表单,它总是报告CloseReason.UserClosing。我已经尝试过使用反射(基于Task manager close is not detected second time in a WinForms Application中的建议),但得到的结果与FormClosingEventArgs报告的结果相同
我写了一个测试应用

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        Dim fi As FieldInfo
        Dim ty As Type = GetType(Form)
        fi = ty.GetField("closeReason", BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.Public)
        Dim cr As String = fi.GetValue(Me).ToString()

        My.Computer.FileSystem.WriteAllText("d:\closetest.log", cr & vbCrLf, True)
        My.Computer.FileSystem.WriteAllText("d:\closetest.log", e.CloseReason.ToString & vbCrLf, True)

    End Sub

上面的代码总是在FormClosingEventArgs和反射值中报告UserClosing。我如何关闭表单并不重要-包括通过TaskManager关闭。这真的很令人沮丧--就好像微软已经完全关闭了操作系统中的这一功能。我的问题是,我有一个应用程序,似乎关闭它自己,并没有留下任何痕迹,在我自己的日志,也没有在Windows应用程序日志-什么都没有,没有。所以我怀疑一些外部事件,需要看看这是否可能记录它...

wfsdck30

wfsdck301#

你可以这样做:

Dim CloseByMyButton As Boolean = False

Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
    'If this form is child form call this   
    CloseByMyButton = True
    me.Close 

    'if this form is main form call this
    'Application.exit
End Sub

Private Sub MessageForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    'may be e.CloseReason = CloseReason.TaskManagerClosing must first line in this sub procedure, because it is too quick 
    If e.CloseReason = CloseReason.TaskManagerClosing Then
        MessageBox.Show("You close from Task Manager")
    ElseIf e.CloseReason = CloseReason.ApplicationExitCall Then
        MessageBox.Show("You close by exit application")
    ElseIf e.CloseReason = CloseReason.UserClosing Then
        If CloseByMyButton = True Then
            MessageBox.Show("You close by UserClosing With btnClose_Click")
        Else
            MessageBox.Show("You close by UserClosing Normally")
        End If
    Else
        MessageBox.Show("You close by Others")
    End If

End Sub
xqk2d5yq

xqk2d5yq2#

我在Windows 11和Windows Server 2019上进行了一些实验。以下是我发现的:

  • 所有用户触发的关闭事件(包括通过任务管理器关闭)--> UserClosing
  • Windows关机--> Windows关机
  • 由任务计划程序关闭--> TaskManager关闭

如果在启动触发器中指定了最大运行时间,则任务计划程序可以关闭应用程序。
一个实际的例子:在我的大多数应用程序中,当应用程序即将关闭(FormClosing事件)时,我会要求用户确认,但如果CloseReason是WindowsShutdown或TaskManagerClosing,我会立即关闭应用程序。因此,应用程序在必要时不会妨碍操作系统。

相关问题