microsoft/winget-cli

winget upgrade should be able to force close programs and apply the upgrade

Opened this issue · 4 comments

Relevant area(s)

WinGet CLI

Description of the new feature / enhancement

I tried running an upgrade yet it failed with:

Files modified by the installer are currently in use by a different application. Exit the applications then try again.
Installer failed with exit code: 6

Now I have to manually figure out the process that generates the issue, even though I simply want to force the upgrade. I don't care how the program in question is closed or if there might be data loss. I only care that the upgrade is applied with as little user interaction as possible.

Full log:

winget upgrade --all --silent
Name       Id                   Version Available Source
--------------------------------------------------------
OBS Studio OBSProject.OBSStudio 32.0.1  32.0.2    winget
1 upgrades available.

Installing dependencies:
This package requires the following dependencies:
  - Packages
      Microsoft.VCRedist.2015+.x64
(1/1) Found OBS Studio [OBSProject.OBSStudio] Version 32.0.2
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Successfully verified installer hash
Starting package install...
The installer will request to run as administrator. Expect a prompt.
Files modified by the installer are currently in use by a different application. Exit the applications then try again.
Installer failed with exit code: 6

I also tried:

 winget upgrade --all --silent --force

Proposed technical implementation details

I don't have strong preferences about the implementation details, yet I could see either a prompt that the user has to enter y / n or a flag like --quit-running. This feature may be added to an existing flag like --force.

My assumption already was that both/either --silent and/or --force would make the upgrade proceed.


If there are other alteratives to solve this like upgrading the program in the background, and old version still running as long as the process exists, I am also fine with that.

Goal is: Force upgrade the program no matter what the current state is.

(This may also apply if the program was installed with a different source than winget. I may open a different issue for that though.)

One of the big challenges with this is that there is no way for WinGet to know what process needs to be ended. Some packages have a bunch of executables, and any one of those could prevent the upgrade. There may be switches for some of them to be forced to shut down on the installation of the upgrade, but I'm not sure how many there are. I'll go ahead and keep this issue open, but I don't have very high confidence of how this would be implemented.

The default behavior would still be that an upgrade is blocked by an application running. In general, it would probably be "--force" as opposed to some kind of "stop running" argument, but I'm open to suggestions if other folks are interested in this feature.

@denelon Fair enough, though I wonder if the responsibility of knowing what processes to force quit could be offloaded to the user through a custom pre-upgrade hook.

I, as a user of winget, run the winget upgrade.

winget upgrade --all --silent

This yields an error, e.g.:

winget upgrade
Name                       Id                    Version Available Source
-------------------------------------------------------------------------
KeePass Password Safe 2.59 DominikReichl.KeePass 2.59    2.60.0    winget
OBS Studio                 OBSProject.OBSStudio  32.0.1  32.0.2    winget
2 upgrades available.
PS C:\Users\philipp.kretzschmar> winget upgrade OBSProject.OBSStudio
Found OBS Studio [OBSProject.OBSStudio] Version 32.0.2
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
This package requires the following dependencies:
  - Packages
      Microsoft.VCRedist.2015+.x64
Successfully verified installer hash
Starting package install...
The installer will request to run as administrator. Expect a prompt.
Files modified by the installer are currently in use by a different application. Exit the applications then try again.
Installer failed with exit code: 6

I, as the user, have the responsibility of finding out what other programs to quit and to add them in a config file, e.g. dummy-config as json:

{
  "pre-upgrade": {
        "<package_id>": {
           "kill-processes": ["<whatever>", "<process>", "<...>"]
        }
   }
}

Or just make it a universal script, so that the user could enter any valid powershell script (though that may pose a security risk).

And ideally one would also have an post-upgrade hook to ensure that certain services run again.

And in the best of worlds, one could create central recipies for packages id to share with other users, and for certain selected packages, winget could come with suggested recipies out of the box.


Another similar issue #1675 has skype as a roadblock. (So people are currently running into this issue and having a hard time figuring out what to quit.) Yet at least thanks to this tip I found what is preventing the install to proceed:

winget upgrade --id OBSProject.OBSStudio -i

(Could you make that info be part of the cli log instead of the abstract exit code: 6? Or suggest the user to run with i flag to find out what is blocking the install?)

In my case, at least chrome is blocking my upgrade:

Image

So it is what I would like to be able to configure to force quit on upgrade.

(One could even think this further, e.g. adding an option that it only shall try killing programs if it actually runs into an error to begin with. Yet those are implementation details for you to decide on if you want to add this feature.)


Last but not least: for now I managed the upgrade via:

> Stop-Process -Name chrome && winget upgrade --id OBSProject.OBSStudio --silent

WinGet does support "expected return codes". If OBS Studio returns "6" because the application is in use, WinGet can provide a "friendly" message and a URL.

Search for "ExpectedReturnCode" in the installer schema reference for 1.10.

WinGet does support "expected return codes". If OBS Studio returns "6" because the application is in use, WinGet can provide a "friendly" message and a URL.

Search for "ExpectedReturnCode" in the installer schema reference for 1.10.

I do not understand. Are you saying that one can get a list of programs that are blocking the install via cli? If so, how?

As one of the problem is that on cli, I currently am only seeing Installer failed with exit code: 6, I have to go through the graphical setup in order to see which programs are blocking the install.

I don't follow what to do with the information about ExpectedReturnCode.