Sometimes you want to have applications closed before other actions can start. Think about an install or uninstall that can only take place if certain applications are not running. With this script, you can close these applications. You can run the script silently or with user interaction. Whatever you prefer.
This script is also multilingual. The default language is English, but German, Dutch, French, Spanish and Indonesian are also supported. The GUI is in that language, the log file is in the English language. For translation, the file 'translations.json' is used.
You can enable logging. If the script is run with admin rights, the logpath is set to %WINDIR%\System32\Logfiles. Otherwise, it is the users' %TEMP% folder.
Some background information
The script detects the currently logged-on user by who is the owner of the 'explorer.exe' process. That is also the case for the SID. Finally, the user name from the user who is running the script is detected.
The language is stored in two locations:
- HKEY_CURRENT_USER\Control Panel\Desktop - > Value PreferredUILanguages
- HKEY_USERS\.DEFAULT\Control Panel\Desktop\MuiCached -> Value MachinePreferredUILanguages
But, if running with admin rights, the HKEY_CURRENT_USER must be translated to HKEY_USERS\<SID>. That is why the SID is needed. To keep things simple, I always use this technique, admin rights or not.
For the layout, I used a form. The form has been created with PowerShell Studio 2020. It was very easy to modify the layout.
The help function:
The help function gives detailed information.
Some examples.
Command line | Picture and logfile |
."C:\CloseApps\CloseRunningApps_v11.ps1" -ApplicationsToClose notepad,excel
|
![]() |
No logfile. | |
."C:\CloseApps\CloseRunningApps_v11.ps1" -ApplicationsToClose notepad,excel -DetailedLogging
(Powershell running as an admin, French MUI pack applied.) |
![]() |
Mon 18 Jan 2021 22:13:19 ***** Parameters part ***** Mon 18 Jan 2021 22:13:19 ***** User details part ***** Mon 18 Jan 2021 22:13:19 ***** Language part ***** Mon 18 Jan 2021 22:13:19 ***** Forms part ***** |
|
."C:\CloseApps\CloseRunningApps_v11.ps1" -ApplicationsToClose notepad,excel -DetailedLogging -LanguageOverride en
(Powershell running as an admin, French MUI pack applied.) |
![]() |
Mon 18 Jan 2021 22:14:59 ***** Parameters part ***** Mon 18 Jan 2021 22:14:59 ***** User details part ***** Mon 18 Jan 2021 22:14:59 ***** Language part ***** Mon 18 Jan 2021 22:14:59 ***** Forms part ***** |
|
."C:\CloseApps\CloseRunningApps_v11.ps1" -ApplicationsToClose notepad,excel -DetailedLogging -LanguageOverride gg -NoCancel (Powershell running as an admin, French MUI pack applied.) |
![]() |
Mon 18 Jan 2021 22:19:07 ***** Parameters part ***** Mon 18 Jan 2021 22:19:07 ***** User details part ***** Mon 18 Jan 2021 22:19:07 ***** Language part ***** Mon 18 Jan 2021 22:19:07 ***** Forms part ***** |
|
."C:\CloseApps\CloseRunningApps_v11.ps1" -ApplicationsToClose notepad,excel -DetailedLogging -Silent | <No picture> |
Thu 7 Jan 2021 15:40:49 ***** Parameters part ***** Thu 7 Jan 2021 15:40:49 ***** User details part ***** Thu 7 Jan 2021 15:40:49 ***** Language part ***** Thu 7 Jan 2021 15:40:49 ***** Forms part ***** |
|
."C:\CloseApps\CloseRunningApps_v11.ps1" -ApplicationsToClose notepad -DetailedLogging -CountdownInMinutes 130 | ![]() |
Mon 18 Jan 2021 21:41:49 ***** Parameters part ***** Mon 18 Jan 2021 21:41:49 ***** User details part ***** Mon 18 Jan 2021 21:41:49 ***** Language part ***** Mon 18 Jan 2021 21:41:49 ***** Forms part ***** |
|
."C:\CloseApps\CloseRunningApps_v11.ps1" -ApplicationsToClose notepad -DetailedLogging -CountdownInMinutes 130 -NoCancel | ![]() |
Mon 18 Jan 2021 21:42:42 ***** Parameters part ***** Mon 18 Jan 2021 21:42:42 ***** User details part ***** Mon 18 Jan 2021 21:42:42 ***** Language part ***** Mon 18 Jan 2021 21:42:42 ***** Forms part ***** |
|
."C:\CloseApps\CloseRunningApps_v11.ps1" -ApplicationsToClose notepad -DetailedLogging -CountdownInMinutes 1 -NoCancel | ![]() |
Mon 18 Jan 2021 21:44:13 ***** Parameters part *****
Mon 18 Jan 2021 21:44:13 Key: ApplicationsToClose Value: notepad Mon 18 Jan 2021 21:44:13 ***** User details part ***** Mon 18 Jan 2021 21:44:13 ***** Language part ***** Mon 18 Jan 2021 21:44:13 ***** Forms part ***** |
The script:
<#
.SYNOPSIS
Closes all the applications.
.DESCRIPTION
Closes all the applications that matches the parameter.
.EXAMPLE
Close Word, Excel and Adobe Acrobat Reader
."CloseRunningProcesses_v11.ps1" -ApplicationsToClose Winword,Excel,AcroRd32
.EXAMPLE
Close Word, Excel and Adobe Acrobat Reader and suppress the Cancel botton.
."CloseRunningProcesses_v11.ps1" -ApplicationsToClose Winword,Excel,AcroRd32 -NoCancel
.EXAMPLE
Close Word, Excel and Adobe Acrobat Reader and suppress the Cancel botton. Enable the logfile.
The logfile is in %TEMP% folder.
."CloseRunningProcesses_v11.ps1" -ApplicationsToClose Winword,Excel,AcroRd32 -NoCancel -DetailedLogging
.EXAMPLE
Close Word, Excel and Adobe Acrobat Reader and suppress the Cancel botton.
Show the GUI in the German language
."CloseRunningProcesses_v11.ps1" -ApplicationsToClose Winword,Excel,AcroRd32 -NoCancel -LanguageOverride de
.EXAMPLE
Close Word, Excel and Adobe Acrobat Reader and perform a silent closure of these applications.
."CloseRunningProcesses_v11.ps1" -ApplicationsToClose Winword,Excel,AcroRd32 -Silent
.NOTES
Author: Willem-Jan Vroom
Website: https://www.vroom.cc/
Twitter: @TheStingPilot
v0.1:
* Initial version.
v0.2:
* Improved layout.
v0.3:
* Changed the log file location: it is always the %TEMP% folder from the using who is starting the form.
v0.4:
* Changes in the translations.json file.
v1.0
* Final version.
v1.1
* The Function UserDetails has been modified. In some cases there where errors while running this part. That has been solved.
* Countdown timer
#>
[CmdletBinding(DefaultParameterSetName = 'Default')]
Param
(
[Parameter(HelpMessage ='Give all the executables you want to close. Wildcards are not allowed.')]
[Parameter(Mandatory = $True, ParameterSetName='Default')]
[String[]] $ApplicationsToClose,
[Parameter(HelpMessage ='Suppress the Cancel button.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Switch] $NoCancel,
[Parameter(HelpMessage ='Perform the operation silently.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Switch] $Silent,
[Parameter(HelpMessage ='Logging to the logfile in the users %TEMP% folder.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Switch] $DetailedLogging,
[Parameter(HelpMessage = 'Override the language.')]
[Parameter(Mandatory = $False, ParameterSetName = 'Default')]
[String] $LanguageOverride,
[Parameter(HelpMessage ='Countdown timer in minutes. Thus 130 minutes is 2:10:00.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Int] $CountdownInMinutes
)
# =============================================================================================================================================
# Function block
# =============================================================================================================================================
Function Add-EntryToLogFile
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 17-May-2020
Created by: Willem-Jan Vroom
Organization:
Functionname: Add-EntryToLogFile
=============================================================================================================================================
.SYNOPSIS
This function adds a line to a log file
#>
Param
(
[string] $Entry
)
Write-Verbose $Entry
if($Global:DetailedLogging)
{
$Timestamp = (Get-Date -UFormat "%a %e %b %Y %X").ToString()
Add-Content $Global:LogFile -Value $($Timestamp + " " + $Entry) -Force -ErrorAction SilentlyContinue
}
}
Function UserDetails
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 03-Jan-21 / Modified on 14-Jan-21
Created by: Willem-Jan Vroom
Functionname: UserDetails
=============================================================================================================================================
.SYNOPSIS
This function returns 4 details of the Current Logged In Usser
1. The username of the current logged in user
2. User\Domain of the current logged in user
3. User SID fo the User\Domain
4. Account name that is using the script
#>
$Explorer = (Get-WMIObject -Query "Select * From Win32_Process Where Name='explorer.exe'")
if($Explorer.Count -gt 1)
{
$UserName = ($Explorer[-1]).GetOwner()
$SID = (($Explorer[-1]).GetOwnerSID()).SID
}
else
{
$UserName = ($Explorer).GetOwner()
$SID = (($Explorer).GetOwnerSID()).SID
}
$UserAndDomain = "$($Username.Domain )\$($Username.User)"
$ScriptAccount = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Return $($Username.User),$UserAndDomain,$SID,$ScriptAccount
}
Function Test-RegistryKeyValue
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 30-Dec-20
Created by: (C) Aaron Jensen
https://stackoverflow.com/questions/5648931/test-if-registry-value-exists
Organization: Carbon Module
Functionname: Test-RegistryKeyValue
=============================================================================================================================================
.SYNOPSIS
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string]# The path to the registry key where the value should be set. Will be created if it doesn't exist.
$Path,
[Parameter(Mandatory = $true)]
[string]# The name of the value being set.
$Name
)
if (-not (Test-Path -Path $Path -PathType Container))
{
return $false
}
$properties = Get-ItemProperty -Path $Path
if (-not $properties)
{
return $false
}
$member = Get-Member -InputObject $properties -Name $Name
if ($member)
{
return $true
}
else
{
return $false
}
}
Function Find-Language
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 30-Dec-20
Created by: Willem-Jan Vroom
Organisation:
Functionname: Find-Language
=============================================================================================================================================
.SYNOPSIS
#>
[CmdletBinding()]
Param
(
$CurrentUserSID
)
$Result = "en-US"
$RegKey = "REGISTRY::HKEY_USERS\$CurrentUserSID\Control Panel\Desktop"
$Value = "PreferredUILanguages"
if (Test-RegistryKeyValue -Path $RegKey -Name $Value)
{
$Result = (get-itemproperty $RegKey | Select -ExpandProperty $Value).Split()[0]
Add-EntryToLogFile -Entry "Regkey '$RegKey' value '$Value' exists. The data is '$Result'."
Return $Result
}
$RegKey = "REGISTRY::HKEY_USERS\.DEFAULT\Control Panel\Desktop\MuiCached"
$Value = "MachinePreferredUILanguages"
if (Test-RegistryKeyValue -Path $RegKey -Name $Value)
{
$Result = (get-itemproperty $RegKey | Select -ExpandProperty $Value).Split()[0]
Add-EntryToLogFile -Entry "Regkey '$RegKey' value '$Value' exists. The data is '$Result'."
Return $Result
}
Add-EntryToLogFile -Entry "There was a problem reading the registry... :-("
Return $Result
}
Function Find-RunningProcessesToClose
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 17-October-2018 Updated on 03-Aug-2020
Created by: Willem-Jan Vroom
Organization:
Functionname: Find-RunningProcessesToClose
=============================================================================================================================================
.SYNOPSIS
#>
Param
(
[String[]] $LookForInArray,
[Switch] $ExactMatch
)
$tmpArray = @()
$Processes = @(Get-Process | Select-Object -Property Name, Description, ProductVersion, Path)
$Record = [ordered] @{"Name" = "";
"Application" = ""}
Add-EntryToLogFile -Entry "Starting to find all the applications to be closed."
ForEach ($ProcesName in $Processes)
{
ForEach ($SearchItem in $LookForInArray)
{
if(-not($ExactMatch))
{
$SearchItem = "*$($SearchItem)*"
}
$ExeFromPath = "-"
if ($ProcesName.Path)
{
$ExeFromPath = ($ProcesName.Path).Split("\")[-1]
}
if (($ProcesName.Name -like $SearchItem) -or ($ExeFromPath -like $SearchItem))
{
$Record."Name" = $ProcesName.Name
$Record."Application" = "$($ProcesName.Description) $($ProcesName.ProductVersion)"
$objRecord = New-Object PSObject -Property $Record
$tmpArray += $objRecord
Add-EntryToLogFile " -> Found application: $($Record."Application")."
}
}
}
Add-EntryToLogFile -Entry "End starting to the find all the applications to be closed."
Return $tmpArray
}
Function CloseRunningProcesses
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 17-October-2018 Updated on 03-Aug-2020
Created by: Willem-Jan Vroom
Organization:
Functionname: CloseRunningProcesses
=============================================================================================================================================
.SYNOPSIS
This function closes all the applications with the given PID's.
#>
Param
(
[String[]] $AppNames
)
ForEach ($AppName in $AppNames)
{
Try
{
Stop-Process -Name $AppName -Force -ErrorAction SilentlyContinue
Add-EntryToLogFile -Entry " * The application '$AppName' has been closed successfully."
}
Catch
{
Add-EntryToLogFile -Entry " * There was an error: '$($_.Exception.Message)' while closing '$AppName'."
}
}
}
# =============================================================================================================================================
# End function block
# =============================================================================================================================================
# =============================================================================================================================================
# Declares the variables.
# =============================================================================================================================================
Clear-Host
$CurrentDir = Split-Path -parent $MyInvocation.MyCommand.Definition
$arrAppNames = @()
$Global:DetailedLogging = $DetailedLogging
$ApplicationVersion = "v1.1"
$CountDown = $False
if($CountdownInMinutes -gt 0)
{
$CountDown = $True
}
# =============================================================================================================================================
# Find the logpath.
# It is the key 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders' with the value 'Local AppData'.
# And then '\temp' is added.
# =============================================================================================================================================
$OnlyUserName, `
$LoggedOnUserInDomainFormat, `
$UseridSID, `
$InstallAccount = UserDetails
$RegKey = "REGISTRY::HKEY_USERS\$UseridSID\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
$Value = "Local AppData"
$LogPath = ((Get-ItemProperty $RegKey).$Value) + "\temp"
# =============================================================================================================================================
# Define the results file. This file contains all the results.
# =============================================================================================================================================
if($Global:DetailedLogging)
{
$strLastPartOfFileName = " ($((Get-Date).ToString('G'))).log"
$strLastPartOfFileName = $strLastPartOfFileName -replace ":","-"
$strLastPartOfFileName = $strLastPartOfFileName -replace "/","-"
$PreFixLogFile = "CloseRunningApplications"
$Global:LogFile = $LogPath + "\"+ $PreFixLogFile + $strLastPartOfFileName
New-Item $Global:LogFile -ItemType File -Force | Out-Null
}
# =============================================================================================================================================
# Find all the arguments and put them in the log file
# Source: https://ss64.com/ps/psboundparameters.html
# =============================================================================================================================================
$TableWithParameters = @()
$RecordWithParameters = [ordered] @{"Key" = "";
"Value" = ""}
Add-EntryToLogFile -Entry "***** Parameters part *****"
ForEach($boundparam in $PSBoundParameters.GetEnumerator())
{
$tmpValue = $($boundparam.Value)
$Value = ""
if($tmpValue -is [array])
{
ForEach ($object in $tmpValue)
{
if(-not($value))
{
$Value = $object
}
else
{
$Value +=",$($object)"
}
}
}
else
{
$Value = $tmpValue
}
Add-EntryToLogFile -Entry "Key: $($boundparam.Key) Value: $Value"
}
Add-EntryToLogFile -Entry "***** End Parameters part *****`r`n"
# =============================================================================================================================================
# Write the logged in user details to the log file.
# =============================================================================================================================================
Add-EntryToLogFile -Entry "***** User details part *****"
Add-EntryToLogFile -Entry "Logged on user: $LoggedOnUserInDomainFormat"
Add-EntryToLogFile -Entry "Logged on user (SID): $UseridSID"
Add-EntryToLogFile -Entry "Installation account: $InstallAccount"
Add-EntryToLogFile -Entry "***** End User details part *****`r`n"
# =============================================================================================================================================
# Read the JSON file with the translations.
# If the JSON file does not contain the detected language, then fallback to English.
# =============================================================================================================================================
Add-EntryToLogFile -Entry "***** Language part *****"
if ($LanguageOverride)
{
$Language = $LanguageOverride
Add-EntryToLogFile "The parameter -LanguageOverride is used. The language is '$Language'."
}
else
{
$Language = (Find-Language -CurrentUserSID $UseridSID).SubString(0, 2)
}
$JSONFile = $CurrentDir + "\translations.json"
if (-not (Test-Path $JSONFile))
{
$Message = "The language file '$JSONFile' does not exists. Leaving the script."
Add-EntryToLogFile -Entry $Message
Write-Host $Message
Exit 1
}
$Translations = Get-Content $JSONFile -Encoding UTF8 | ConvertFrom-Json
if (-not ($Translations.$Language))
{
Add-EntryToLogFile "The language '$Language' is not found in the json file '$JSONFile'."
$Language = "en"
Add-EntryToLogFile "Falling back to the default language '$Language'."
}
Add-EntryToLogFile "The language '$Language' is used."
$SubTextBlockText = $Translations.$Language."SubTextBox"
if ($NoCancel)
{
$SubTextBlockText += "`r`n`r`n$($Translations.$Language."SubTextBox_NoCancel")"
}
Add-EntryToLogFile -Entry "***** End language part *****`r`n"
# =============================================================================================================================================
# Forms Block
# =============================================================================================================================================
Add-EntryToLogFile -Entry "***** Forms part *****"
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$CloseOpenPrograms = New-Object system.Windows.Forms.Form
$CloseOpenPrograms.AutoScaleDimensions = New-Object System.Drawing.SizeF(6, 13)
$CloseOpenPrograms.AutoScaleMode = 'Font'
$CloseOpenPrograms.ClientSize = New-Object System.Drawing.Size(376, 546)
$CloseOpenPrograms.Name = 'CloseOpenPrograms'
$CloseOpenPrograms.Opacity = 0.95
$CloseOpenPrograms.StartPosition = 'CenterScreen'
$CloseOpenPrograms.FormBorderStyle = 'Fixed3D'
$CloseOpenPrograms.ControlBox = $True
$CloseOpenPrograms.UseWaitCursor = $False
$CloseOpenPrograms.Text = "$($Translations.$Language."CloseOpenPrograms") $ApplicationVersion"
$SubTextBox = New-Object 'System.Windows.Forms.TextBox'
$SubTextBox.BackColor = [System.Drawing.SystemColors]::ControlLight
$SubTextBox.Font = [System.Drawing.Font]::new('Microsoft Sans Serif', '11')
$SubTextBox.Location = New-Object System.Drawing.Point(12, 12)
$SubTextBox.Multiline = $True
$SubTextBox.Name = 'SubTextBox'
$SubTextBox.ReadOnly = $True
$SubTextBox.Size = New-Object System.Drawing.Size(356, 118)
$SubTextBox.TabStop = $False
$SubTextBox.Text = $SubTextBlockText
$DataGridView_RunningApps = New-Object system.Windows.Forms.DataGridView
$DataGridView_RunningApps.Size = New-Object System.Drawing.Size(355, 310)
$DataGridView_RunningApps.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#e9e9e9")
$DataGridView_RunningApps.ColumnCount = 1
$DataGridView_RunningApps.Columns[0].Width = 322
$DataGridView_RunningApps.AllowUserToAddRows = $False
$DataGridView_RunningApps.AllowUserToDeleteRows = $False
$DataGridView_RunningApps.AllowUserToResizeColumns = $False
$DataGridView_RunningApps.AllowUserToResizeRows = $False
$DataGridView_RunningApps.ColumnHeadersHeightSizeMode = 'AutoSize'
$DataGridView_RunningApps.Name = 'DataGridView_RunningApps'
$DataGridView_RunningApps.ReadOnly = $True
$DataGridView_RunningApps.RowHeadersWidthSizeMode = 'DisableResizing'
$DataGridView_RunningApps.ScrollBars = 'Vertical'
$DataGridView_RunningApps.TabStop = $False
$DataGridView_RunningApps.Location = New-Object System.Drawing.Point(12, 136)
$DataGridView_RunningApps.BorderStyle = 'Fixed3D'
$DataGridView_RunningApps.Columns[0].Name = $Translations.$Language."DataGridView_RunningApps"
$Button_ok = New-Object 'System.Windows.Forms.Button'
$Button_ok.Anchor = 'Bottom, Right'
$Button_ok.Location = New-Object System.Drawing.Point(218, 484)
$Button_ok.Name = 'Button_ok'
$Button_ok.Size = New-Object System.Drawing.Size(150, 50)
$Button_ok.TabIndex = 1
$Button_ok.UseCompatibleTextRendering = $True
$Button_ok.UseVisualStyleBackColor = $True
$Button_ok.DialogResult = 'Ok'
$Button_ok.Text = $Translations.$Language."Button_ok"
$Button_cancel = New-Object 'System.Windows.Forms.Button'
$Button_cancel.Anchor = 'Bottom, Left'
$Button_cancel.Location = New-Object System.Drawing.Point(12, 484)
$Button_cancel.Name = 'Button_cancel'
$Button_cancel.Size = New-Object System.Drawing.Size(150, 50)
$Button_cancel.TabIndex = 0
$Button_cancel.UseCompatibleTextRendering = $True
$Button_cancel.UseVisualStyleBackColor = $True
$Button_cancel.DialogResult = 'Cancel'
$Button_cancel.Text = $Translations.$Language."Button_cancel"
$txtBoxCountDown = New-Object 'System.Windows.Forms.TextBox'
$txtBoxCountDown.Location = New-Object System.Drawing.Point(218, 453)
$txtBoxCountDown.Name = 'txtBoxCountDown'
$txtBoxCountDown.Size = New-Object System.Drawing.Size(149, 20)
$txtBoxTimeRemaining = New-Object 'System.Windows.Forms.TextBox'
$txtBoxTimeRemaining.Location = New-Object System.Drawing.Point(12, 453)
$txtBoxTimeRemaining.Name = 'txtBoxTimeRemaining'
$txtBoxTimeRemaining.Size = New-Object System.Drawing.Size(150, 20)
$txtBoxTimeRemaining.Text = $Translations.$Language."txtBoxTimeRemaining"
$CloseOpenPrograms.controls.AddRange(@($SubTextBox,$DataGridView_RunningApps,$Button_ok,$Button_cancel,$txtBoxCountDown,$txtBoxTimeRemaining))
# =============================================================================================================================================
# End Forms Block
# =============================================================================================================================================
# =============================================================================================================================================
# Hide the Cancel button in case the parameter 'NoCancel' is used.
# Hide the countdown boxes in case there is no countdown and set the variables if there is a countdown.
# =============================================================================================================================================
if($NoCancel)
{
$Button_cancel.Visible = $False
$CloseOpenPrograms.ControlBox = $False
$tmpValue = $Translations.$Language."Button_cancel".Replace("&","")
Add-EntryToLogFile -Entry "The parameter -NoCancel is used, so the cancel button '$tmpValue' is invisible."
}
if(-not ($CountDown))
{
$txtBoxTimeRemaining.Visible = $False
$txtBoxCountDown.Visible = $False
}
else
{
Add-Type -Assembly PresentationFramework
$timerCountDown = New-Object -TypeName System.Windows.Threading.DispatcherTimer
$Timeleft = New-Timespan -Seconds ($CountdownInMinutes * 60)
$OneSecond = New-TimeSpan -Seconds 1
}
# =============================================================================================================================================
# Find all the running processes.
#
# Only show the form in case there are items to show.
# =============================================================================================================================================
$AppsToClose = Find-RunningProcessesToClose -LookForInArray $ApplicationsToClose -ExactMatch
if($AppsToClose)
{
ForEach ($App in $AppsToClose)
{
if (-not($arrAppNames).Contains($App.Name))
{
$DataGridView_RunningApps.Rows.Add($App.Application) | Out-Null
Add-EntryToLogFile "The application '$($App.Application)' is added to the list of applications to be closed."
$arrAppNames += $App.Name
}
}
if(-not($Silent))
{
$Button_ok.add_Click({
$tmpValue = $Translations.$Language."Button_ok".Replace("&","")
Add-EntryToLogFile -Entry "Clicked on the '$tmpValue' button."
Add-EntryToLogFile -Entry "The results of the automatic closure of each application:"
CloseRunningProcesses -AppNames $arrAppNames
$CloseOpenPrograms.Close()
})
$Button_cancel.add_Click({
$tmpValue = $Translations.$Language."Button_cancel".Replace("&","")
Add-EntryToLogFile -Entry "Clicked on the '$tmpValue' button. No applications will be closed."
$CloseOpenPrograms.Close()
})
if($CountDown)
{
Add-EntryToLogFile "The countdown timer has been set to $($CountdownInMinutes * 60) seconds."
$timerCountDown.Interval = New-TimeSpan -Seconds 1
$timerCountDown.Tag = $Timeleft
$timerCountDown.add_Tick({
$timerCountDown.Tag = $timerCountDown.Tag - $OneSecond
$txtBoxCountDown.Text = $timerCountDown.Tag.ToString()
if($timerCountDown.Tag.TotalSeconds -le 0)
{
$timerCountDown.Stop()
Add-EntryToLogFile "The countdown has reached 0. The applications will be closed now."
CloseRunningProcesses -AppNames $arrAppNames
[void]$CloseOpenPrograms.Close()
}
})
$timerCountDown.IsEnabled = $True
$timerCountDown.Start()
}
[void]$CloseOpenPrograms.ShowDialog()
if($timerCountDown.IsEnabled)
{
Add-EntryToLogFile "The timer has been stopped."
$timerCountDown.Stop()
}
$CloseOpenPrograms.Dispose()
Add-EntryToLogFile -Entry "***** End forms part *****`r`n"
}
else
{
Add-EntryToLogFile -Entry "The following applications will be silently closed:"
CloseRunningProcesses -AppNames $arrAppNames
Add-EntryToLogFile -Entry "***** End forms part *****`r`n"
Remove-Variable * -ErrorAction SilentlyContinue
}
}
else
{
Add-EntryToLogFile "There are no applications to be closed."
Add-EntryToLogFile -Entry "***** End forms part *****`r`n"
Remove-Variable * -ErrorAction SilentlyContinue
}
And translations.json:
{
"en" :
{
"CloseOpenPrograms" : "Close open applications",
"SubTextBox" : "After closing the applications below the installation will continue.",
"SubTextBox_NoCancel" : "Closing the applications below is mandatory.",
"DataGridView_RunningApps" : "Application",
"HeaderText.Text" : "The following applications will be closed:",
"Button_ok" : "Close applications and e&xit",
"Button_cancel" : "&Cancel",
"txtBoxTimeRemaining" : "Time remaining:"
},
"de" :
{
"CloseOpenPrograms" : "Schließen Sie offene Anwendungen",
"SubTextBox" : "Nach dem Schließen der folgenden Anwendungen wird die Installation fortgesetzt.",
"SubTextBox_NoCancel" : "Das Schließen der folgenden Anwendungen ist obligatorisch.",
"DataGridView_RunningApps" : "Anwendung",
"HeaderText.Text" : "Die folgenden Anwendungen werden geschlossen:",
"Button_ok" : "Anwendungen &schließen und beenden",
"Button_cancel" : "&Aufheben",
"txtBoxTimeRemaining" : "Verbleibende Zeit:"
},
"nl" :
{
"CloseOpenPrograms" : "Sluiten geopende applicaties",
"SubTextBox" : "Na het sluiten van de onderstaande applicaties zal de installatie worden voortgezet.",
"SubTextBox_NoCancel" : "Het sluiten van de onderstaande applicaties is verplicht.",
"DataGridView_RunningApps" : "Applicatie",
"HeaderText.Text" : "De volgende applicaties worden gestopt:",
"Button_ok" : "Sluit applicaties en &klaar.",
"Button_cancel" : "&Annuleren",
"txtBoxTimeRemaining" : "Resterende tijd:"
},
"fr" :
{
"CloseOpenPrograms" : "Fermer les applications ouvertes",
"SubTextBox" : "Après avoir fermé les applications ci-dessous, l'installation continuera.",
"SubTextBox_NoCancel" : "La fermeture des candidatures ci-dessous est obligatoire.",
"DataGridView_RunningApps" : "Application",
"HeaderText.Text" : "Les candidatures suivantes seront fermées:",
"Button_ok" : "Fermer les applications et &quitter",
"Button_cancel" : "&Annuler",
"txtBoxTimeRemaining" : "Temps restant:"
},
"es" :
{
"CloseOpenPrograms" : "Cerrar aplicaciones abiertas",
"SubTextBox" : "Después de cerrar las aplicaciones a continuación, la instalación continuará.",
"SubTextBox_NoCancel" : "Es obligatorio cerrar las aplicaciones siguientes.",
"DataGridView_RunningApps" : "Solicitud",
"HeaderText.Text" : "Se cerrarán las siguientes aplicaciones:",
"Button_ok" : "Cerrar aplicaciones y &salir",
"Button_cancel" : "&Cancelar",
"txtBoxTimeRemaining" : "Tiempo restante:"
},
"id" :
{
"CloseOpenPrograms" : "Tutup aplikasi yang terbuka",
"SubTextBox" : "Setelah menutup aplikasi di bawah ini, penginstalan akan dilanjutkan.",
"SubTextBox_NoCancel" : "Menutup aplikasi di bawah ini adalah wajib.",
"DataGridView_RunningApps" : "Aplikasi",
"HeaderText.Text" : "Aplikasi berikut akan ditutup:",
"Button_ok" : "Tutup aplikasi dan &keluar",
"Button_cancel" : "&Membatalkan",
"txtBoxTimeRemaining" : "Waktu yang tersisa:"
}
}