@@ -56,17 +56,17 @@ function Uninstall-WingetID ($WingetIDUninst) {
5656function Uninstall-ModsApp ($AppUninst , $AllVersions ) {
5757 foreach ($app in $AppUninst ) {
5858 # we start from scanning the x64 node in registry, if something was found, then we set x64=TRUE
59- [bool ]$app_was_x64 = Process - installedSoftware - app $app - x64 $true ;
59+ [bool ]$app_was_x64 = Get-InstalledSoftware - app $app - x64 $true ;
6060
6161 # if nothing was found in x64 node, then we repeat that action in x86 node
6262 if (! $app_was_x64 ) {
63- Process - installedSoftware - app $app | Out-Null ;
63+ Get-InstalledSoftware - app $app | Out-Null ;
6464 }
6565 }
6666 Return
6767}
6868
69- Function Process-installedSoftware () {
69+ Function Get-InstalledSoftware () {
7070 [OutputType ([Bool ])]
7171 Param (
7272 [parameter (Mandatory = $true )] [string ]$app ,
@@ -84,48 +84,71 @@ Function Process-installedSoftware() {
8484 foreach ($obj in $InstalledSoftware ) {
8585 if ($obj.GetValue (' DisplayName' ) -like $App ) {
8686 $UninstallString = $obj.GetValue (' UninstallString' )
87- $CleanedUninstallString = $UninstallString.Trim ([char ]0x0022 )
87+ $CleanedUninstallString = $UninstallString.Replace (' "' , ' ' )
88+ $ExeString = $CleanedUninstallString.Substring (0 , $CleanedUninstallString.IndexOf (' .exe' ) + 4 )
8889 if ($UninstallString -like " MsiExec.exe*" ) {
8990 $ProductCode = Select-String " {.*}" - inputobject $UninstallString
9091 $ProductCode = $ProductCode.matches.groups [0 ].value
91- # MSI x64 Installer
92- $Exec = Start-Process " C:\Windows \System32\msiexec.exe" - ArgumentList " /x$ProductCode REBOOT=R /qn" - PassThru - Wait
93- # Stop Hard Reboot (if bad MSI!)
92+ # MSI Installer
93+ $Exec = Start-Process " $ env: SystemRoot \System32\msiexec.exe" - ArgumentList " /x$ProductCode REBOOT=R /qn" - PassThru - Wait
94+ # Stop Hard Reboot (if bad MSI!)
9495 if ($Exec.ExitCode -eq 1641 ) {
95- Start-Process " C:\Windows \System32\shutdown.exe" - ArgumentList " /a"
96+ Start-Process " $ env: SystemRoot \System32\shutdown.exe" - ArgumentList " /a"
9697 }
9798 }
9899 else {
99100 $QuietUninstallString = $obj.GetValue (' QuietUninstallString' )
100101 if ($QuietUninstallString ) {
101- $QuietUninstallString = Select-String " (\x22.*\x22 ) +(.*)" - inputobject $QuietUninstallString
102+ $QuietUninstallString = Select-String ' ("[^"]*" ) +(.*)' - inputobject $QuietUninstallString
102103 $Command = $QuietUninstallString.matches.groups [1 ].value
103104 $Parameter = $QuietUninstallString.matches.groups [2 ].value
104- # All EXE x64 Installers (already defined silent uninstall)
105+ # All EXE Installers (already defined silent uninstall)
105106 Start-Process $Command - ArgumentList $Parameter - Wait
106107 }
107108 else {
108- if ((Test-Path $CleanedUninstallString )) {
109- $NullSoft = Select-String - Path $CleanedUninstallString - Pattern " Nullsoft"
110- }
111- if ($NullSoft ) {
112- # NSIS x64 Installer
113- Start-Process $UninstallString - ArgumentList " /S" - Wait
114- }
115- else {
116- if ((Test-Path $CleanedUninstallString )) {
117- $Inno = Select-String - Path $CleanedUninstallString - Pattern " Inno Setup"
118- }
119- if ($Inno ) {
120- # Inno x64 Installer
121- Start-Process $UninstallString - ArgumentList " /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-" - Wait
109+ # Improved detection logic
110+ if ((Test-Path $ExeString - ErrorAction SilentlyContinue)) {
111+ try {
112+ # Read the whole file to find installer signatures
113+ $fileContent = Get-Content - Path $ExeString - Raw - ErrorAction Stop
114+ # Executes silent uninstallation based on installer type
115+ if ($fileContent -match " \bNullsoft\b" -or $fileContent -match " \bNSIS\b" ) {
116+ # Nullsoft (NSIS) Uninstaller
117+ Start-Process $ExeString - ArgumentList " /NCRC /S" - Wait
118+ }
119+ elseif ($fileContent -match " \bInno Setup\b" ) {
120+ # Inno Uninstaller
121+ Start-Process $ExeString - ArgumentList " /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-" - Wait
122+ }
123+ elseif ($fileContent -match " \bWise Solutions\b" ) {
124+ # Wise Uninstaller (Unwise32.exe)
125+ # Find the Install.log path parameter in the UninstallString
126+ $ArgString = $CleanedUninstallString.Substring ($CleanedUninstallString.IndexOf (' .exe' ) + 4 ).Trim()
127+ # Copy files to temp folder so that Unwise32.exe can find Install.log (very, very old system)
128+ Copy-Item - Path $ExeString - Destination $env: TEMP - Force
129+ $ExeString = Join-Path $env: TEMP (Split-Path $ExeString - Leaf)
130+ Copy-Item - Path $ArgString - Destination $env: TEMP - Force
131+ $ArgString = Join-Path $env: TEMP (Split-Path $ArgString - Leaf)
132+ # Execute the uninstaller with the copied Unwise32.exe
133+ Start-Process $ExeString - ArgumentList " /s $ArgString " - Wait
134+ # Remove the copied Unwise32.exe from temp folder (Install.log gets deleted by Unwise32.exe)
135+ Remove-Item - Path $ExeString - Force - ErrorAction SilentlyContinue
136+ }
137+ else {
138+ Write-Host " $ ( if ($true -eq $x64 ) {' x64' } else {' x86' }) Uninstaller unknown, trying the UninstallString from registry..."
139+ $NativeUninstallString = Select-String " (\x22.*\x22) +(.*)" - inputobject $UninstallString
140+ $Command = $NativeUninstallString.matches.groups [1 ].value
141+ $Parameter = $NativeUninstallString.matches.groups [2 ].value
142+ Start-Process $Command - ArgumentList $Parameter - Wait
143+ }
122144 }
123- else {
124- Write-Host " $ ( if ($true -eq $x64 ) {' x64' } else {' x86' }) Uninstaller unknown, trying the UninstallString from registry..."
145+ catch {
146+ Write-Warning " Could not read installer file: $_ "
147+ # Fallback to standard method
148+ Write-Host " Failed to inspect installer, trying UninstallString directly..."
125149 $NativeUninstallString = Select-String " (\x22.*\x22) +(.*)" - inputobject $UninstallString
126150 $Command = $NativeUninstallString.matches.groups [1 ].value
127151 $Parameter = $NativeUninstallString.matches.groups [2 ].value
128- # All EXE x64 Installers (native defined uninstall)
129152 Start-Process $Command - ArgumentList $Parameter - Wait
130153 }
131154 }
@@ -141,10 +164,15 @@ Function Process-installedSoftware() {
141164}
142165
143166function Remove-ModsLnk ($Lnk ) {
167+ $removedCount = 0
144168 foreach ($link in $Lnk ) {
145- Remove-Item - Path " ${env: Public} \Desktop\$link .lnk" - Force - ErrorAction SilentlyContinue | Out-Null
169+ $linkPath = " ${env: Public} \Desktop\$link .lnk"
170+ if (Test-Path $linkPath ) {
171+ Remove-Item - Path $linkPath - Force - ErrorAction SilentlyContinue | Out-Null
172+ $removedCount ++
173+ }
146174 }
147- Return
175+ Return $removedCount
148176}
149177
150178function Add-ModsReg ($AddKey , $AddValue , $AddTypeData , $AddType ) {
0 commit comments