From 630377d0bd0960a3ac914f389322db4383ca39c8 Mon Sep 17 00:00:00 2001
From: zoicware <118035521+zoicware@users.noreply.github.com>
Date: Mon, 12 Jan 2026 16:10:13 -0500
Subject: [PATCH] add new classic apps options
---
RemoveWindowsAi.ps1 | 916 +++++++++++++++++++++++++++++++++++---------
1 file changed, 735 insertions(+), 181 deletions(-)
diff --git a/RemoveWindowsAi.ps1 b/RemoveWindowsAi.ps1
index 7da7e7b..fbfc407 100644
--- a/RemoveWindowsAi.ps1
+++ b/RemoveWindowsAi.ps1
@@ -14,11 +14,13 @@ param(
[array]$Options,
[switch]$AllOptions,
[switch]$revertMode,
- [switch]$backupMode
+ [switch]$backupMode,
+ [ValidateSet('photoviewer', 'mspaint', 'snippingtool', 'notepad', 'photoslegacy')]
+ [array]$InstallClassicApps
)
if ($nonInteractive) {
- if (!($AllOptions) -and (!$Options -or $Options.Count -eq 0)) {
+ if (!($AllOptions) -and (!$Options -or $Options.Count -eq 0) -and !($InstallClassicApps)) {
throw 'Non-Interactive mode was supplied without any options... Please use -Options or -AllOptions when using Non-Interactive Mode'
exit
}
@@ -58,6 +60,10 @@ If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]:
$arglist = $arglist + " -Options $Options"
}
}
+
+ if ($InstallClassicApps -and $InstallClassicApps.Count -ne 0) {
+ $arglist = $arglist + " -InstallClassicApps $InstallClassicApps"
+ }
}
if ($EnableLogging) {
@@ -999,183 +1005,184 @@ function Disable-Copilot-Policies {
}
+#function from: https://github.com/Andrew-J-Larson/OS-Scripts/blob/main/Windows/Wrapper-Functions/Download-AppxPackage-Function.ps1
+function Download-AppxPackage {
+ param(
+ # there has to be an alternative, as sometimes the API fails on PackageFamilyName
+ [string]$PackageFamilyName,
+ [string]$ProductId,
+ [string]$outputDir
+ )
+ if (-Not ($PackageFamilyName -Or $ProductId)) {
+ # can't do anything without at least one
+ Write-Error 'Missing either PackageFamilyName or ProductId.'
+ return $null
+ }
+
+ try {
+ $UserAgent = [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome # needed as sometimes the API will block things when it knows requests are coming from PowerShell
+ }
+ catch {
+ #ignore error
+ }
+
+ $DownloadedFiles = @()
+ $errored = $false
+ $allFilesDownloaded = $true
+
+ $apiUrl = 'https://store.rg-adguard.net/api/GetFiles'
+ $versionRing = 'Retail'
+
+ $architecture = switch ($env:PROCESSOR_ARCHITECTURE) {
+ 'x86' { 'x86' }
+ { @('x64', 'amd64') -contains $_ } { 'x64' }
+ 'arm' { 'arm' }
+ 'arm64' { 'arm64' }
+ default { 'neutral' } # should never get here
+ }
+
+ if (Test-Path $outputDir -PathType Container) {
+ New-Item -Path "$outputDir\$PackageFamilyName" -ItemType Directory -Force | Out-Null
+ $downloadFolder = "$outputDir\$PackageFamilyName"
+ }
+ else {
+ $downloadFolder = Join-Path $env:TEMP $PackageFamilyName
+ if (!(Test-Path $downloadFolder -PathType Container)) {
+ New-Item $downloadFolder -ItemType Directory -Force | Out-Null
+ }
+ }
+
+ $body = @{
+ type = if ($ProductId) { 'ProductId' } else { 'PackageFamilyName' }
+ url = if ($ProductId) { $ProductId } else { $PackageFamilyName }
+ ring = $versionRing
+ lang = 'en-US'
+ }
+
+ # required due to the api being protected behind Cloudflare now
+ if (-Not $apiWebSession) {
+ $global:apiWebSession = $null
+ $apiHostname = (($apiUrl.split('/'))[0..2]) -Join '/'
+ Invoke-WebRequest -Uri $apiHostname -UserAgent $UserAgent -SessionVariable $apiWebSession -UseBasicParsing
+ }
+
+ $raw = $null
+ try {
+ $raw = Invoke-RestMethod -Method Post -Uri $apiUrl -ContentType 'application/x-www-form-urlencoded' -Body $body -UserAgent $UserAgent -WebSession $apiWebSession
+ }
+ catch {
+ $errorMsg = 'An error occurred: ' + $_
+ Write-Host $errorMsg
+ $errored = $true
+ return $false
+ }
+
+ # hashtable of packages by $name
+ # > values = hashtables of packages by $version
+ # > values = arrays of packages as objects (containing: url, filename, name, version, arch, publisherId, type)
+ [Collections.Generic.Dictionary[string, Collections.Generic.Dictionary[string, array]]] $packageList = @{}
+ # populate $packageList
+ $patternUrlAndText = '
.*)"\s.*>(?.*\.(app|msi)x.*)<\/a>'
+ $raw | Select-String $patternUrlAndText -AllMatches | ForEach-Object { $_.Matches } | ForEach-Object {
+ $url = ($_.Groups['url']).Value
+ $text = ($_.Groups['text']).Value
+ $textSplitUnderscore = $text.split('_')
+ $name = $textSplitUnderscore.split('_')[0]
+ $version = $textSplitUnderscore.split('_')[1]
+ $arch = ($textSplitUnderscore.split('_')[2]).ToLower()
+ $publisherId = ($textSplitUnderscore.split('_')[4]).split('.')[0]
+ $textSplitPeriod = $text.split('.')
+ $type = ($textSplitPeriod[$textSplitPeriod.length - 1]).ToLower()
+
+ # create $name hash key hashtable, if it doesn't already exist
+ if (!($packageList.keys -match ('^' + [Regex]::escape($name) + '$'))) {
+ $packageList["$name"] = @{}
+ }
+ # create $version hash key array, if it doesn't already exist
+ if (!(($packageList["$name"]).keys -match ('^' + [Regex]::escape($version) + '$'))) {
+ ($packageList["$name"])["$version"] = @()
+ }
+
+ # add package to the array in the hashtable
+ ($packageList["$name"])["$version"] += @{
+ url = $url
+ filename = $text
+ name = $name
+ version = $version
+ arch = $arch
+ publisherId = $publisherId
+ type = $type
+ }
+ }
+
+ # an array of packages as objects, meant to only contain one of each $name
+ $latestPackages = @()
+ # grabs the most updated package for $name and puts it into $latestPackages
+ $packageList.GetEnumerator() | ForEach-Object { ($_.value).GetEnumerator() | Select-Object -Last 1 } | ForEach-Object {
+ $packagesByType = $_.value
+ $msixbundle = ($packagesByType | Where-Object { $_.type -match '^msixbundle$' })
+ $appxbundle = ($packagesByType | Where-Object { $_.type -match '^appxbundle$' })
+ $msix = ($packagesByType | Where-Object { ($_.type -match '^msix$') -And ($_.arch -match ('^' + [Regex]::Escape($architecture) + '$')) })
+ $appx = ($packagesByType | Where-Object { ($_.type -match '^appx$') -And ($_.arch -match ('^' + [Regex]::Escape($architecture) + '$')) })
+ if ($msixbundle) { $latestPackages += $msixbundle }
+ elseif ($appxbundle) { $latestPackages += $appxbundle }
+ elseif ($msix) { $latestPackages += $msix }
+ elseif ($appx) { $latestPackages += $appx }
+ }
+
+ # download packages
+ $latestPackages | ForEach-Object {
+ $url = $_.url
+ $filename = $_.filename
+ # TODO: may need to include detection in the future of expired package download URLs..... in the case that downloads take over 10 minutes to complete
+
+ $downloadFile = Join-Path $downloadFolder $filename
+
+ # If file already exists, ask to replace it
+ if (Test-Path $downloadFile) {
+ Write-Host "`"${filename}`" already exists at `"${downloadFile}`"."
+ $confirmation = ''
+ while (!(($confirmation -eq 'Y') -Or ($confirmation -eq 'N'))) {
+ $confirmation = Read-Host "`nWould you like to re-download and overwrite the file at `"${downloadFile}`" (Y/N)?"
+ $confirmation = $confirmation.ToUpper()
+ }
+ if ($confirmation -eq 'Y') {
+ Remove-Item -Path $downloadFile -Force
+ }
+ else {
+ $DownloadedFiles += $downloadFile
+ }
+ }
+
+ if (!(Test-Path $downloadFile)) {
+ # Write-Host "Attempting download of `"${filename}`" to `"${downloadFile}`" . . ."
+ $fileDownloaded = $null
+ $PreviousProgressPreference = $ProgressPreference
+ $ProgressPreference = 'SilentlyContinue' # avoids slow download when using Invoke-WebRequest
+ try {
+ Invoke-WebRequest -Uri $url -OutFile $downloadFile
+ $fileDownloaded = $?
+ }
+ catch {
+ $ProgressPreference = $PreviousProgressPreference # return ProgressPreference back to normal
+ $errorMsg = 'An error occurred: ' + $_
+ Write-Host $errorMsg
+ $errored = $true
+ break $false
+ }
+ $ProgressPreference = $PreviousProgressPreference # return ProgressPreference back to normal
+ if ($fileDownloaded) { $DownloadedFiles += $downloadFile }
+ else { $allFilesDownloaded = $false }
+ }
+ }
+
+ if ($errored) { Write-Host 'Completed with some errors.' }
+ if (-Not $allFilesDownloaded) { Write-Host 'Warning: Not all packages could be downloaded.' }
+ return $DownloadedFiles
+}
+
function Remove-AI-Appx-Packages {
- #function from: https://github.com/Andrew-J-Larson/OS-Scripts/blob/main/Windows/Wrapper-Functions/Download-AppxPackage-Function.ps1
- function Download-AppxPackage {
- param(
- # there has to be an alternative, as sometimes the API fails on PackageFamilyName
- [string]$PackageFamilyName,
- [string]$ProductId,
- [string]$outputDir
- )
- if (-Not ($PackageFamilyName -Or $ProductId)) {
- # can't do anything without at least one
- Write-Error 'Missing either PackageFamilyName or ProductId.'
- return $null
- }
-
- try {
- $UserAgent = [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome # needed as sometimes the API will block things when it knows requests are coming from PowerShell
- }
- catch {
- #ignore error
- }
-
- $DownloadedFiles = @()
- $errored = $false
- $allFilesDownloaded = $true
-
- $apiUrl = 'https://store.rg-adguard.net/api/GetFiles'
- $versionRing = 'Retail'
-
- $architecture = switch ($env:PROCESSOR_ARCHITECTURE) {
- 'x86' { 'x86' }
- { @('x64', 'amd64') -contains $_ } { 'x64' }
- 'arm' { 'arm' }
- 'arm64' { 'arm64' }
- default { 'neutral' } # should never get here
- }
-
- if (Test-Path $outputDir -PathType Container) {
- New-Item -Path "$outputDir\$PackageFamilyName" -ItemType Directory -Force | Out-Null
- $downloadFolder = "$outputDir\$PackageFamilyName"
- }
- else {
- $downloadFolder = Join-Path $env:TEMP $PackageFamilyName
- if (!(Test-Path $downloadFolder -PathType Container)) {
- New-Item $downloadFolder -ItemType Directory -Force | Out-Null
- }
- }
-
- $body = @{
- type = if ($ProductId) { 'ProductId' } else { 'PackageFamilyName' }
- url = if ($ProductId) { $ProductId } else { $PackageFamilyName }
- ring = $versionRing
- lang = 'en-US'
- }
-
- # required due to the api being protected behind Cloudflare now
- if (-Not $apiWebSession) {
- $global:apiWebSession = $null
- $apiHostname = (($apiUrl.split('/'))[0..2]) -Join '/'
- Invoke-WebRequest -Uri $apiHostname -UserAgent $UserAgent -SessionVariable $apiWebSession -UseBasicParsing
- }
-
- $raw = $null
- try {
- $raw = Invoke-RestMethod -Method Post -Uri $apiUrl -ContentType 'application/x-www-form-urlencoded' -Body $body -UserAgent $UserAgent -WebSession $apiWebSession
- }
- catch {
- $errorMsg = 'An error occurred: ' + $_
- Write-Host $errorMsg
- $errored = $true
- return $false
- }
-
- # hashtable of packages by $name
- # > values = hashtables of packages by $version
- # > values = arrays of packages as objects (containing: url, filename, name, version, arch, publisherId, type)
- [Collections.Generic.Dictionary[string, Collections.Generic.Dictionary[string, array]]] $packageList = @{}
- # populate $packageList
- $patternUrlAndText = '.*)"\s.*>(?.*\.(app|msi)x.*)<\/a>'
- $raw | Select-String $patternUrlAndText -AllMatches | ForEach-Object { $_.Matches } | ForEach-Object {
- $url = ($_.Groups['url']).Value
- $text = ($_.Groups['text']).Value
- $textSplitUnderscore = $text.split('_')
- $name = $textSplitUnderscore.split('_')[0]
- $version = $textSplitUnderscore.split('_')[1]
- $arch = ($textSplitUnderscore.split('_')[2]).ToLower()
- $publisherId = ($textSplitUnderscore.split('_')[4]).split('.')[0]
- $textSplitPeriod = $text.split('.')
- $type = ($textSplitPeriod[$textSplitPeriod.length - 1]).ToLower()
-
- # create $name hash key hashtable, if it doesn't already exist
- if (!($packageList.keys -match ('^' + [Regex]::escape($name) + '$'))) {
- $packageList["$name"] = @{}
- }
- # create $version hash key array, if it doesn't already exist
- if (!(($packageList["$name"]).keys -match ('^' + [Regex]::escape($version) + '$'))) {
- ($packageList["$name"])["$version"] = @()
- }
-
- # add package to the array in the hashtable
- ($packageList["$name"])["$version"] += @{
- url = $url
- filename = $text
- name = $name
- version = $version
- arch = $arch
- publisherId = $publisherId
- type = $type
- }
- }
-
- # an array of packages as objects, meant to only contain one of each $name
- $latestPackages = @()
- # grabs the most updated package for $name and puts it into $latestPackages
- $packageList.GetEnumerator() | ForEach-Object { ($_.value).GetEnumerator() | Select-Object -Last 1 } | ForEach-Object {
- $packagesByType = $_.value
- $msixbundle = ($packagesByType | Where-Object { $_.type -match '^msixbundle$' })
- $appxbundle = ($packagesByType | Where-Object { $_.type -match '^appxbundle$' })
- $msix = ($packagesByType | Where-Object { ($_.type -match '^msix$') -And ($_.arch -match ('^' + [Regex]::Escape($architecture) + '$')) })
- $appx = ($packagesByType | Where-Object { ($_.type -match '^appx$') -And ($_.arch -match ('^' + [Regex]::Escape($architecture) + '$')) })
- if ($msixbundle) { $latestPackages += $msixbundle }
- elseif ($appxbundle) { $latestPackages += $appxbundle }
- elseif ($msix) { $latestPackages += $msix }
- elseif ($appx) { $latestPackages += $appx }
- }
-
- # download packages
- $latestPackages | ForEach-Object {
- $url = $_.url
- $filename = $_.filename
- # TODO: may need to include detection in the future of expired package download URLs..... in the case that downloads take over 10 minutes to complete
-
- $downloadFile = Join-Path $downloadFolder $filename
-
- # If file already exists, ask to replace it
- if (Test-Path $downloadFile) {
- Write-Host "`"${filename}`" already exists at `"${downloadFile}`"."
- $confirmation = ''
- while (!(($confirmation -eq 'Y') -Or ($confirmation -eq 'N'))) {
- $confirmation = Read-Host "`nWould you like to re-download and overwrite the file at `"${downloadFile}`" (Y/N)?"
- $confirmation = $confirmation.ToUpper()
- }
- if ($confirmation -eq 'Y') {
- Remove-Item -Path $downloadFile -Force
- }
- else {
- $DownloadedFiles += $downloadFile
- }
- }
-
- if (!(Test-Path $downloadFile)) {
- # Write-Host "Attempting download of `"${filename}`" to `"${downloadFile}`" . . ."
- $fileDownloaded = $null
- $PreviousProgressPreference = $ProgressPreference
- $ProgressPreference = 'SilentlyContinue' # avoids slow download when using Invoke-WebRequest
- try {
- Invoke-WebRequest -Uri $url -OutFile $downloadFile
- $fileDownloaded = $?
- }
- catch {
- $ProgressPreference = $PreviousProgressPreference # return ProgressPreference back to normal
- $errorMsg = 'An error occurred: ' + $_
- Write-Host $errorMsg
- $errored = $true
- break $false
- }
- $ProgressPreference = $PreviousProgressPreference # return ProgressPreference back to normal
- if ($fileDownloaded) { $DownloadedFiles += $downloadFile }
- else { $allFilesDownloaded = $false }
- }
- }
-
- if ($errored) { Write-Host 'Completed with some errors.' }
- if (-Not $allFilesDownloaded) { Write-Host 'Warning: Not all packages could be downloaded.' }
- return $DownloadedFiles
- }
if ($revert) {
@@ -2250,6 +2257,380 @@ Get-ScheduledTask -TaskName "*Office Actions Server*" -ErrorAction SilentlyConti
}
+function install-photoviewer {
+
+ #restore classic photoviewer
+ $extensions = @('.Bmp', '.Cr2', '.Dib', '.Gif', '.JFIF', '.Jpe', '.Jpeg', '.Jpg', '.Jxr', '.Png', '.Tif', '.Tiff', '.Wdp')
+
+ foreach ($ext in $extensions) {
+ if ($ext -in @('.JFIF', '.Jpeg', '.Gif', '.Png', '.Wdp')) {
+ reg.exe add "HKLM\SOFTWARE\Classes\PhotoViewer.FileAssoc$ext" /v 'EditFlags' /t REG_DWORD /d 65536 /f >$null
+ reg.exe add "HKLM\SOFTWARE\Classes\PhotoViewer.FileAssoc$ext" /v 'ImageOptionFlags' /t REG_DWORD /d 1 /f >$null
+ reg.exe add "HKLM\SOFTWARE\Classes\PhotoViewer.FileAssoc$ext" /v 'FriendlyTypeName' /t REG_EXPAND_SZ /d '@%ProgramFiles%\Windows Photo Viewer\PhotoViewer.dll,-3055' /f >$null
+ reg.exe add "HKLM\SOFTWARE\Classes\PhotoViewer.FileAssoc$ext\DefaultIcon" /ve /t REG_SZ /d '%SystemRoot%\System32\imageres.dll,-72' /f >$null
+ reg.exe add "HKLM\SOFTWARE\Classes\PhotoViewer.FileAssoc$ext\shell\open" /v 'MuiVerb' /t REG_EXPAND_SZ /d '@%ProgramFiles%\Windows Photo Viewer\photoviewer.dll,-3043' /f >$null
+ reg.exe add "HKLM\SOFTWARE\Classes\PhotoViewer.FileAssoc$ext\shell\open\command" /ve /t REG_EXPAND_SZ /d "%SystemRoot%\System32\rundll32.exe \`"%ProgramFiles%\Windows Photo Viewer\PhotoViewer.dll\`", ImageView_Fullscreen %1" /f >$null
+ reg.exe add "HKLM\SOFTWARE\Classes\PhotoViewer.FileAssoc$ext\shell\open\DropTarget" /v 'Clsid' /t REG_SZ /d '{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}' /f >$null
+ }
+
+ if ($ext -in @('.Cr2', '.Tif')) {
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations' /v $ext.ToLower() /t REG_SZ /d 'PhotoViewer.FileAssoc.Tiff' /f >$null
+ }
+ elseif ($ext -in @('.Dib', '.Bmp')) {
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations' /v $ext.ToLower() /t REG_SZ /d 'PhotoViewer.FileAssoc.Bitmap' /f >$null
+ }
+ elseif ($ext -in @('.Jpg', '.Jpe', '.Jpeg')) {
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations' /v $ext.ToLower() /t REG_SZ /d 'PhotoViewer.FileAssoc.Jpeg' /f >$null
+ }
+ else {
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations' /v $ext.ToLower() /t REG_SZ /d "PhotoViewer.FileAssoc$ext" /f >$null
+ }
+ }
+}
+
+function install-paint {
+ param(
+ [string]$path
+ )
+
+ get-appxpackage '*Microsoft.Paint*' | Remove-AppxPackage -AllUsers -ErrorAction SilentlyContinue
+
+ $command = "
+ copy-item `"$path\paint\mspaint.exe`" -Destination `"$env:systemroot\system32\mspaint.exe`" -Force
+ copy-item `"$path\paint\mspaint.exe.mui`" -Destination `"$env:systemroot\System32\en-US\mspaint.exe.mui`" -Force
+ copy-item `"$path\paint\mspaint.exe.mun`" -Destination `"$env:systemroot\SystemResources`" -Force
+"
+ Run-Trusted -command $command
+ Start-Sleep 1
+
+ $command = "regedit.exe /s `"$path\paint\paint.reg`""
+ Run-Trusted -command $command
+
+ $langID = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Language' -Name 'InstallLanguage').InstallLanguage
+ $languageMap = @{
+ '0804' = @{PAD = 'zh-CN'; Name = 'Chinese (Simplified)' }
+ '0412' = @{PAD = 'ko-KR'; Name = 'Korean' }
+ '0404' = @{PAD = 'zh-TW'; Name = 'Chinese (Traditional)' }
+ '0422' = @{PAD = 'uk-UA'; Name = 'Ukrainian' }
+ '041f' = @{PAD = 'tr-TR'; Name = 'Turkish' }
+ '041e' = @{PAD = 'th-TH'; Name = 'Thai' }
+ '241a' = @{PAD = 'sr-Latn-RS'; Name = 'Serbian (Latin)' }
+ '0424' = @{PAD = 'sl-SI'; Name = 'Slovenian' }
+ '041b' = @{PAD = 'sk-SK'; Name = 'Slovak' }
+ '0419' = @{PAD = 'ru-RU'; Name = 'Russian' }
+ '0418' = @{PAD = 'ro-RO'; Name = 'Romanian' }
+ '0816' = @{PAD = 'pt-PT'; Name = 'Portuguese (Portugal)' }
+ '0416' = @{PAD = 'pt-BR'; Name = 'Portuguese (Brazil)' }
+ '0415' = @{PAD = 'pl-PL'; Name = 'Polish' }
+ '0413' = @{PAD = 'nl-NL'; Name = 'Dutch' }
+ '0414' = @{PAD = 'nb-NO'; Name = 'Norwegian' }
+ '0426' = @{PAD = 'lv-LV'; Name = 'Latvian' }
+ '0427' = @{PAD = 'lt-LT'; Name = 'Lithuanian' }
+ '0411' = @{PAD = 'ja-JP'; Name = 'Japanese' }
+ '0410' = @{PAD = 'it-IT'; Name = 'Italian' }
+ '040e' = @{PAD = 'hu-HU'; Name = 'Hungarian' }
+ '041a' = @{PAD = 'hr-HR'; Name = 'Croatian' }
+ '040d' = @{PAD = 'he-IL'; Name = 'Hebrew' }
+ '040c' = @{PAD = 'fr-FR'; Name = 'French (France)' }
+ '0c0c' = @{PAD = 'fr-CA'; Name = 'French (Canada)' }
+ '040b' = @{PAD = 'fi-FI'; Name = 'Finnish' }
+ '0425' = @{PAD = 'et-EE'; Name = 'Estonian' }
+ '080a' = @{PAD = 'es-MX'; Name = 'Spanish (Mexico)' }
+ '040a' = @{PAD = 'es-ES'; Name = 'Spanish (Spain)' }
+ '0809' = @{PAD = 'en-GB'; Name = 'English (UK)' }
+ '0408' = @{PAD = 'el-GR'; Name = 'Greek' }
+ '0407' = @{PAD = 'de-DE'; Name = 'German' }
+ '0406' = @{PAD = 'da-DK'; Name = 'Danish' }
+ '0405' = @{PAD = 'cs-CZ'; Name = 'Czech' }
+ '0402' = @{PAD = 'bg-BG'; Name = 'Bulgarian' }
+ '0401' = @{PAD = 'ar-SA'; Name = 'Arabic' }
+ '041d' = @{PAD = 'sv-SE'; Name = 'Swedish' }
+ }
+
+ if ($languageMap.ContainsKey($langID)) {
+ $lang = $languageMap[$langID]
+ $pad = $lang.PAD
+
+ # Copy language specific MUI file
+ $command = "Copy-Item -Path `"$path\paint\paint_lang_files\$pad\mspaint.exe.mui`" -Destination `"$env:SYSTEMROOT\System32\$pad\mspaint.exe.mui`" -Force"
+ Run-Trusted -command $command
+
+ Write-Status -msg "Copied $pad language file"
+ }
+
+
+ #create start shortcut
+ $WshShell = New-Object -comObject WScript.Shell
+ $Shortcut = $WshShell.CreateShortcut('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Paint.lnk')
+ $Shortcut.TargetPath = 'C:\Windows\System32\mspaint.exe'
+ $Shortcut.Save()
+
+}
+
+function install-snipping {
+ param(
+ [string]$path
+ )
+ # uninstall uwp
+ Get-AppxPackage '*ScreenSketch*' -ErrorAction SilentlyContinue | Remove-AppxPackage -ErrorAction SilentlyContinue
+
+ $command = "
+ copy-item `"$path\snipping\SnippingTool.exe`" -Destination `"$env:systemroot\system32\SnippingTool.exe`" -Force
+ copy-item `"$path\snipping\SnippingTool.exe.mui`" -Destination `"$env:systemroot\System32\en-US\SnippingTool.exe.mui`" -Force
+"
+ Run-Trusted -command $command
+ Start-Sleep 1
+
+ $langID = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Language' -Name 'InstallLanguage').InstallLanguage
+ $languageMap = @{
+ '0804' = @{PAD = 'zh-CN'; Name = 'Chinese (Simplified)' }
+ '0412' = @{PAD = 'ko-KR'; Name = 'Korean' }
+ '0404' = @{PAD = 'zh-TW'; Name = 'Chinese (Traditional)' }
+ '0422' = @{PAD = 'uk-UA'; Name = 'Ukrainian' }
+ '041f' = @{PAD = 'tr-TR'; Name = 'Turkish' }
+ '041e' = @{PAD = 'th-TH'; Name = 'Thai' }
+ '241a' = @{PAD = 'sr-Latn-RS'; Name = 'Serbian (Latin)' }
+ '0424' = @{PAD = 'sl-SI'; Name = 'Slovenian' }
+ '041b' = @{PAD = 'sk-SK'; Name = 'Slovak' }
+ '0419' = @{PAD = 'ru-RU'; Name = 'Russian' }
+ '0418' = @{PAD = 'ro-RO'; Name = 'Romanian' }
+ '0816' = @{PAD = 'pt-PT'; Name = 'Portuguese (Portugal)' }
+ '0416' = @{PAD = 'pt-BR'; Name = 'Portuguese (Brazil)' }
+ '0415' = @{PAD = 'pl-PL'; Name = 'Polish' }
+ '0413' = @{PAD = 'nl-NL'; Name = 'Dutch' }
+ '0414' = @{PAD = 'nb-NO'; Name = 'Norwegian' }
+ '0426' = @{PAD = 'lv-LV'; Name = 'Latvian' }
+ '0427' = @{PAD = 'lt-LT'; Name = 'Lithuanian' }
+ '0411' = @{PAD = 'ja-JP'; Name = 'Japanese' }
+ '0410' = @{PAD = 'it-IT'; Name = 'Italian' }
+ '040e' = @{PAD = 'hu-HU'; Name = 'Hungarian' }
+ '041a' = @{PAD = 'hr-HR'; Name = 'Croatian' }
+ '040d' = @{PAD = 'he-IL'; Name = 'Hebrew' }
+ '040c' = @{PAD = 'fr-FR'; Name = 'French (France)' }
+ '0c0c' = @{PAD = 'fr-CA'; Name = 'French (Canada)' }
+ '040b' = @{PAD = 'fi-FI'; Name = 'Finnish' }
+ '0425' = @{PAD = 'et-EE'; Name = 'Estonian' }
+ '080a' = @{PAD = 'es-MX'; Name = 'Spanish (Mexico)' }
+ '040a' = @{PAD = 'es-ES'; Name = 'Spanish (Spain)' }
+ '0809' = @{PAD = 'en-GB'; Name = 'English (UK)' }
+ '0408' = @{PAD = 'el-GR'; Name = 'Greek' }
+ '0407' = @{PAD = 'de-DE'; Name = 'German' }
+ '0406' = @{PAD = 'da-DK'; Name = 'Danish' }
+ '0405' = @{PAD = 'cs-CZ'; Name = 'Czech' }
+ '0402' = @{PAD = 'bg-BG'; Name = 'Bulgarian' }
+ '0401' = @{PAD = 'ar-SA'; Name = 'Arabic' }
+ '041d' = @{PAD = 'sv-SE'; Name = 'Swedish' }
+ }
+
+ if ($languageMap.ContainsKey($langID)) {
+ $lang = $languageMap[$langID]
+ $pad = $lang.PAD
+
+ # Copy language specific MUI file
+ $command = "Copy-Item -Path `"$path\snipping\snipping_lang_files\$pad\SnippingTool.exe.mui`" -Destination `"$env:SYSTEMROOT\System32\$pad\SnippingTool.exe.mui`" -Force"
+ Run-Trusted -command $command
+
+ Write-Status -msg "Copied $pad language file"
+
+ }
+
+
+ $WshShell = New-Object -comObject WScript.Shell
+ $Shortcut = $WshShell.CreateShortcut('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\SnippingTool.lnk')
+ $Shortcut.TargetPath = ('C:\Windows\System32\SnippingTool.exe')
+ $Shortcut.Save()
+
+}
+
+
+function install-notepad {
+
+ #uninstall new notepad
+ taskkill.exe /im notepad.exe /f *>$null
+ taskkill.exe /im dllhost.exe /f *>$null
+ get-appxpackage '*notepad*' | Remove-AppxPackage -AllUsers -ErrorAction SilentlyContinue
+ #enable win10 notepad
+ Add-WindowsCapability -Online -Name Microsoft.Windows.Notepad.System~~~~0.0.1.0 -LimitAccess | Out-Null
+ # fix registry
+ Remove-Item -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\App Paths\notepad.exe' -Force -ErrorAction SilentlyContinue
+ Remove-ItemProperty -Path 'HKLM:\SOFTWARE\Classes\Applications\notepad.exe' -Name NoOpenWith -Force -ErrorAction SilentlyContinue
+ reg.exe add 'HKLM\SOFTWARE\Classes\*\OpenWithList\notepad.exe' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.htm\OpenWithList' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.htm\OpenWithList\notepad.exe' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.inf' /ve /t REG_SZ /d 'inffile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.ini' /ve /t REG_SZ /d 'inifile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.log' /ve /t REG_SZ /d 'txtfile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.ps1' /ve /t REG_SZ /d 'Microsoft.PowerShellScript.1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.psd1' /ve /t REG_SZ /d 'Microsoft.PowerShellData.1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.psm1' /ve /t REG_SZ /d 'Microsoft.PowerShellModule.1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.scp' /ve /t REG_SZ /d 'txtfile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.txt' /ve /t REG_SZ /d 'txtfile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.txt\ShellNew' /v 'ItemName' /t REG_EXPAND_SZ /d '@%SystemRoot%\system32\notepad.exe,-470' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.txt\ShellNew' /v 'NullFile' /t REG_SZ /d ' ' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\.wtx' /ve /t REG_SZ /d 'txtfile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Applications\notepad.exe' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Applications\notepad.exe\shell' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Applications\notepad.exe\shell\edit' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Applications\notepad.exe\shell\edit\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Applications\notepad.exe\shell\open' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Applications\notepad.exe\shell\open\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inffile' /ve /t REG_SZ /d 'Setup Information' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inffile' /v 'FriendlyTypeName' /t REG_EXPAND_SZ /d '@%SystemRoot%\System32\setupapi.dll,-2000' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inffile\DefaultIcon' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\System32\imageres.dll,-69' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inffile\shell' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inffile\shell\open' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inffile\shell\open\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inffile\shell\print' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inffile\shell\print\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE /p %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inifile' /ve /t REG_SZ /d 'Configuration Settings' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inifile' /v 'EditFlags' /t REG_DWORD /d 0x00200000 /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inifile' /v 'FriendlyTypeName' /t REG_SZ /d '@shell32.dll,-10151' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inifile\DefaultIcon' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\imageres.dll,-69' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inifile\shell' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inifile\shell\open' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inifile\shell\open\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inifile\shell\print' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\inifile\shell\print\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE /p %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellData.1' /v 'EditFlags' /t REG_DWORD /d 0x00020000 /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellData.1' /v 'FriendlyTypeName' /t REG_EXPAND_SZ /d "@\`"%systemroot%\system32\windowspowershell\v1.0\powershell.exe\`",-104" /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellData.1\Shell' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellData.1\Shell\Open' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellData.1\Shell\Open\Command' /ve /t REG_SZ /d "\`"C:\Windows\System32\notepad.exe\`" \`"%1\`"" /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellModule.1' /v 'EditFlags' /t REG_DWORD /d 0x00020000 /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellModule.1' /v 'FriendlyTypeName' /t REG_EXPAND_SZ /d "@\`"%systemroot%\system32\windowspowershell\v1.0\powershell.exe\`",-106" /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellModule.1\Shell' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellModule.1\Shell\Open' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellModule.1\Shell\Open\Command' /ve /t REG_SZ /d "\`"C:\Windows\System32\notepad.exe\`" \`"%1\`"" /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellScript.1' /v 'EditFlags' /t REG_DWORD /d 0x00020000 /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellScript.1' /v 'FriendlyTypeName' /t REG_EXPAND_SZ /d "@\`"%systemroot%\system32\windowspowershell\v1.0\powershell.exe\`",-103" /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellScript.1\DefaultIcon' /ve /t REG_SZ /d "\`"C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe\`",1" /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell\Open' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell\Open\Command' /ve /t REG_SZ /d "\`"C:\Windows\System32\notepad.exe\`" \`"%1\`"" /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\SystemFileAssociations\text\OpenWithList' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\SystemFileAssociations\text\OpenWithList\Notepad.exe' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\SystemFileAssociations\text\shell' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\SystemFileAssociations\text\shell\edit' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\SystemFileAssociations\text\shell\edit\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\SystemFileAssociations\text\shell\open' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\SystemFileAssociations\text\shell\open\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile' /ve /t REG_SZ /d 'Text Document' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile' /v 'EditFlags' /t REG_DWORD /d 0x00210000 /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile' /v 'FriendlyTypeName' /t REG_EXPAND_SZ /d '@%SystemRoot%\system32\notepad.exe,-469' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile\DefaultIcon' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\imageres.dll,-102' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile\shell' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile\shell\open' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile\shell\open\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile\shell\print' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile\shell\print\command' /ve /t REG_EXPAND_SZ /d '%SystemRoot%\system32\NOTEPAD.EXE /p %1' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile\shell\printto' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Classes\txtfile\shell\printto\command' /ve /t REG_EXPAND_SZ /d "%SystemRoot%\system32\notepad.exe /pt \`"%1\`" \`"%2\`" \`"%3\`" \`"%4\`"" /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows\Notepad' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows\Notepad\Capabilities' /v 'ApplicationDescription' /t REG_EXPAND_SZ /d '@%SystemRoot%\system32\NOTEPAD.EXE,-9' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows\Notepad\Capabilities' /v 'ApplicationName' /t REG_EXPAND_SZ /d '@%SystemRoot%\system32\NOTEPAD.EXE,-9' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows\Notepad\Capabilities\FileAssociations' /v '.ini' /t REG_SZ /d 'inifile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows\Notepad\Capabilities\FileAssociations' /v '.log' /t REG_SZ /d 'logfile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows\Notepad\Capabilities\FileAssociations' /v '.scp' /t REG_SZ /d 'scpfile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows\Notepad\Capabilities\FileAssociations' /v '.txt' /t REG_SZ /d 'txtfile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\Microsoft\Windows\Notepad\Capabilities\FileAssociations' /v '.wtx' /t REG_SZ /d 'wtxfile' /f >$null
+ reg.exe add 'HKLM\SOFTWARE\RegisteredApplications' /v 'Notepad' /t REG_SZ /d 'Software\Microsoft\Windows\Notepad\Capabilities' /f >$null
+ reg.exe add 'HKCU\Software\Microsoft\Notepad' /v 'ShowStoreBanner' /t REG_DWORD /d 0x00000000 /f >$null
+
+ #create start shortcut
+ $WshShell = New-Object -comObject WScript.Shell
+ $Shortcut = $WshShell.CreateShortcut('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Notepad.lnk')
+ $Shortcut.TargetPath = 'C:\Windows\System32\Notepad.exe'
+ $Shortcut.Save()
+
+}
+
+function install-photoslegacy {
+
+ $appx = Get-AppxPackage -AllUsers | Where-Object { $_.PackageFullName -like '*PhotosLegacy*' }
+
+ if (!$appx) {
+ Remove-Item "$env:TEMP\Microsoft.PhotosLegacy_8wekyb3d8bbwe*" -Force -Recurse -ErrorAction SilentlyContinue
+ $downloadedfiles = Download-AppxPackage -PackageFamilyName 'Microsoft.PhotosLegacy_8wekyb3d8bbwe' -outputDir "$env:TEMP"
+ $package = $downloadedfiles | Where-Object { $_ -match '\.appxbundle$' } | Select-Object -First 1
+ $dependencies = $downloadedfiles | Where-Object { $_ -match '\.appx$' }
+ if ($package) {
+ try {
+ Add-AppPackage $package -DependencyPath $dependencies -ForceApplicationShutdown
+ }
+ catch {
+ Write-status -msg "Can't install PhotosLegacy via appxbundle... make sure you have the appx service enabled" -errorOutput
+ }
+
+ }
+ else {
+ Write-status -msg "Can't find PhotosLegacy Installer" -errorOutput
+ }
+ }
+}
+
+function install-classicapps {
+ param(
+ [ValidateSet('photoviewer', 'mspaint', 'snippingtool', 'notepad', 'photoslegacy')]
+ [array]$app
+ )
+
+ #check if files are downloaded locally
+ if (Test-Path "$PSScriptroot\ClassicApps") {
+ Write-Status -msg 'Classic Apps Files Found Locally'
+ $classicApps = "$PSScriptroot\ClassicApps"
+ }
+ else {
+ #check if they are already downloaded if not download them
+ if (!(Test-Path "$env:TEMP\ClassicApps")) {
+ $ProgressPreference = 'SilentlyContinue'
+ Write-Status -msg 'Downloading Classic Apps Files from Github...'
+ $url = 'https://github.com/zoicware/RemoveWindowsAI/archive/refs/heads/main.zip'
+ try {
+ Invoke-WebRequest -Uri $url -OutFile "$env:TEMP\main.zip" -ErrorAction Stop
+ }
+ catch {
+ Write-Status -msg 'Unable to Download Github Repo' -errorOutput
+ return
+ }
+ Expand-Archive -Path "$env:TEMP\main.zip" -DestinationPath $env:TEMP -Force
+ $sourceDir = "$env:TEMP\RemoveWindowsAI-main\ClassicApps"
+ $destDir = "$env:TEMP\ClassicApps"
+ Copy-Item -Path $sourceDir -Destination $destDir -Recurse -Force
+ Remove-Item "$env:TEMP\RemoveWindowsAI-main" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item "$env:TEMP\main.zip" -Recurse -Force -ErrorAction SilentlyContinue
+ }
+
+ $classicApps = "$env:TEMP\ClassicApps"
+ }
+
+
+ switch ($app) {
+ 'photoviewer' {
+ Write-Status -msg 'Installing Classic Photo Viewer...'
+ install-photoviewer
+ }
+ 'mspaint' {
+ Write-Status -msg 'Installing Classic Paint...'
+ install-paint -path $classicApps
+ }
+ 'snippingtool' {
+ Write-Status -msg 'Installing Classic Snipping Tool...'
+ install-snipping -path $classicApps
+ }
+ 'notepad' {
+ Write-Status -msg 'Installing Classic Notepad...'
+ install-notepad
+ }
+ 'photoslegacy' {
+ Write-Status -msg 'Installing Photos Legacy...'
+ install-photoslegacy
+ }
+ Default {
+ Write-Status -msg 'Unknown Classic App Option' -errorOutput
+ }
+ }
+}
+
if ($nonInteractive) {
if ($AllOptions) {
@@ -2279,6 +2660,12 @@ if ($nonInteractive) {
'RemoveRecallTasks' { Remove-Recall-Tasks }
}
}
+
+ if ($InstallClassicApps) {
+ foreach ($app in $InstallClassicApps) {
+ install-classicapps -app $app
+ }
+ }
}
else {
@@ -2320,9 +2707,8 @@ else {
$contentRow.Height = [System.Windows.GridLength]::new(1, [System.Windows.GridUnitType]::Star)
$mainGrid.RowDefinitions.Add($contentRow) | Out-Null
- # Add this BEFORE your bottom row definition:
$toggleRow = New-Object System.Windows.Controls.RowDefinition
- $toggleRow.Height = [System.Windows.GridLength]::new(130) # Fixed height for toggle
+ $toggleRow.Height = [System.Windows.GridLength]::new(130)
$mainGrid.RowDefinitions.Add($toggleRow) | Out-Null
$bottomRow = New-Object System.Windows.Controls.RowDefinition
@@ -2347,6 +2733,78 @@ else {
[System.Windows.Controls.Grid]::SetRow($scrollViewer, 1)
$mainGrid.Children.Add($scrollViewer) | Out-Null
+ $scrollViewerStyle = @'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+'@
+
+ $reader = New-Object System.Xml.XmlNodeReader([xml]$scrollViewerStyle)
+ $scrollViewer.Style = [Windows.Markup.XamlReader]::Load($reader)
+
+
$stackPanel = New-Object System.Windows.Controls.StackPanel
$stackPanel.Orientation = 'Vertical'
$scrollViewer.Content = $stackPanel
@@ -2549,7 +3007,98 @@ else {
return $toggleButton
}
-
+ $divider = New-Object System.Windows.Controls.Separator
+ $divider.Margin = '0,10,0,10'
+ $divider.Background = [System.Windows.Media.Brushes]::DarkGray
+ $stackPanel.Children.Add($divider) | Out-Null
+
+ $classicAppsHeader = New-Object System.Windows.Controls.TextBlock
+ $classicAppsHeader.Text = 'Install Classic Windows Apps'
+ $classicAppsHeader.FontSize = 16
+ $classicAppsHeader.FontWeight = 'Bold'
+ $classicAppsHeader.Foreground = [System.Windows.Media.Brushes]::Cyan
+ $classicAppsHeader.Margin = '0,10,0,10'
+ $stackPanel.Children.Add($classicAppsHeader) | Out-Null
+
+ $classicAppsFunctions = @(
+ 'Install-Classic-Photoviewer'
+ 'Install-Classic-Mspaint'
+ 'Install-Classic-SnippingTool'
+ 'Install-Classic-Notepad'
+ 'Install-Photos-Legacy'
+ )
+
+ $classicAppsDescriptions = @{
+ 'Install-Classic-Photoviewer' = 'Installs the classic Windows Photo Viewer from Windows 7/8, allowing you to view images with the traditional viewer instead of the modern Photos app.'
+ 'Install-Classic-Mspaint' = 'Installs the classic Microsoft Paint application from older Windows versions.'
+ 'Install-Classic-SnippingTool' = 'Installs the classic Snipping Tool, replacing the modern Snip & Sketch app.'
+ 'Install-Classic-Notepad' = 'Installs the classic Notepad from Windows 10, replacing the modern uwp version.'
+ 'Install-Photos-Legacy' = 'Installs the legacy Windows Photos app from the Microsoft Store.'
+ }
+
+ $functionDescriptions += $classicAppsDescriptions
+ foreach ($func in $classicAppsFunctions) {
+ $optionContainer = New-Object System.Windows.Controls.DockPanel
+ $optionContainer.Margin = '0,5,0,5'
+ $optionContainer.LastChildFill = $false
+
+ $checkbox = New-Object System.Windows.Controls.CheckBox
+ $checkbox.Content = $func.Replace('-', ' ')
+ $checkbox.FontSize = 14
+ $checkbox.Foreground = [System.Windows.Media.Brushes]::White
+ $checkbox.Margin = '0,0,10,0'
+ $checkbox.VerticalAlignment = 'Center'
+ $checkbox.IsChecked = $false
+ [System.Windows.Controls.DockPanel]::SetDock($checkbox, 'Left')
+ $checkboxes[$func] = $checkbox
+
+ $infoButton = New-Object System.Windows.Controls.Button
+ $infoButton.Content = '?'
+ $infoButton.Width = 25
+ $infoButton.Height = 25
+ $infoButton.FontSize = 12
+ $infoButton.FontWeight = 'Bold'
+ $infoButton.Background = [System.Windows.Media.Brushes]::DarkBlue
+ $infoButton.Foreground = [System.Windows.Media.Brushes]::White
+ $infoButton.BorderBrush = [System.Windows.Media.Brushes]::Transparent
+ $infoButton.BorderThickness = 0
+ $infoButton.VerticalAlignment = 'Center'
+ $infoButton.Cursor = 'Hand'
+ [System.Windows.Controls.DockPanel]::SetDock($infoButton, 'Right')
+
+ $infoTemplate = @'
+
+
+
+
+
+'@
+ $infoButton.Template = [System.Windows.Markup.XamlReader]::Parse($infoTemplate)
+
+ $infoButton.Add_Click({
+ param($sender, $e)
+
+ # Find the correct function name
+ foreach ($f in $classicAppsFunctions) {
+ if ($checkboxes[$f].Parent -eq $sender.Parent) {
+ $funcName = $f
+ break
+ }
+ }
+
+ $description = $functionDescriptions[$funcName]
+ [System.Windows.MessageBox]::Show($description, $funcName, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
+ })
+
+ $optionContainer.Children.Add($checkbox) | Out-Null
+ $optionContainer.Children.Add($infoButton) | Out-Null
+ $stackPanel.Children.Add($optionContainer) | Out-Null
+ }
+
+ $allFunctions = $functions + $classicAppsFunctions
$toggleGrid = New-Object System.Windows.Controls.Grid
[System.Windows.Controls.Grid]::SetRow($toggleGrid, 2)
@@ -2902,7 +3451,7 @@ else {
$progressWindow.Show()
$selectedFunctions = @()
- foreach ($func in $functions) {
+ foreach ($func in $allFunctions) {
if ($checkboxes[$func].IsChecked) {
$selectedFunctions += $func
}
@@ -2931,6 +3480,11 @@ else {
'Hide-AI-Components' { Hide-AI-Components }
'Disable-Notepad-Rewrite' { Disable-Notepad-Rewrite }
'Remove-Recall-Tasks' { Remove-Recall-Tasks }
+ 'Install-Classic-Photoviewer' { install-classicapps -app 'photoviewer' }
+ 'Install-Classic-Mspaint' { install-classicapps -app 'mspaint' }
+ 'Install-Classic-SnippingTool' { install-classicapps -app 'snippingtool' }
+ 'Install-Classic-Notepad' { install-classicapps -app 'notepad' }
+ 'Install-Photos-Legacy' { install-classicapps -app 'photoslegacy' }
}
Start-Sleep -Milliseconds 500