winget-cli icon indicating copy to clipboard operation
winget-cli copied to clipboard

Manifest fields for custom uninstall arguments and return codes

Open jedieaston opened this issue 3 years ago • 6 comments

Description of the new feature / enhancement

We currently have a bunch of manifest fields for installing packages:

InstallerSwitches:
    Custom: /allthethings
    Silent:  /VERYSILENT
    SilentWithProgress: /somewhatsilent
InstallerSuccessCodes:
    - 12
    - 57
    - 99

But we don't have any for uninstalling packages. Many packages return funny error codes that still mean success after an uninstall, or require special arguments to make uninstall 100% silent. Currently, there isn't a way to tell winget to use these.

(I believe this will help with the Edge WebView2 issues, as it requires user interaction to uninstall and then it exits with a non-zero code, which halts the upgrade leaving the user with no WebView2).

Proposed technical implementation details

Some matching manifest keys that work similarly to the existing installer fields, per installer (I realize that it may be difficult to make a best guess at InstallerType if winget didn't install the package to begin with, but that will need to be implemented anyway at some point). Ideally, these switches should be ran on the local uninstall executable, presuming it still exists.

If a manifest isn't available for an app that a user wants to uninstall, then the current behavior should be preserved.

UninstallerSwitches:
    Custom: /uninstallallthethings
    Silent:  /VERYSILENT
    SilentWithProgress: /somewhatsilent
UninstallerSuccessCodes:
    - 12
    - 57
    - 99

jedieaston avatar Jan 31 '22 17:01 jedieaston

Additional context from a thread on Twitter.

I asked if we had samples of uninstall experiences that could be improved with arguments for silent:

  • winget uninstall citrix.workspace is showing the prompt, CitrixWorkspaceApp22.12.0.48.exe /uninstall /silent silently removes the Citrix Workspace App without a prompt.
  • Another one: "C:\Program Files\IrfanView\iv_uninstall.exe" /silent

denelon avatar Feb 03 '23 17:02 denelon

Another one to add to the list as an example of where uninstaller exit codes are important: winget uninstall mirc. This one is amusing in itself, as it uses the NSIS (Nullsoft installer). The following occurs:

  • Uninstaller is run
    • Note that the uninstaller binary, uninstall.exe, is located in the same directory as the mIRC software itself, i.e. C:\Program Files\mIRC
    • Also note that the uninstaller is not run silently (i.e. is interactive), despite the installer being run silently
  • The uninstaller GUI reports that "not all files could be removed"
    • This is ironic, since the only file it could not remove is uninstall.exe located within that directory
    • If your reaction is "that's a bug in NSIS", then keep reading
  • After the uninstaller finishes the application uninstallation phase, it deletes itself and the underlying directory (i.e. C:\Program Files\mIRC)
  • The uninstaller exits with an exit code of 1223
  • WinGet complains about exit code 1223

It should be crystal clear to folks at Microsoft that not all uninstallers and software are created equal, and thus things like UninstallerSwitches and UninstallerSuccessCodes are important.

Refer to the Chocolatey project for proof of this, where the package maintainer can wrangle both install and uninstall scenarios using PowerShell. (Yes I know WinGet does not permit this, I'm just simply noting the importance of being able to handle both installer and uninstaller scenarios, and quite often install vs. uninstall vary.)

koitsu avatar May 14 '23 23:05 koitsu

Vencord is another one. to uninstall it you need to pass -uninstall to the installer

solomoncyj avatar Jun 22 '23 12:06 solomoncyj

  • Also note that the uninstaller is not run silently (i.e. is interactive), despite the installer being run silently

I don't think how the installer was executed is relevant to how the uninstaller is executed.

Winget already knows that NSIS uses /S as the silent switch. If /S does not make it silent then you would have to take that up with the mIRC people, they are either overriding the silent switch in their un.onInit or forgot to make their Message boxes silent. That being said, I'm not sure if Winget will apply the /S to the uninstaller automatically. Ideally, mIRC should write a QuietUninstallString entry for Winget to use.

  • This is ironic, since the only file it could not remove is uninstall.exe located within that directory

NSIS uninstallers by default will copy and run themselves outside the installation directory because a running executable cannot delete itself. The installer author would have to code things differently on purpose to make it work differently.

The uninstaller exits with an exit code of 1223

The NSIS exit codes are 0 for success, 1 for user cancel and 2 for cancelled by script action. If a installer/uninstaller returns something else then the installer author made a deliberate choice to do so.

1223 is Windows error code ERROR_CANCELLED.

sredna avatar Jul 10 '23 02:07 sredna

The uninstaller exits with an exit code of 1223

The NSIS exit codes are 0 for success, 1 for user cancel and 2 for cancelled by script action. If a installer/uninstaller returns something else then the installer author made a deliberate choice to do so.

1223 is Windows error code ERROR_CANCELLED.

Please explain the following, all of which are NSIS-based. It is safe to say that all these software authors (all of whom are independent from one another) did not "make a deliberate choice to do so".

  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/audacity/tools/chocolateyInstall.ps1#L11
  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/autohotkey.install/tools/chocolateyInstall.ps1#L16
  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/avidemux/tools/chocolateyInstall.ps1#L14
  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/everything/tools/chocolateyInstall.ps1#L11
  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/filezilla/tools/chocolateyInstall.ps1#L11
  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/mendeley/tools/chocolateyInstall.ps1#L12
  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/peazip.install/tools/chocolateyinstall.ps1#L12
  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/qbittorrent/tools/chocolateyinstall.ps1#L15
  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/tribler/tools/chocolateyInstall.ps1#L16
  • https://github.com/chocolatey-community/chocolatey-packages/blob/master/automatic/vlc.install/tools/chocolateyInstall.ps1#L11

koitsu avatar Jul 10 '23 09:07 koitsu

all of which are NSIS-based

Incorrect!

Please explain the following

  • Audacity: This is using Inno, not NSIS. All Inno standard exit codes are < 10. Their documentation also says "any non-zero exit code indicates that the uninstaller was not run to completion". (This also applies to the installer)
  • AutoHotKey: Not NSIS, some kind of custom thing?
  • Avidemux: NSIS. Uses a deprecated 3rd-party plug-in. Looks like it might return 1223 if the UAC elevation dialog is cancelled.
  • Everything: NSIS. Closed source but does not seem like it would return 1223.
  • Mendeley: Uses the same 3rd-party plug-in as above but I can't tell if it can return 1223 without the source.
  • Peazip: This is using Inno, not NSIS.
  • qbittorrent: NSIS. Uses a deprecated 3rd-party plug-in. Looks like it might return 1223 if the UAC elevation dialog is cancelled.
  • Tribler: NSIS. Uses some 3rd-party plug-ins, don't know if these can return 1223.
  • VLC: NSIS. Nothing pops out at me as something that would return 1223.

sredna avatar Jul 10 '23 14:07 sredna