Skip to content

Instantly share code, notes, and snippets.

@middletonk
Created February 5, 2021 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save middletonk/543c07e2c273434b41457ad6f8d8a58a to your computer and use it in GitHub Desktop.
Save middletonk/543c07e2c273434b41457ad6f8d8a58a to your computer and use it in GitHub Desktop.
PSADT Show-WelcomePrompt function overload for <3.8.4
#region Function Show-WelcomePrompt
### OVERLOAD of Show-WelcomePrompt with thanks to Josiah Pewterbaugh for his recommended "Remind Me Later" UI changes -Kevin Middleton
### https://www.josiahpewterbaugh.com/
Function Show-WelcomePrompt {
<#
.SYNOPSIS
Called by Show-InstallationWelcome to prompt the user to optionally do the following:
1) Close the specified running applications.
2) Provide an option to defer the installation.
3) Show a countdown before applications are automatically closed.
.DESCRIPTION
The user is presented with a Windows Forms dialog box to close the applications themselves and continue or to have the script close the applications for them.
If the -AllowDefer option is set to true, an optional "Defer" button will be shown to the user. If they select this option, the script will exit and return a 1618 code (SCCM fast retry code).
The dialog box will timeout after the timeout specified in the XML configuration file (default 1 hour and 55 minutes) to prevent SCCM installations from timing out and returning a failure code to SCCM. When the dialog times out, the script will exit and return a 1618 code (SCCM fast retry code).
.PARAMETER ProcessDescriptions
The descriptive names of the applications that are running and need to be closed.
.PARAMETER CloseAppsCountdown
Specify the countdown time in seconds before running applications are automatically closed when deferral is not allowed or expired.
.PARAMETER ForceCloseAppsCountdown
Specify whether to show the countdown regardless of whether deferral is allowed.
.PARAMETER PersistPrompt
Specify whether to make the prompt persist in the center of the screen every couple of seconds, specified in the AppDeployToolkitConfig.xml.
.PARAMETER AllowDefer
Specify whether to provide an option to defer the installation.
.PARAMETER DeferTimes
Specify the number of times the user is allowed to defer.
.PARAMETER DeferDeadline
Specify the deadline date before the user is allowed to defer.
.PARAMETER MinimizeWindows
Specifies whether to minimize other windows when displaying prompt. Default: $true.
.PARAMETER TopMost
Specifies whether the windows is the topmost window. Default: $true.
.PARAMETER ForceCountdown
Specify a countdown to display before automatically proceeding with the installation when a deferral is enabled.
.PARAMETER CustomText
Specify whether to display a custom message specified in the XML file. Custom message must be populated for each language section in the XML.
.EXAMPLE
Show-WelcomePrompt -ProcessDescriptions 'Lotus Notes, Microsoft Word' -CloseAppsCountdown 600 -AllowDefer -DeferTimes 10
.NOTES
This is an internal script function and should typically not be called directly. It is used by the Show-InstallationWelcome prompt to display a custom prompt.
.LINK
http://psappdeploytoolkit.com
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$false)]
[string]$ProcessDescriptions,
[Parameter(Mandatory=$false)]
[int32]$CloseAppsCountdown,
[Parameter(Mandatory=$false)]
[ValidateNotNullorEmpty()]
[boolean]$ForceCloseAppsCountdown,
[Parameter(Mandatory=$false)]
[ValidateNotNullorEmpty()]
[boolean]$PersistPrompt = $false,
[Parameter(Mandatory=$false)]
[switch]$AllowDefer = $false,
[Parameter(Mandatory=$false)]
[string]$DeferTimes,
[Parameter(Mandatory=$false)]
[string]$DeferDeadline,
[Parameter(Mandatory=$false)]
[ValidateNotNullorEmpty()]
[boolean]$MinimizeWindows = $true,
[Parameter(Mandatory=$false)]
[ValidateNotNullorEmpty()]
[boolean]$TopMost = $true,
[Parameter(Mandatory=$false)]
[ValidateNotNullorEmpty()]
[int32]$ForceCountdown = 0,
[Parameter(Mandatory=$false)]
[switch]$CustomText = $false
)
Begin {
## Get the name of this function and write header
[string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -CmdletBoundParameters $PSBoundParameters -Header
}
Process {
## Reset switches
[boolean]$showCloseApps = $false
[boolean]$showDefer = $false
[boolean]$persistWindow = $false
## Reset times
[datetime]$startTime = Get-Date
[datetime]$countdownTime = $startTime
## Check if the countdown was specified
If ($CloseAppsCountdown) {
If ($CloseAppsCountdown -gt $configInstallationUITimeout) {
Throw 'The close applications countdown time cannot be longer than the timeout specified in the XML configuration for installation UI dialogs to timeout.'
}
}
## Initial form layout: Close Applications / Allow Deferral
If ($processDescriptions) {
Write-Log -Message "Prompt user to close application(s) [$processDescriptions]..." -Source ${CmdletName}
$showCloseApps = $true
}
If (($allowDefer) -and (($deferTimes -ge 0) -or ($deferDeadline))) {
Write-Log -Message 'User has the option to defer.' -Source ${CmdletName}
$showDefer = $true
If ($deferDeadline) {
# Remove the Z from universal sortable date time format, otherwise it could be converted to a different time zone
$deferDeadline = $deferDeadline -replace 'Z',''
# Convert the deadline date to a string
[string]$deferDeadline = (Get-Date -Date $deferDeadline).ToString()
}
}
## If deferral is being shown and 'close apps countdown' or 'persist prompt' was specified, enable those features.
If (-not $showDefer) {
If ($closeAppsCountdown -gt 0) {
Write-Log -Message "Close applications countdown has [$closeAppsCountdown] seconds remaining." -Source ${CmdletName}
$showCountdown = $true
}
}
If ($showDefer) {
If ($persistPrompt) { $persistWindow = $true }
}
## If 'force close apps countdown' was specified, enable that feature.
If ($forceCloseAppsCountdown -eq $true) {
Write-Log -Message "Close applications countdown has [$closeAppsCountdown] seconds remaining." -Source ${CmdletName}
$showCountdown = $true
}
## If 'force countdown' was specified, enable that feature.
If ($forceCountdown -eq $true) {
Write-Log -Message "Countdown has [$closeAppsCountdown] seconds remaining." -Source ${CmdletName}
$showCountdown = $true
}
[string[]]$processDescriptions = $processDescriptions -split ','
[Windows.Forms.Application]::EnableVisualStyles()
$formWelcome = New-Object -TypeName 'System.Windows.Forms.Form'
$pictureBanner = New-Object -TypeName 'System.Windows.Forms.PictureBox'
$labelAppName = New-Object -TypeName 'System.Windows.Forms.Label'
$labelCountdown = New-Object -TypeName 'System.Windows.Forms.Label'
$labelDefer = New-Object -TypeName 'System.Windows.Forms.Label'
$listBoxCloseApps = New-Object -TypeName 'System.Windows.Forms.ListBox'
$buttonContinue = New-Object -TypeName 'System.Windows.Forms.Button'
$buttonDefer = New-Object -TypeName 'System.Windows.Forms.Button'
$buttonCloseApps = New-Object -TypeName 'System.Windows.Forms.Button'
$buttonAbort = New-Object -TypeName 'System.Windows.Forms.Button'
$buttonRemindMeLater = New-Object -TypeName 'System.Windows.Forms.Button' #RemindMeLater
$formWelcomeWindowState = New-Object -TypeName 'System.Windows.Forms.FormWindowState'
$flowLayoutPanel = New-Object -TypeName 'System.Windows.Forms.FlowLayoutPanel'
$panelButtons = New-Object -TypeName 'System.Windows.Forms.Panel'
$toolTip = New-Object -TypeName 'System.Windows.Forms.ToolTip'
## Remove all event handlers from the controls
[scriptblock]$Form_Cleanup_FormClosed = {
Try {
$labelAppName.remove_Click($handler_labelAppName_Click)
$labelDefer.remove_Click($handler_labelDefer_Click)
$buttonCloseApps.remove_Click($buttonCloseApps_OnClick)
$buttonContinue.remove_Click($buttonContinue_OnClick)
$buttonDefer.remove_Click($buttonDefer_OnClick)
$buttonRemindMeLater.remove_Click($buttonRemindMeLater_OnClick) #RemindMeLater
$buttonAbort.remove_Click($buttonAbort_OnClick)
$script:welcomeTimer.remove_Tick($timer_Tick)
$timerPersist.remove_Tick($timerPersist_Tick)
$timerRunningProcesses.remove_Tick($timerRunningProcesses_Tick)
$formWelcome.remove_Load($Form_StateCorrection_Load)
$formWelcome.remove_FormClosed($Form_Cleanup_FormClosed)
}
Catch { }
}
[scriptblock]$Form_StateCorrection_Load = {
## Correct the initial state of the form to prevent the .NET maximized form issue
$formWelcome.WindowState = 'Normal'
$formWelcome.AutoSize = $true
$formWelcome.TopMost = $TopMost
$formWelcome.BringToFront()
# Get the start position of the form so we can return the form to this position if PersistPrompt is enabled
Set-Variable -Name 'formWelcomeStartPosition' -Value $formWelcome.Location -Scope 'Script'
## Initialize the countdown timer
[datetime]$currentTime = Get-Date
[datetime]$countdownTime = $startTime.AddSeconds($CloseAppsCountdown)
$script:welcomeTimer.Start()
## Set up the form
[timespan]$remainingTime = $countdownTime.Subtract($currentTime)
[string]$labelCountdownSeconds = [string]::Format('{0}:{1:d2}:{2:d2}', $remainingTime.Days * 24 + $remainingTime.Hours, $remainingTime.Minutes, $remainingTime.Seconds)
If ($forceCountdown -eq $true) {
switch ($deploymentType){
'Install' { $labelCountdown.Text = ($configWelcomePromptCountdownMessage -f $($configDeploymentTypeInstall.ToLower())) + "`n$labelCountdownSeconds" }
'Uninstall' { $labelCountdown.Text = ($configWelcomePromptCountdownMessage -f $($configDeploymentTypeUninstall.ToLower())) + "`n$labelCountdownSeconds" }
'Repair' { $labelCountdown.Text = ($configWelcomePromptCountdownMessage -f $($configDeploymentTypeRepair.ToLower())) + "`n$labelCountdownSeconds" }
Default { $labelCountdown.Text = ($configWelcomePromptCountdownMessage -f $($configDeploymentTypeInstall.ToLower())) + "`n$labelCountdownSeconds" }
}
}
Else { $labelCountdown.Text = "$configClosePromptCountdownMessage`n$labelCountdownSeconds" }
}
## Add the timer if it doesn't already exist - this avoids the timer being reset if the continue button is clicked
If (-not ($script:welcomeTimer)) {
$script:welcomeTimer = New-Object -TypeName 'System.Windows.Forms.Timer'
}
If ($showCountdown) {
[scriptblock]$timer_Tick = {
## Get the time information
[datetime]$currentTime = Get-Date
[datetime]$countdownTime = $startTime.AddSeconds($CloseAppsCountdown)
[timespan]$remainingTime = $countdownTime.Subtract($currentTime)
Set-Variable -Name 'closeAppsCountdownGlobal' -Value $remainingTime.TotalSeconds -Scope 'Script'
## If the countdown is complete, close the application(s) or continue
If ($countdownTime -lt $currentTime) {
If ($forceCountdown -eq $true) {
Write-Log -Message 'Countdown timer has elapsed. Force continue.' -Source ${CmdletName}
$buttonContinue.PerformClick()
}
Else {
Write-Log -Message 'Close application(s) countdown timer has elapsed. Force closing application(s).' -Source ${CmdletName}
If ($buttonCloseApps.CanFocus) { $buttonCloseApps.PerformClick() }
Else { $buttonContinue.PerformClick() }
}
}
Else {
# Update the form
[string]$labelCountdownSeconds = [string]::Format('{0}:{1:d2}:{2:d2}', $remainingTime.Days * 24 + $remainingTime.Hours, $remainingTime.Minutes, $remainingTime.Seconds)
if ($labelCountdownSeconds -eq "1:00:00") #RemindMeLater
{
$formWelcome.WindowState = 'Normal'
$formWelcome.BringToFront()
$formWelcome.Refresh()
}
if ($labelCountdownSeconds -eq "0:30:00") #RemindMeLater
{
$formWelcome.WindowState = 'Normal'
$formWelcome.BringToFront()
$formWelcome.Refresh()
}
if ($labelCountdownSeconds -eq "0:15:00") #RemindMeLater
{
$labelCountdown.ForeColor = 'Red'
$labelApp.ForeColor = 'Red'
#$shellApp.MinimizeAll() | Out-Null
$buttonRemindMeLater.Enabled = $false
$formWelcome.BringToFront()
$formWelcome.WindowState = 'Normal'
$formWelcome.TopMost = $true
$formWelcome.BringToFront()
$formWelcome.Refresh()
}
if (($labelCountdownSeconds -gt "0:00:00") -and ($labelCountdownSeconds -lt "0:15:00")) #RemindMeLater
{
$labelCountdown.ForeColor = 'Red'
$buttonRemindMeLater.Enabled = $false
$formWelcome.Refresh()
}
If ($forceCountdown -eq $true) {
switch ($deploymentType){
'Install' { $labelCountdown.Text = ($configWelcomePromptCountdownMessage -f $configDeploymentTypeInstall) + "`n$labelCountdownSeconds" }
'Uninstall' { $labelCountdown.Text = ($configWelcomePromptCountdownMessage -f $configDeploymentTypeUninstall) + "`n$labelCountdownSeconds" }
'Repair' { $labelCountdown.Text = ($configWelcomePromptCountdownMessage -f $configDeploymentTypeRepair) + "`n$labelCountdownSeconds" }
Default { $labelCountdown.Text = ($configWelcomePromptCountdownMessage -f $configDeploymentTypeInstall) + "`n$labelCountdownSeconds" }
}
}
Else { $labelCountdown.Text = "$configClosePromptCountdownMessage`n$labelCountdownSeconds" }
[Windows.Forms.Application]::DoEvents()
}
}
}
Else {
$script:welcomeTimer.Interval = ($configInstallationUITimeout * 1000)
[scriptblock]$timer_Tick = { $buttonAbort.PerformClick() }
}
$script:welcomeTimer.add_Tick($timer_Tick)
## Persistence Timer
If ($persistWindow) {
$timerPersist = New-Object -TypeName 'System.Windows.Forms.Timer'
$timerPersist.Interval = ($configInstallationPersistInterval * 1000)
[scriptblock]$timerPersist_Tick = { Update-InstallationWelcome }
$timerPersist.add_Tick($timerPersist_Tick)
$timerPersist.Start()
}
[scriptblock]$buttonRemindMeLater_OnClick = {
## Minimize the form
$shellApp.UndoMinimizeAll() | Out-Null
$formWelcome.WindowState = 'Minimized'
}
## Process Re-Enumeration Timer
If ($configInstallationWelcomePromptDynamicRunningProcessEvaluation) {
$timerRunningProcesses = New-Object -TypeName 'System.Windows.Forms.Timer'
$timerRunningProcesses.Interval = ($configInstallationWelcomePromptDynamicRunningProcessEvaluationInterval * 1000)
[scriptblock]$timerRunningProcesses_Tick = { try { Get-RunningProcessesDynamically } catch {} }
$timerRunningProcesses.add_Tick($timerRunningProcesses_Tick)
$timerRunningProcesses.Start()
}
## Form
$formWelcome.Controls.Add($pictureBanner)
$formWelcome.Controls.Add($buttonAbort)
##----------------------------------------------
## Create padding object
$paddingNone = New-Object -TypeName 'System.Windows.Forms.Padding'
$paddingNone.Top = 0
$paddingNone.Bottom = 0
$paddingNone.Left = 0
$paddingNone.Right = 0
## Generic Button properties
$buttonWidth = 110
$buttonHeight = 23
$buttonPadding = 50
$buttonSize = New-Object -TypeName 'System.Drawing.Size'
$buttonSize.Width = $buttonWidth
$buttonSize.Height = $buttonHeight
$buttonPadding = New-Object -TypeName 'System.Windows.Forms.Padding'
$buttonPadding.Top = 0
$buttonPadding.Bottom = 5
$buttonPadding.Left = 50
$buttonPadding.Right = 0
## Picture Banner
$pictureBanner.DataBindings.DefaultDataSourceUpdateMode = 0
$pictureBanner.ImageLocation = $appDeployLogoBanner
$System_Drawing_Point = New-Object -TypeName 'System.Drawing.Point'
$System_Drawing_Point.X = 0
$System_Drawing_Point.Y = 0
$pictureBanner.Location = $System_Drawing_Point
$pictureBanner.Name = 'pictureBanner'
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
$System_Drawing_Size.Height = $appDeployLogoBannerHeight
$System_Drawing_Size.Width = 450
$pictureBanner.Size = $System_Drawing_Size
$pictureBanner.SizeMode = 'CenterImage'
$pictureBanner.Margin = $paddingNone
$pictureBanner.TabIndex = 0
$pictureBanner.TabStop = $false
## Label App Name
$labelAppName.DataBindings.DefaultDataSourceUpdateMode = 0
$labelAppName.Name = 'labelAppName'
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
If (-not $showCloseApps) {
$System_Drawing_Size.Height = 40
}
Else {
$System_Drawing_Size.Height = 65
}
$System_Drawing_Size.Width = 450
$labelAppName.Size = $System_Drawing_Size
$System_Drawing_Size.Height = 0
$labelAppName.MaximumSize = $System_Drawing_Size
$labelAppName.Margin = '0,15,0,15'
$labelAppName.Padding = '20,0,20,0'
$labelAppName.TabIndex = 1
## Initial form layout: Close Applications / Allow Deferral
If ($showCloseApps) {
$labelAppNameText = $configClosePromptMessage
}
ElseIf (($showDefer) -or ($forceCountdown)) {
$labelAppNameText = "$configDeferPromptWelcomeMessage `n$installTitle"
}
If ($CustomText) {
$labelAppNameText = "$labelAppNameText `n`n$configWelcomePromptCustomMessage"
}
$labelAppName.Text = $labelAppNameText
$labelAppName.TextAlign = 'TopCenter'
$labelAppName.Anchor = 'Top'
$labelAppName.AutoSize = $true
$labelAppName.add_Click($handler_labelAppName_Click)
## Listbox Close Applications
$listBoxCloseApps.DataBindings.DefaultDataSourceUpdateMode = 0
$listBoxCloseApps.FormattingEnabled = $true
$listBoxCloseApps.HorizontalScrollbar = $true
$listBoxCloseApps.Name = 'listBoxCloseApps'
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
$System_Drawing_Size.Height = 100
$System_Drawing_Size.Width = 300
$listBoxCloseApps.Size = $System_Drawing_Size
$listBoxCloseApps.Margin = '75,0,0,0'
$listBoxCloseApps.TabIndex = 3
$ProcessDescriptions | ForEach-Object { $null = $listboxCloseApps.Items.Add($_) }
## Label Defer
$labelDefer.DataBindings.DefaultDataSourceUpdateMode = 0
$labelDefer.Name = 'labelDefer'
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
$System_Drawing_Size.Height = 90
$System_Drawing_Size.Width = 450
$labelDefer.Size = $System_Drawing_Size
$System_Drawing_Size.Height = 0
$labelDefer.MaximumSize = $System_Drawing_Size
$labelDefer.Margin = $paddingNone
$labelDefer.Padding = '40,0,20,0'
$labelDefer.TabIndex = 4
$deferralText = "$configDeferPromptExpiryMessage`n"
If ($deferTimes -ge 0) {
$deferralText = "$deferralText `n$configDeferPromptRemainingDeferrals $([int32]$deferTimes + 1)"
}
If ($deferDeadline) {
$deferralText = "$deferralText `n$configDeferPromptDeadline $deferDeadline"
}
If (($deferTimes -lt 0) -and (-not $DeferDeadline)) {
$deferralText = "$deferralText `n$configDeferPromptNoDeadline"
}
$deferralText = "$deferralText `n`n$configDeferPromptWarningMessage"
$labelDefer.Text = $deferralText
$labelDefer.TextAlign = 'MiddleCenter'
$labelDefer.AutoSize = $true
$labelDefer.add_Click($handler_labelDefer_Click)
## Label Countdown
$labelCountdown.DataBindings.DefaultDataSourceUpdateMode = 0
$labelCountdown.Name = 'labelCountdown'
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
$System_Drawing_Size.Height = 40
$System_Drawing_Size.Width = 450
$labelCountdown.Size = $System_Drawing_Size
$System_Drawing_Size.Height = 0
$labelCountdown.MaximumSize = $System_Drawing_Size
$labelCountdown.Margin = $paddingNone
$labelCountdown.Padding = '40,0,20,0'
$labelCountdown.TabIndex = 4
$labelCountdown.Font = 'Microsoft Sans Serif, 9pt, style=Bold'
$labelCountdown.Text = '00:00:00'
$labelCountdown.TextAlign = 'MiddleCenter'
$labelCountdown.AutoSize = $true
$labelCountdown.add_Click($handler_labelDefer_Click)
## Panel Flow Layout
$System_Drawing_Point = New-Object -TypeName 'System.Drawing.Point'
$System_Drawing_Point.X = 0
$System_Drawing_Point.Y = $appDeployLogoBannerHeight
$flowLayoutPanel.Location = $System_Drawing_Point
$flowLayoutPanel.AutoSize = $true
$flowLayoutPanel.Anchor = 'Top'
$flowLayoutPanel.FlowDirection = 'TopDown'
$flowLayoutPanel.WrapContents = $true
$flowLayoutPanel.Controls.Add($labelAppName)
If ($showCloseApps) { $flowLayoutPanel.Controls.Add($listBoxCloseApps) }
If ($showDefer) {
$flowLayoutPanel.Controls.Add($labelDefer)
}
If ($showCountdown) {
$flowLayoutPanel.Controls.Add($labelCountdown)
}
## Button Close For Me
$buttonCloseApps.DataBindings.DefaultDataSourceUpdateMode = 0
$buttonCloseApps.Location = '15,0'
$buttonCloseApps.Name = 'buttonCloseApps'
$buttonCloseApps.Size = $buttonSize
$buttonCloseApps.TabIndex = 5
$buttonCloseApps.Text = $configClosePromptButtonClose
$buttonCloseApps.DialogResult = 'Yes'
$buttonCloseApps.AutoSize = $true
$buttonCloseApps.UseVisualStyleBackColor = $true
$buttonCloseApps.add_Click($buttonCloseApps_OnClick)
## Button Defer
$buttonDefer.DataBindings.DefaultDataSourceUpdateMode = 0
If (-not $showCloseApps) {
$buttonDefer.Location = '15,0'
}
Else {
$buttonDefer.Location = '170,0'
}
$buttonDefer.Name = 'buttonDefer'
$buttonDefer.Size = $buttonSize
$buttonDefer.TabIndex = 6
$buttonDefer.Text = $configClosePromptButtonDefer
$buttonDefer.DialogResult = 'No'
$buttonDefer.AutoSize = $true
$buttonDefer.UseVisualStyleBackColor = $true
$buttonDefer.add_Click($buttonDefer_OnClick)
## Button Remind Me Later
$buttonRemindMeLater.DataBindings.DefaultDataSourceUpdateMode = 0
$buttonRemindMeLater.Location = '170,0'
$buttonRemindMeLater.Name = 'buttonRemindMeLater'
$buttonRemindMeLater.Size = $buttonSize
$buttonRemindMeLater.TabIndex = 6
$buttonRemindMeLater.Text = "Remind Me Later"
#$buttonRemindMeLater.DialogResult = 'No'
$buttonRemindMeLater.AutoSize = $true
$buttonRemindMeLater.UseVisualStyleBackColor = $true
$buttonRemindMeLater.add_Click($buttonRemindMeLater_OnClick)
## Button Continue
$buttonContinue.DataBindings.DefaultDataSourceUpdateMode = 0
$buttonContinue.Location = '325,0'
$buttonContinue.Name = 'buttonContinue'
$buttonContinue.Size = $buttonSize
$buttonContinue.TabIndex = 7
$buttonContinue.Text = $configClosePromptButtonContinue
$buttonContinue.DialogResult = 'OK'
$buttonContinue.AutoSize = $true
$buttonContinue.UseVisualStyleBackColor = $true
$buttonContinue.add_Click($buttonContinue_OnClick)
If ($showCloseApps) {
# Add tooltip to Continue button
$toolTip.BackColor = [Drawing.Color]::LightGoldenrodYellow
$toolTip.IsBalloon = $false
$toolTip.InitialDelay = 100
$toolTip.ReshowDelay = 100
$toolTip.SetToolTip($buttonContinue, $configClosePromptButtonContinueTooltip)
}
## Button Abort (Hidden)
$buttonAbort.DataBindings.DefaultDataSourceUpdateMode = 0
$buttonAbort.Name = 'buttonAbort'
$buttonAbort.Size = '1,1'
$buttonAbort.TabStop = $false
$buttonAbort.DialogResult = 'Abort'
$buttonAbort.TabIndex = 5
$buttonAbort.UseVisualStyleBackColor = $true
$buttonAbort.add_Click($buttonAbort_OnClick)
## Form Welcome
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
$System_Drawing_Size.Height = 0
$System_Drawing_Size.Width = 0
$formWelcome.Size = $System_Drawing_Size
$formWelcome.Padding = $paddingNone
$formWelcome.Margin = $paddingNone
$formWelcome.DataBindings.DefaultDataSourceUpdateMode = 0
$formWelcome.Name = 'WelcomeForm'
$formWelcome.Text = $installTitle
$formWelcome.StartPosition = 'CenterScreen'
$formWelcome.FormBorderStyle = 'FixedDialog'
$formWelcome.MaximizeBox = $false
$formWelcome.MinimizeBox = $false
$formWelcome.TopMost = $TopMost
$formWelcome.TopLevel = $true
$formWelcome.Icon = New-Object -TypeName 'System.Drawing.Icon' -ArgumentList $AppDeployLogoIcon
$formWelcome.AutoSize = $true
$formWelcome.Controls.Add($pictureBanner)
$formWelcome.Controls.Add($flowLayoutPanel)
## Panel Button
$System_Drawing_Point = New-Object -TypeName 'System.Drawing.Point'
$System_Drawing_Point.X = 0
# Calculate the position of the panel relative to the size of the form
$System_Drawing_Point.Y = (($formWelcome.Size | Select-Object -ExpandProperty 'Height') - 10)
$panelButtons.Location = $System_Drawing_Point
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
$System_Drawing_Size.Height = 40
$System_Drawing_Size.Width = 450
$panelButtons.Size = $System_Drawing_Size
$panelButtons.AutoSize = $true
$panelButtons.Anchor = 'Top'
$padding = New-Object -TypeName 'System.Windows.Forms.Padding'
$padding.Top = 0
$padding.Bottom = 0
$padding.Left = 0
$padding.Right = 0
$panelButtons.Margin = $padding
If ($showCloseApps) { $panelButtons.Controls.Add($buttonCloseApps) }
If ($showDefer) { $panelButtons.Controls.Add($buttonDefer) }
$panelButtons.Controls.Add($buttonContinue)
$panelButtons.Controls.Add($buttonRemindMeLater)
## Add the Buttons Panel to the form
$formWelcome.Controls.Add($panelButtons)
## Save the initial state of the form
$formWelcomeWindowState = $formWelcome.WindowState
# Init the OnLoad event to correct the initial state of the form
$formWelcome.add_Load($Form_StateCorrection_Load)
# Clean up the control events
$formWelcome.add_FormClosed($Form_Cleanup_FormClosed)
Function Update-InstallationWelcome {
$formWelcome.BringToFront()
$formWelcome.Location = "$($formWelcomeStartPosition.X),$($formWelcomeStartPosition.Y)"
$formWelcome.Refresh()
}
# Function invoked by a timer to periodically check running processes dynamically whilst showing the welcome prompt
Function Get-RunningProcessesDynamically {
$dynamicRunningProcesses = $null
Get-RunningProcesses -ProcessObjects $processObjects -DisableLogging -OutVariable 'dynamicRunningProcesses'
[string]$dynamicRunningProcessDescriptions = ($dynamicRunningProcesses | Where-Object { $_.ProcessDescription } | Select-Object -ExpandProperty 'ProcessDescription' | Select-Object -Unique | Sort-Object) -join ','
If ($dynamicRunningProcessDescriptions -ne $script:runningProcessDescriptions) {
# Update the runningProcessDescriptions variable for the next time this function runs
Set-Variable -Name 'runningProcessDescriptions' -Value $dynamicRunningProcessDescriptions -Force -Scope 'Script'
If ($dynamicrunningProcesses) {
Write-Log -Message "The running processes have changed. Updating the apps to close: [$script:runningProcessDescriptions]..." -Source ${CmdletName}
}
# Update the list box with the processes to close
$listboxCloseApps.Items.Clear()
$script:runningProcessDescriptions -split "," | ForEach-Object { $null = $listboxCloseApps.Items.Add($_) }
}
# If CloseApps processes were running when the prompt was shown, and they are subsequently detected to be closed while the form is showing, then close the form. The deferral and CloseApps conditions will be re-evaluated.
If ($ProcessDescriptions) {
If (-not ($dynamicRunningProcesses)) {
Write-Log -Message 'Previously detected running processes are no longer running.' -Source ${CmdletName}
$formWelcome.Dispose()
}
}
# If CloseApps processes were not running when the prompt was shown, and they are subsequently detected to be running while the form is showing, then close the form for relaunch. The deferral and CloseApps conditions will be re-evaluated.
ElseIf (-not $ProcessDescriptions) {
If ($dynamicRunningProcesses) {
Write-Log -Message 'New running processes detected. Updating the form to prompt to close the running applications.' -Source ${CmdletName}
$formWelcome.Dispose()
}
}
}
## Minimize all other windows
If ($minimizeWindows) { $null = $shellApp.MinimizeAll() }
## Show the form
$result = $formWelcome.ShowDialog()
$formWelcome.Dispose()
Switch ($result) {
OK { $result = 'Continue' }
No { $result = 'Defer' }
Yes { $result = 'Close' }
Abort { $result = 'Timeout' }
}
If ($configInstallationWelcomePromptDynamicRunningProcessEvaluation){
$timerRunningProcesses.Stop()
}
Write-Output -InputObject $result
}
End {
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer
}
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment