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 'CloseRunningApps_v13.json' is used.
These examples have been created with an earlier version.
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:
Get-Help "C:\tmp\CloseRunningApps_v13\CloseRunningApps_v13.ps1" -Detailed
NAME
C:\tmp\CloseRunningApps_v13\CloseRunningApps_v13.ps1
SYNOPSIS
Closes all the applications.
SYNTAX
C:\tmp\CloseRunningApps_v13\CloseRunningApps_v13.ps1 [-Directories <String[]>] [-ApplicationsToClose <String[]>]
[-NoCancel] [-Silent] [-DetailedLogging] [-LanguageOverride <String>] [-Title <String>] [-CountdownInMinutes
<Int32>] [<CommonParameters>]
DESCRIPTION
Closes all the applications that matches the parameter.
PARAMETERS
-Directories <String[]>
-ApplicationsToClose <String[]>
-NoCancel [<SwitchParameter>]
-Silent [<SwitchParameter>]
-DetailedLogging [<SwitchParameter>]
-LanguageOverride <String>
-Title <String>
-CountdownInMinutes <Int32>
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer, PipelineVariable, and OutVariable. For more information, see
about_CommonParameters (https:/go.microsoft.com/fwlink/?LinkID=113216).
-------------------------- EXAMPLE 1 --------------------------
PS C:\>Close Word, Excel and Adobe Acrobat Reader
."CloseRunningProcesses_v13.ps1" -ApplicationsToClose Winword,Excel,AcroRd32
-------------------------- EXAMPLE 2 --------------------------
PS C:\>Close Word, Excel and Adobe Acrobat Reader and suppress the Cancel botton.
."CloseRunningProcesses_v13.ps1" -ApplicationsToClose Winword,Excel,AcroRd32 -NoCancel
-------------------------- EXAMPLE 3 --------------------------
PS C:\>Close Word, Excel and Adobe Acrobat Reader and suppress the Cancel botton. Enable the logfile.
The logfile is in %TEMP% folder.
."CloseRunningProcesses_v13.ps1" -ApplicationsToClose Winword,Excel,AcroRd32 -NoCancel -DetailedLogging
-------------------------- EXAMPLE 4 --------------------------
PS C:\>Close Word, Excel and Adobe Acrobat Reader and suppress the Cancel botton.
Show the GUI in the German language
."CloseRunningProcesses_v13.ps1" -ApplicationsToClose Winword,Excel,AcroRd32 -NoCancel -LanguageOverride de
-------------------------- EXAMPLE 5 --------------------------
PS C:\>Close Word, Excel and Adobe Acrobat Reader and perform a silent closure of these applications.
."CloseRunningProcesses_v13.ps1" -ApplicationsToClose Winword,Excel,AcroRd32 -Silent
-------------------------- EXAMPLE 6 --------------------------
PS C:\>Close all applications that can be found in the directory C:\Program Files\Microsoft Office\root\Office16
and perform a silent closure of these applications.
."CloseRunningProcesses_v13.ps1" -Directories "C:\Program Files\Microsoft Office\root\Office16" -Silent
REMARKS
To see the examples, type: "get-help C:\tmp\CloseRunningApps_v13\CloseRunningApps_v13.ps1 -examples".
For more information, type: "get-help C:\tmp\CloseRunningApps_v13\CloseRunningApps_v13.ps1 -detailed".
For technical information, type: "get-help C:\tmp\CloseRunningApps_v13\CloseRunningApps_v13.ps1 -full".
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_v13.ps1" -ApplicationsToClose Winword,Excel,AcroRd32
.EXAMPLE
Close Word, Excel and Adobe Acrobat Reader and suppress the Cancel botton.
."CloseRunningProcesses_v13.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_v13.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_v13.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_v13.ps1" -ApplicationsToClose Winword,Excel,AcroRd32 -Silent
.EXAMPLE
Close all applications that can be found in the directory C:\Program Files\Microsoft Office\root\Office16 and perform a silent closure of these applications.
."CloseRunningProcesses_v13.ps1" -Directories "C:\Program Files\Microsoft Office\root\Office16" -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
v1.2:
* Implementation Title parameter. You can specify the title of the box.
* The form leaves with an exit code:
-> (0) Ok
-> (2) Cancel
-> (4) CountDownTimerEqualsZero
* The assembly System.Windows.Threading has been renamed to System.Threading.
* The assembly WindowsCore is also loaded.
* Function Find-RunningProcessesToClose has been modified.
v1.3:
* The json file has the same name as the script. Easier for versioning.
* Implementation Directories parameter.
#>
[CmdletBinding(DefaultParameterSetName = 'Default')]
Param
(
[Parameter(HelpMessage ='Search for executables in the given directories.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[String[]] $Directories,
[Parameter(HelpMessage ='Give all the executables you want to close. Wildcards are not allowed.')]
[Parameter(Mandatory = $False, 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 = 'Custom form title.')]
[Parameter(Mandatory = $False, ParameterSetName = 'Default')]
[String] $Title = "",
[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 / Updated on 21-Jan-2021
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, @{Name="Application";Expression={$_.Description + " " + $_.ProductVersion}},@{Name="Executable";Expression={(($_."Path").split("\"))[-1]}} |Where {$_.Executable})
$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)*"
}
if (($ProcesName.Name -like $SearchItem) -or ($ProcesName.Executable -like $SearchItem))
{
$Record."Name" = $ProcesName.Name
$Record."Application" = $ProcesName.Application
$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'."
}
}
}
Function Get-AllFilesWithPattern
{
<#
.NOTES
========================================================================================================================
Created with: Windows PowerShell ISE
Created on: 13-January-2019 / Modified 12-February-2021.
Created by: Willem-Jan Vroom
Organization:
Functionname: Get-AllFilesWithPattern
========================================================================================================================
.SYNOPSIS
Find all files in the given folder that matches a filter.
#>
param
(
[string] $FolderToLookIn,
[string] $Pattern,
[Switch] $IncludeSubFolders
)
$arrItems = @()
if(test-Path $FolderToLookIn)
{
if ($IncludeSubFolders)
{
$arrItems = Get-ChildItem -Path $FolderToLookIn -Filter $Pattern | Sort-Object -Property FullName
}
else
{
$arrItems = Get-ChildItem -Path $FolderToLookIn -Filter $Pattern -Recurse -Depth 10 | Sort-Object -Property FullName
}
}
Return $arrItems
}
# =============================================================================================================================================
# End function block
# =============================================================================================================================================
# =============================================================================================================================================
# Declares the variables.
# =============================================================================================================================================
Clear-Host
$CurrentDir = Split-Path -parent $MyInvocation.MyCommand.Definition
$arrAppNames = @()
$Global:DetailedLogging = $DetailedLogging
$ApplicationVersion = "v1.3"
$CountDown = $False
$ReturnCode = 0
if($CountdownInMinutes -gt 0)
{
$CountDown = $True
}
if($Title)
{
$Title += " $ApplicationVersion"
}
# =============================================================================================================================================
# 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"
# =============================================================================================================================================
# Check if the correct parameters are used.
# =============================================================================================================================================
if(-not $Directories -and -not $ApplicationsToClose)
{
Add-EntryToLogFile -Entry "You must specify either the Directories or ApplicationsToClose parameter."
Add-EntryToLogFile -Entry "The script is closed."
Exit 9
}
# =============================================================================================================================================
# 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 + "\"+ $($MyInvocation.MyCommand.Name -replace ".ps1",".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"
# =============================================================================================================================================
# Find all the executables when the Directories parameter is used.
# =============================================================================================================================================
if($Directories)
{
ForEach ($Directory in $Directories)
{
$ApplicationsToClose += Get-AllFilesWithPattern -FolderToLookIn $Directory -Pattern "*.exe" -IncludeSubFolders
}
}
# =============================================================================================================================================
# Write all the executables to the log file
# =============================================================================================================================================
Add-EntryToLogFile -Entry "***** Write all the executables to log file. *****`r`n"
ForEach ($ApplicationToClose in $ApplicationsToClose)
{
Add-EntryToLogFile -Entry " -> Found executable: $ApplicationToClose"
}
Add-EntryToLogFile -Entry "***** End writing all the executables to the log file. *****`r`n"
# =============================================================================================================================================
# Forms Block
# =============================================================================================================================================
Add-EntryToLogFile -Entry "***** Forms part *****"
Add-Type -AssemblyName PresentationCore
Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName WindowsBase
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Threading
[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
if($Title)
{
$CloseOpenPrograms.Text = $Title
Add-EntryToLogFile "The custom title '$($CloseOpenPrograms.Text)' is used."
}
else
{
$CloseOpenPrograms.Text = "$($Translations.$Language."CloseOpenPrograms") $ApplicationVersion"
Add-EntryToLogFile "The default title '$($CloseOpenPrograms.Text)' is used."
}
$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
{
$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.Tag = 0
$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.Tag = 2
$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
$CloseOpenPrograms.Tag = 4
$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"
Add-EntryToLogFile -Entry "Exitcode: $($CloseOpenPrograms.Tag)"
Exit $($CloseOpenPrograms.Tag)
}
else
{
Add-EntryToLogFile -Entry "The following applications will be silently closed:"
CloseRunningProcesses -AppNames $arrAppNames
Add-EntryToLogFile -Entry "***** End forms part *****`r`n"
Add-EntryToLogFile -Entry "Exitcode: $($CloseOpenPrograms.Tag)"
Exit $($CloseOpenPrograms.Tag)
}
}
else
{
Add-EntryToLogFile "There are no applications to be closed."
Add-EntryToLogFile -Entry "***** End forms part *****`r`n"
Add-EntryToLogFile -Entry "Exitcode: $ReturnCode"
Exit 0
}
And CloseRunningApps_v13.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:"
}
}