2

How can I get a closing event in this very simple app? It is a windowless winforms app. I do not want to have a tray icon, at least not a visible one.

Module Module1
    Sub Main()
        While True
            MsgBox("I am still alive!")
            System.Threading.Thread.Sleep(10000)
        End While
    End Sub

    ' how do I call this?
    Public Sub ProgramClosing()
        MsgBox("Program is closing. Good Bye.")
    End Sub
End Module

UPDATE:

The code below works, but for some reason I get two messages "Program closing. Good Bye.", instead of one.

Module Module1
    Sub Main()
        AddHandler Application.ApplicationExit, AddressOf AppClosing
        For i = 0 To 2
            MsgBox(i & vbCrLf & "I am still alive!")
            System.Threading.Thread.Sleep(5000)
        Next
        Application.Exit()
    End Sub

    Private Sub AppClosing(sender As Object, e As EventArgs)
        MsgBox("Program closing. Good Bye.") ' THIS IS SHOWN TWICE
    End Sub
End Module

UPDATE #2

I have tested to see if this event would fire when Windows actually shut down, and it did not.

I built the app with the code below, started the app (outside of Visual Studio), confirmed that it was running using Task Manager and turned off the computer. File "DebugFile.txt" never got created.

Module Module1
    Sub Main()
        AddHandler Application.ApplicationExit, AddressOf AppClosing
        While True
            ' do tasks here
            System.Threading.Thread.Sleep(10000)
        End While
    End Sub

    Private Sub AppClosing(sender As Object, e As EventArgs)
        RemoveHandler Application.ApplicationExit, AddressOf AppClosing
        System.IO.File.AppendAllText("DebugFile.txt", "App closed at " & Now.ToString & vbCrLf)
    End Sub
End Module
mcu
  • 3,302
  • 8
  • 38
  • 64
  • First you never will get out of your main, secondly your method `ProgramClosing` doesnt do anything. What and when should a user be able to close out? This question lacks details, please update. – Trevor Jul 18 '15 at 18:46
  • The program is supposed to shut down when the computer is powered down, but first I need to do some cleanup. – mcu Jul 18 '15 at 18:47
  • I need to be able to code my own cleanup. How do I call it? – mcu Jul 18 '15 at 18:48
  • Please see this, it has been answered before. http://stackoverflow.com/questions/20852014/is-there-any-way-to-capture-application-exit-event-in-vb-net-windows-form-system – Trevor Jul 18 '15 at 18:53
  • That was just what I needed. But for some reason, the event gets fired twice. Any idea why? See updated post for new code. – mcu Jul 18 '15 at 19:01

2 Answers2

1

If the app should run constantly, than I would Change it to Win From instead of console (I'm attaching C# example that you can easily translate to VB.Net. You can load a winform app without any GUI using the following in your form Load event:

private void Form1_Load(object sender, EventArgs e)
{
    this.Hide();
    this.Visible = false;
    this.Opacity = 0;
    this.ShowInTaskbar = false;
}

You can see more details in the following post as well How can I hide my application's form in the Windows Taskbar? Now, use the form closing event to do what ever you wish.

private void frmMonitor_FormClosing(object sender, FormClosingEventArgs e)
{
    //Your exit code
}

It should run only once.

Another option is to run on FormClosed event that will execute after the form has been closed.

Hope it helped,
Liron

Community
  • 1
  • 1
Liron
  • 515
  • 4
  • 20
  • At the example I see module - it mean you are running a console application and not WinForm. – Liron Jul 18 '15 at 19:37
  • In project properties, the startup object was set to be sub Main(). https://msdn.microsoft.com/en-us/library/17k74w0c%28v=vs.90%29.aspx – mcu Jul 18 '15 at 19:40
  • Changing your startup object does not change your application type. It just tells the compiler what's the main sub to use. If you want to change your app to WinForm you will need to change your application type from console application to Windows Form Application, – Liron Jul 18 '15 at 21:32
  • It was created as a Windows Forms Application right from the start. It never was a console app. – mcu Jul 18 '15 at 21:41
  • What is `Form1.InitializeProcess()`? – mcu Jul 18 '15 at 22:55
  • It's an internal function from my example, you should ignore it, I will edit the post and remove it. – Liron Jul 19 '15 at 03:51
  • So, I have built a project using your code. I run it from Visual Studio. No form is shown - so far so good. Then I click on _Stop Debugging_ and nothing happens, neither `FormClosing` nor `FormClosed` events are fired. – mcu Jul 19 '15 at 05:54
  • I'm not sure this is the correct way to test it. Stopping the debug is similar to kill a process, it does not shutdown as it should be. My suggestion is to create a quick test scenario that will shut you app. One possible way can be: a registry value that you check periodically and if the value is 1 that it will invoke a shut down method in your app. On your app you will need to create a timer that every couple of seconds and if the value has been changed, it will close your app properly. I'm sure there are more option to shut it down but that's the quickest. If sample code needed let me know – Liron Jul 19 '15 at 06:00
  • My end goal is to make this happen when Windows shuts down. Do you know how I can fire `FormClosing` event when Windows shuts down? – mcu Jul 19 '15 at 06:07
  • So what you will need to do as to add an event listener for the winodws shutdown / hibernate / sleep or other power event and when caught, initialize your exit code - see the following post: [.NET WinForms - How to listen to events for system LogOff, User Locked, Hibernate Started and System resumed?](http://stackoverflow.com/q/2242499/3839692) it has an example in VB as well – Liron Jul 19 '15 at 06:10
  • Your approach works, although I think I would prefer a solution that avoids a form altogether if possible. But I will accept your answer if nothing else shows up. – mcu Jul 19 '15 at 16:13
  • You can try the following, it worked for me in the past: Create a console application. Go to the project properties and modify it to Windows Form Application. You will get a console application with some of the winforms benefits. there you can bind the event listeners exactly like you have done in a regular Win Form App. – Liron Jul 19 '15 at 17:59
-1

Essentially, as soon as the while loop ends, your program is "closing." That is, unless you put code after that, the program will exit. How about putting a call to ProgramClosing() right after the End While?

Oh, I stupidly failed to observe that your while loop is infinite, as @436f6465786572 says in his/her comment. So add some way to exit the loop.

adv12
  • 8,443
  • 2
  • 24
  • 48