EXE - Exit (close) Actions

Ask your Windows PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Locked
User avatar
njcappa
Posts: 66
Joined: Wed May 04, 2016 6:50 am

EXE - Exit (close) Actions

Post by njcappa » Fri Sep 21, 2018 12:09 pm

Hi All,

If I have a script that I build into an exe (no win forms), is there a way for me to preform an action if the user clicks on the X close button?
I ask because I'd like to perform a number of clean up actions.

Thanks

User avatar
mxtrinidad
Site Admin
Posts: 328
Joined: Sun Mar 03, 2013 12:42 pm

Re: Post Exist Action

Post by mxtrinidad » Fri Sep 21, 2018 12:14 pm

The executable self-contained. There's no "x" button in a executable, only in Windows Form.

User avatar
njcappa
Posts: 66
Joined: Wed May 04, 2016 6:50 am

Re: EXE - Exit (close) Actions

Post by njcappa » Fri Sep 21, 2018 1:04 pm

sorry, just to clarify, I mean this:

https://imgur.com/a/XywBbxJ

if this is still the windows form, then how would I call an action to take place if someone closes it?

thanks

User avatar
mxtrinidad
Site Admin
Posts: 328
Joined: Sun Mar 03, 2013 12:42 pm

Re: EXE - Exit (close) Actions

Post by mxtrinidad » Fri Sep 21, 2018 2:15 pm

Again, that's outside the executable and "x"-exit it's cause by a Windows mouse action.
The executable runs within the console and can't trap calls outside of the console.

User avatar
Alexander Riedel
Posts: 7023
Joined: Tue May 29, 2007 4:43 pm

Re: EXE - Exit (close) Actions

Post by Alexander Riedel » Fri Sep 21, 2018 9:48 pm

In a console application there really is no option. In a Windows Application (there is a different host for that), which still is no form, we *could* add a close handler which gets called when the application is closed.
Not sure if that applies or is an option for what you are trying to do.
Alexander Riedel
SAPIEN Technologies, Inc.

User avatar
jvierra
Posts: 13725
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: EXE - Exit (close) Actions

Post by jvierra » Fri Sep 21, 2018 11:38 pm

Here is an example of how to trap the close events in a PowerShell console.

Code: Select all


$code = @'
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;


namespace Win32API{
    public class CloseHandler{

        //static bool exitSystem = false;

        [DllImport("Kernel32")]
        private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);

        private delegate bool EventHandler(CtrlType sig);
        static EventHandler _handler;

        enum CtrlType{
            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT = 1,
            CTRL_CLOSE_EVENT = 2,
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT = 6
        }

        private static bool Handler(CtrlType sig){
            Console.WriteLine("Exiting system due to external CTRL-C, or process kill, or shutdown");

            //do your cleanup here
            Thread.Sleep(5000); //simulate some cleanup delay

            Console.WriteLine("Cleanup complete");

            //allow main to run off
            //exitSystem = true;

            //shutdown right away so there are no lingering threads
            Environment.Exit(-1);

            return true;
        }
        public void SetHandler(){
            //exitSystem = true;
            _handler += new EventHandler(Handler);
            SetConsoleCtrlHandler(_handler, true);
        }

    }
}
'@
Add-Type $code
$handler = [Win32API.CloseHandler]::new()

$handler.SetHandler()

while(1){
    Write-Host Sleeping...
    sleep 2
}

The code just sends a message when one of the termination control events is received (CTRL_*).

This can be modified to call a PowerShell function or scriptblock when the control message arrives.

Place in PS1 file and run with powershell. Ctl-C or the 'X' will trigger the handler.
This can be included as a snippet to be inserted into a script with PSS or PrimalScript.

Later I will work out the best way to add PS code to the handler.

User avatar
njcappa
Posts: 66
Joined: Wed May 04, 2016 6:50 am

Re: EXE - Exit (close) Actions

Post by njcappa » Sat Sep 22, 2018 7:36 am

Thank you for all the information guys!

I'll take a look at the example code from jvierra and see if I can work that into what I need to accomplish.

User avatar
jvierra
Posts: 13725
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: EXE - Exit (close) Actions

Post by jvierra » Sat Sep 22, 2018 8:10 am

You will not do much because it only calls C# code. I posted it to show that the events can be caught and handled within a PowerShell console.

I am now trying to add an event generator to allow the code to generate an object event. This will allow the use of "Register-ObjectEvent" to cause the C# code to call arbitrary PowerShell code.

I haven't done this before mixing PS and C# classes with events. I suspect either Alex or David could do this in a few minutes. I have to sneak up on it the first time.

I will work on it tomorrow. I have all of the test code almost ready and now need to test and validate the behavior.

User avatar
njcappa
Posts: 66
Joined: Wed May 04, 2016 6:50 am

Re: EXE - Exit (close) Actions

Post by njcappa » Mon Sep 24, 2018 6:47 am

Thanks again, jvierra.

I appreciate the efforts on putting something like this together.

User avatar
jvierra
Posts: 13725
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: EXE - Exit (close) Actions

Post by jvierra » Mon Sep 24, 2018 7:41 am

I discovered on issue. You cannot run any PowerShell code in this event or after it. Only simple C# code can be run. This is because the pipeline has already been terminated when the event is called. You can write to the console but you cannot read from it. You can use any basic C# code to log to a file or other duties but the PowerShell pipeline is gone so you cannot even inspect its variables.

This is a major limitation of all console based programs.

I can run the handler and trap the exit but no events can be received by PS once this is executed.

Locked