global startup and shutdown events when application starts and exist - vb.net

I need to write a log when the application starts and exits. Obviously when it starts it easy to write the log. But a user can close an application in multiple ways, even shut it down in task manager. is there sort of a global event when shutting an application down it will call a specific event from anywhere and I can add my logging code?

In visual Studio, go to the project properties window, Application tab. AT the bottom is a button labelled 'View Application Events' This takes you to a code view where you can add handlers for the application events including the shutdown event. However, this isn't always fired if your application crashes ^H^H^H^H^H closes in an 'unusual' way.
The startup event is useful too - you could put your startup logging code in there- we use it a lot to put in all the application setup code, with only a splash screen showing, then when the startup code completes the main window will pop up.
Finally, the Unhandled Exception event is a handy place to put a final catch-all backstop error handler

Related

Windows Automaton - InvokePattern blocking execution until everything has completed

I have experienced this behavior in my automation application: when I "click" a button by calling the InvokePattern.Invoke() method everything stops until the handler of the click event inside the automated application finishes.
While this can make some thing simple (for example I don't have to write tons of code to wait for a dialog with progress bar to disappear, because I simply get the control back when everything is done), but I can't do anything else. It even blocks the access to the Automation API in another thread where it continues after the click handler is done.
This causes problems when click handler in the automated application opens a modal dialog, then I can't do anything, the access to the application through automation API is blocked until the dialog is manually closed.
Has anybody solved this somehow and can help me?
Thanks,
Karel
PS: Reference source is saying this:
Request that the control initiate its action.
/// Should return immediately without blocking.
/// There is no way to determine what happened, when it happend, or whether
/// anything happened at all
public void Invoke() { ... }
Edit: It works perfectly when automating Windows notepad application which is not a .NET application. And it does not work for a Notepad clone (C# WinForms aplication).

Debugging problem in VB.Net with Windows Forms with losing events

We have a huge application that runs through a mass of code for every click you do. In one specific case, where you have a specific control in plain sight (so that the events are firing) and you load some special data into it and then click on the new button the form loses some events, like the closing event (you cannot close the form anymore and stop points in debug mode are not triggered) and one validating of a ComboBox that is really needed for the program. The only thing you can do when you get this kind of error is to restart the application to get out of this subform. But I tested it for 2 days now and even when I activate all points in the 'Exception Settings' I don't get any exceptions. The form (and other controls) are not losing ALL events. The resize, for example, still works. Even a specifically called AddHandler is not firing. Can you iterate somehow through the EventHandlerList? Or is there any way to test WHERE the event dies? Somehow any ideas on how to debug such a problem?

How to view active .Net events while stepping through code?

How do I track what events are currently 'Active' or currently being handled while stepping through the code.
The Issue
While I was debugging code (stepping through it) within a rather large application, all of a sudden I found that the code that was being run was running through code in functions that had nothing to do with the code I was troubleshooting. It took me a considerable amount of time to figure out why I found myself stepping through code in functions that were way outside the code I was debugging.
Turns out, at the start of the application, handlers are added to certain controls as well as timer controls. The timer control triggers an event every 5 minutes or so. There were other events being triggered when certain actions were taken, however I had no idea what was causing the debugger to enter into certain functions due to the fact that there was no indication or 'prompt' telling me an Event was Triggered and that was why I was now stepping into other functions.
How do I become aware of what is happening when events are triggered in the manner I mentioned above?
Note
This is not a question about how to add handlers or remove handlers in code.
So basically timers are still running in the same thread as the main logic. every time a function/Event is done and the Window steps into the waiting part in which unser input is read and events are started, timers will trigger. they will not run while other events are busy. If you use Background Worker or start second threads. they will run in between you current steps and the visual studio will jump from one to another. there is a thread window to keep track of all active threads but this only gives a clue. sometimes its still annoying to jump from one to another function. My advice is to use a debugger-hidden attribute on those functions that keep on bothering you.
How to find the Thread window:
How can I view Threads window in Visual studio?
How to use Debugger Hidden:
https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.debuggerhiddenattribute?redirectedfrom=MSDN&view=netframework-4.7.2
and
https://social.msdn.microsoft.com/Forums/vstudio/en-US/cf20736c-cbfb-4919-b495-ea9a9235f9e5/debuggerhiddenattribute-example?forum=csharpgeneral

Vb.Net: How can I trigger an event when a single instance program is opened again?

I've got a single instance (set up via .net) program that operates mostly from the system tray but also has a window.
Users often lose the program among their other system tray icons and believe the program isn't running, trying to open it again from the executable.
How can I detect, within my running program, that the executable is opened again? (So that I can maximize the window)
Thanks in advance.
Opening another copy of a single instance program will bring your form to the front by default, but when the form isn't visible, this won't have any effect.
This is what I was looking for
The MyApplication_StartupNextInstance event occurs when another instance is started. This can be used to call any additional functions you need.
In Project Properties, You can navigate to Application -> View Application Events and handle Me.StartupNextInstance from within Partial Friend Class MyApplication.
Direct all thanks to the comments.

VB.NET exe that talks to out-of-process COM on activate event bombs when external script AppActivates it

I wrote a VB.NET Windows Forms app that requests a string from an out-of-process COM object every time the activate event fires. My form has two tabs, so I need to programmatically flip to the correct tab every time my window gains focus. Works fine, until...
By chance, someone ran a vbscript (yes, script, not exe) that contains:
Set shell = CreateObject("WScript.Shell")
shell.AppActivate("Window Title That Matches My App")
This script consistently crashes my app. Usually so badly that the Exception dialog usually can't paint itself. I have to kill it from task manager. Sometimes the Exception is readable. (I also confirmed the exception by attaching to the running exe with Visual Studio). It's: "System.Runtime.InteropServices.COMException (0x8001010D): An outgoing call cannot be made since the application is dispatching an input-synchronous call."
What's really messing with my mind is that my app has multiple instance detection using a mutex, and if an existing instance is running, my own code (compiled) uses VB.NET's own AppActivate keyword, and this does NOT crash my app. It activates the running instance and exits the redundant instance as expected.
The problem seems solely to be triggered by cscript/wscript's AppActivate. I wrote a 3-liner .vbs to confirm this. It's repeatable.
Is there a way to trap or avoid this in my compiled app?
It's not clear to me WHY this approach actually fixes the problem, but it DOES work:
Add a timer to the form.
Move all the _Activated code to the timer's _Tick event.
Make the _Activated event start the timer.
Make the _Tick event stop the timer then perform the COM stuff.