*** Please fill in the fields below. If you leave fields empty or specify 'latest' rather than the actual version your answer will be delayed as we will be forced to ask you for this information. ***
Product, version and build: Powershell Studio 5.8.241
Operating system: Windows 10 22H2
PowerShell version(s):
*** Please add details and screenshots as needed below. ***
DO NOT POST LICENSES, KEYS OR ANY OTHER LICENSING INFORMATION IN THIS FORUM
I have a tray app that I'm writing, is it possible to execute code when the app is exited or receives the quit command from windows?
Right now the app is a basic while loop.
- #Define a Param block to use custom parameters in the project
- #Param ($CustomParameter)
- #Grab make and model info
- $model = (Get-WmiObject -Class:Win32_ComputerSystem).Model;
- #Check if this is 4u Threadripper, if so open com3
- if ($model -eq "Early 2024 Fusebox 4u") { $port = new-Object System.IO.Ports.SerialPort COM3, 115200, None, 8, one; Write-Host("2024 Fusebox 4u") }
- elseif ($model -eq "Mid 2024 Fusebox 1u") { $port = new-Object System.IO.Ports.SerialPort COM3, 115200, None, 8, one; Write-Host("2024 Fusebox 1u") }
- elseif ($model -eq "System Product Name") { $port = new-Object System.IO.Ports.SerialPort COM3, 115200, None, 8, one; Write-Host("BabinTest") }
- else { Write-Host("No matching ports found"); Write-Host($model) }
- function Main
- {
- <#
- .SYNOPSIS
- The Main function starts the project application.
- .PARAMETER Commandline
- $Commandline contains the complete argument string passed to the script packager executable.
- .NOTES
- Use this function to initialize your script and to call GUI forms.
- .NOTES
- To get the console output in the Packager (Forms Engine) use:
- $ConsoleOutput (Type: System.Collections.ArrayList)
- #>
- Param ([String]$Commandline)
- #--------------------------------------------------------------------------
- #TODO: Add initialization script here (Load modules and check requirements)
- Add-Type -AssemblyName "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- #[void][System.Windows.Forms.MessageBox]::Show('TODO: Add script to the Main function of Startup.pss', 'TODO')
- # Grab Serial ports
- #$serial_ports= Get-CimInstance -Class Win32_SerialPort | Select-Object Name, DeviceID ;
- # Looks for external config file
- Write-Debug "Reading configuration."
- try
- {
- . $PSScriptRoot/config.ps1
- }
- catch
- {
- Write-Debug "Error reading setup file."
- EXIT
- }
- #loop to run watchdog script
- try
- {
- while ($port)
- {
- $port.open() # Open Serial Port
- if (Get-Process -ErrorAction SilentlyContinue -Name "VLC") { $port.WriteLine($preset_101) }
- elseif (Get-Process -ErrorAction SilentlyContinue -Name "cmd") { $port.WriteLine($preset_107) } #Matrix
- #elseif (Get-Process -ErrorAction SilentlyContinue -Name "d3manager") {$port.WriteLine($preset_3)}
- else { $port.WriteLine($preset_100) } #Windows Idle
- write-debug "in loop"
- $port.Close() # Close Serial Port
- Start-Sleep -Seconds 1 # Wait time
- }
- }
- catch
- {
- # Catch any error
- Write-Debug "An error occurred"
- }
- finally
- {
- # [Optional] Run this part always
- $port.Close() # Close Serial Port
- Write-Host("quitting")
- }
- #--------------------------------------------------------------------------
- $script:ExitCode = 0 #Set the exit code for the Packager
- }
Edit: I tried making it a windows service project as well as I noticed that has a "Stop-MyService" function. However this doesn't appear to be called on windows shutdown, only if I stop the service manually.
The below code is what I'm trying with a service
- # Warning: Do not rename Start-MyService, Invoke-MyService and Stop-MyService functions
- function Start-MyService
- {
- # Place one time startup code here.
- # Initialize global variables and open connections if needed
- Write-Host "Serive Start Function"
- $global:bRunService = $true
- $global:bServiceRunning = $false
- $global:bServicePaused = $false
- }
- function Invoke-MyService
- {
- Write-Host "Service Invoke Function"
- $global:bServiceRunning = $true
- while($global:bRunService) {
- try
- {
- if($global:bServicePaused -eq $false) #Only act if service is not paused
- {
- #Place code for your service here
- #e.g. $ProcessList = Get-Process solitaire -ErrorAction SilentlyContinue
- # Use Write-Host or any other PowerShell output function to write to the System's application log
- }
- }
- catch
- {
- # Log exception in application log
- Write-Host $_.Exception.Message
- }
- # Adjust sleep timing to determine how often your service becomes active.
- if($global:bServicePaused -eq $true)
- {
- Start-Sleep -Seconds 20 # if the service is paused we sleep longer between checks.
- }
- else
- {
- Start-Sleep –Seconds 10 # a lower number will make your service active more often and use more CPU cycles
- }
- }
- $global:bServiceRunning = $false
- }
- function Stop-MyService
- {
- Write-Host "Stop Service Function"
- $global:bRunService = $false # Signal main loop to exit
- $CountDown = 30 # Maximum wait for loop to exit
- while($global:bServiceRunning -and $Countdown -gt 0)
- {
- Start-Sleep -Seconds 1 # wait for your main loop to exit
- $Countdown = $Countdown - 1
- }
- # Place code to be executed on service stop here
- # Close files and connections, terminate jobs and
- # use remove-module to unload blocking modules
- }
- function Pause-MyService
- {
- Write-Host "Pause Service Function"
- # Service is being paused
- # Save state
- $global:bServicePaused = $true
- # Note that the thread your PowerShell script is running on is not suspended on 'pause'.
- # It is your responsibility in the service loop to pause processing until a 'continue' command is issued.
- # It is recommended to sleep for longer periods between loop iterations when the service is paused.
- # in order to prevent excessive CPU usage by simply waiting and looping.
- }
- function Continue-MyService
- {
- Write-Host "Continue Service Function"
- # Service is being continued from a paused state
- # Restore any saved states if needed
- $global:bServicePaused = $false
- }