microsoft / winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).
https://learn.microsoft.com/windows/package-manager/
MIT License
23.01k stars 1.43k forks source link

Pin a package #476

Closed denelon closed 1 year ago

denelon commented 4 years ago

Description of the new feature/enhancement

Users should be able to prevent the Windows Package Manager from updating a package (assumes the package doesn't have it's own auto-update).

winget pin <package> and the corollary winget unpin <package>.

This was mentioned by:

@megamorf https://github.com/microsoft/winget-cli/issues/120#issuecomment-635174060 @rodalpho https://github.com/microsoft/winget-cli/issues/120#issuecomment-635520051 @aetos382 https://github.com/microsoft/winget-cli/issues/120#issuecomment-635741018 @kmindi https://github.com/microsoft/winget-cli/issues/120#issuecomment-637343639

Proposed technical implementation details (optional)

There should also be a mechanism to display the packages (and the version) that have been "pinned". This might be a function of list or a function of pin. Additionally, if packages are known to self-update (like Visual Studio Code) an additional meta-data entry in the manifest could help users understand when they may not be able to pin a package.

Edit: Clarifying behavior for ambiguity suggested in other Issues.

Pinning should enable users to specify the exact version (likely the default case with no parameters). It should also allow users to specify what portion of a version should be pinned so bug fixes could be applied, or even minor version bumps.

Note: the syntax below is just suggestive.

Assume the user has installed "Awesome App" version "1.2.3".

winget pin "Awesome App" This would pin to version 1.2.3 and would not be upgraded when any newer version is released.

winget pin "Awesome App" --version 1.2 This would pin version to anything less than version 1.3. If version 1.2.4 were released this would be a valid upgrade.

winget pin "Awesome App" --version 1 This would pin the version to anything less than version 2. If version 1.2.4 were released this would be a valid upgrade. If version 1.3.0 were released this would also be a valid upgrade.

Additional example per @brainz80

E.g. Having nodejs-lts version 12.1.1 installed and running winget pin --all nodejs-lts --version 12.x should make it so that when later winget upgrade --all is ran it'd check if there is a update available for nodejs-lts what matches 12.x - if the latest update is e.g 16.1.1, but there is also a 12.1.2 it'd update nodejs-lts to that version.

griesi007 commented 2 years ago

This happens also frequently with ImageMagick when a new version is published in binaries download on download.imagemagick.org (the previous version is then removed). winget has still the previous version and thus cannot download it anymore because it is not present anymore => 404 [error]

image

marcushallett commented 2 years ago

I see that @denelon marked this as a v1.4 milestone issue. So, I suppose that means it'll be 2023 at the earliest before this feature is available, right?

gknutson1 commented 2 years ago

One use case that I have not seen here is software uninstalled via other launchers. I have OpenTTD installed via Steam, and winget keeps picking it up as version 'unknown'. I don't want winget overriding the Steam version, and want a way to 'ignore' OpenTTD in winget.

MaxVRAM commented 2 years ago

One use case that I have not seen here is software uninstalled via other launchers. I have OpenTTD installed via Steam, and winget keeps picking it up as version 'unknown'. I don't want winget overriding the Steam version, and want a way to 'ignore' OpenTTD in winget.

Exactly. Anyone else use Unity? Unity Hub manages versions to work across more than one project that are locked to Editor versions.

Unity    UnityTechnologies.Unity.2020    2019.2.21f1    2020.3.26f1    winget

I can't use winget upgrade --all when I abort the process attempting to install an upgrade that will break my development environment.

rvtdadmin commented 2 years ago

Is anyone using https://github.com/Romanitho/Winget-AutoUpdate It has a scripted exclude list function. I am reviewing using this even though I might usually not because it upgrades winget to 1.3 and has the exclude function. Not interested in the notifications personally.

sukiletxe commented 2 years ago

I wasn't, but now I am. Thanks for the tip!

FlorianPfaff commented 2 years ago

I would also find this useful. In my case, winget always reports MS office being out of date. However, no update is "available" (or rather can be installed) due to IT policies here. This is why winget always "updates" office (without ever doing anything useful).

bwilsonms commented 2 years ago

this would be good for node on windows where our repo has a dependency on using older versions until the new versions in the pipeline. Seems like a good idea as well if you want parity w/ the ability choco has.

norahvii commented 2 years ago

If chocolatey can do this, winget should be able to. I use both, and really prefer my package managers not fight.

It may also be good of MS to compile a list of features choco has that winget does not, to guide it's improvements going forward.

Bluscream commented 1 year ago

How is this still not a thing yet

NicTanghe commented 1 year ago

Windows isn`t asking you for extra money so they can take their time. They have done a great job with everything under the new management. Just give them some time.

Bluscream commented 1 year ago

Thankfully other software has implemented this eons ago: https://github.com/martinet101/WingetUI/commit/36303dec9040759e60fe8f1d4ab0183d11df6551

KristoferOlafsson commented 1 year ago

I'd also like a feature to pin apps to versions. Or to exclude them from updating.

Karreg commented 1 year ago

Another use case is application managed by the IT department on corp computers. Definitely a needed feature for many reasons, also, it's coherent with all other package managers.

assert-not-singularity commented 1 year ago

The latest version of Dell Display Manager (2.0) doesn't support older monitors. Automatically upgrading an existing 1.56 version to 2.0 breaks functionality to control my monitors. Please allow pinning to versions or even better pinning to major version such as 1.xx.

denelon commented 1 year ago

The specification for this is a PR in progress:

WrinkleRelease commented 1 year ago

Wanted add my support for this feature. I have several packages I do not want to upgrade, yet I want to run winget upgrade --all. I can't. I have upgrade the packages I want one at a time and it's tedious. It would be nice for the pin command to exclude packages from winget upgrade --all once used.

pureby commented 1 year ago

I just tried 'winget upgrade --all' for the first time and it tried to upgrade Audacity to 3+ which is now suspected for spyware. Audacity 2.4 is safe and will remain very popular. I didn't install Audacity with Winget (I used Scoop and pinned it). If Winget is going to upgrade apps installed via Scoop or Choco then we need to be able to pin.

You make a good point. I think we should be able to exclude not only packages, but also directories from winget upgrade --all .

Example: winget pin -directory "C:\MyApps"

See #2749.

masterflitzer commented 1 year ago

but also directories

not to be ignorant, i love features, but why? why is excluding packages not enough and which advantage does excluding dirs bring?

Virakal commented 1 year ago

not to be ignorant, i love features, but why? why is excluding packages not enough and which advantage does excluding dirs bring?

It would significantly simplify pinning all current and future packages added through Chocolatey or Scoop, for one.

pureby commented 1 year ago

not to be ignorant, i love features, but why? why is excluding packages not enough and which advantage does excluding dirs bring?

Shortly put:

I go into detail on the subject and give examples in Feature Request #2749.

masterflitzer commented 1 year ago

thank you for explaining

exoosh commented 1 year ago

From my experience the most common scenario for why you'd want to pin a package version is when there is a known issue with a newer version of that package itself or with one if its dependencies. So on Linux that meant I pinned the docker package because one of its dependencies (containerd) could not be installed.

Yeah, but unlike on Linux, winget still doesn't seem to have a notion of dependencies in that same sense (i.e. libraries that have to match a given software version).

My use case for this would be one that is nicely demonstrated by VMware Workstation Pro:

VMware Workstation                                        VMware.WorkstationPro               16.2.5           17.0.0       winget

Version 16.2.5 was released after 17.0.0 and using 17.0.0 requires a "renewal" of the license key which I don't want to rush at this point. So I can no longer use winget upgrade --all, because it would nuke my VMware Workstation Pro 16.x installation and upgrade it to 17; for which I have no valid license key as of yet (mentioned here).

However, in part this is also an inconsistency of how packages are accepted into the winget package metadata repo. While with Microsoft.VisualStudio.*.* you have the last two segments specify the version and edition, e.g. Microsoft.VisualStudio.2022.Enterprise, or with Python.Python.*.* you have the last two segments specify the major and minor version, e.g. Python.Python.3.11, it's seems to be completely arbitrary whether a given software follows one or the other scheme.

And while it is true that both Visual Studio and Python versions/editions can coexist with parallel installations on a computer, whereas only a single VMware Workstation version can installed at any point, the missing pinning feature limits the utility winget upgrade --all provides merely because there is no way to distinguish between a paid upgrade and a gratis one.

If pinning were to be implemented as outlined in the initial post, it would allow to circumvent this limitation imposed by the creator(s) of the package manifest(s). I can see how a vendor may want to push paid upgrades, but sometimes I want to delay the upgrade or never upgrade to a newer version for other reasons.

masterflitzer commented 1 year ago

Version 16.2.5 was released after 17.0.0 and using 17.0.0 requires a "renewal" of the license

i'm not against pinning but in this case the right thing to do would be having a separate package for each major version, that is VMware.WorkstationPro.16 and VMware.WorkstationPro.17, microsoft is doing similar things with .NET: Microsoft.DotNet.SDK.6 and Microsoft.DotNet.SDK.6

it's seems to be completely arbitrary whether a given software follows one or the other scheme

very true this needs to be fixed with clear rules imo

were to be implemented as outlined in the initial post, it would allow to circumvent this limitation

yeah it would be a welcome feature & workaround but the underlining problems should also be looked at

brianary commented 1 year ago

I've got an old video card, and if I update my driver or driver management software, my card is no longer supported by it. Thankfully, upgrades currently fail, but pinning would be a more reliable protection (and would prevent the wasted attempt).

stee-ren commented 1 year ago

I'm so delighted microsoft has provided this awesome too. I really want to thank the people who probably had to fight a tough fight to be able to even provide this tool under the Microsoft banner. Big time respect!!

Regarding this feature, I really think is a must have for larger adoption, especially within companies (not just corporate). Main reasons being:

The list probably goes on, and I can appreciate this could quickly become a complex area. But I wondered if the idea of extending the settings JSON file support to support an include/exclude section that uses symantic versioning semver (just like NodeJS uses a package.json) to define which versions are allowed.

E.g. `{{ "$schema": "https://aka.ms/winget-settings.schema.json",

// For documentation on these settings, see: https://aka.ms/winget-settings
"experimentalFeatures": {
  "dependencies": true,
  "directMSI": false,
  "zipInstall": false,
},
"visual": {
    "progressBar": "rainbow"
},
"source": {
    "autoUpdateIntervalInMinutes": 5
},

"exclude": [
    "Microsoft.Office"
],
"include": {
    "NodeJS": "~18.1.0",
    "Git": "2.39.0",
    "VisualStudioCode": "^1.74.1"
}

}`

Here's a cheatsheet on semver - https://devhints.io/semver This would allow users, where its important for them, to fix package versions to match their needs in a flexible and well established way. Above, I want all patch sets for NodeJS but I've pinned Git and with VSCode, I've stated I want all the new features within V1, but not to install V2* (which isn't true, I'd be the first on v2 if it existed :-) ). With something like this, I can safely use "winget upgrade --all" so any packages I have (or add in the future) are always updated to the latest, but gives me the control to add special handling for specific where the need arises.

I'm sure this idea isn't new, and has already been discussed internally, but just to throw my tu-pence worth in and show my appreciation for this tool!!

davejdyer commented 1 year ago

I'm so delighted microsoft has provided this awesome too. I really want to thank the people who probably had to fight a tough fight to be able to even provide this tool under the Microsoft banner. Big time respect!!

Regarding this feature, I really think is a must have for larger adoption, especially within companies (not just corporate). Main reasons being:

  • winget does not (and probably cannot ever) always accurately report the latest versions, or current version for a tool, since they have little control over other companies tools and how this information is accurately retrieved. This can lead to unexpected things. E.g. Winget reports I have Webstorm 2020.3.2 and says I should upgrade to 2022.3 (which is already installed), so when it attempts to uninstall my 2022.3, its upsetting :-) Dumb example but I hope its makes the point.
  • Companies need to maintain compatibility across all the machines and in our case, prefer to hold back on Office (and related) updates until they can run some tests internally and then roll it out. So taking the latest for every package, is probably not going to be ok in some cases.
  • The latest major/minor release is not always what companies/users want. Most typical example is LTS versions. For some packages, the requirement is to stick to LTS versions, but always update patches immediately.
  • It can be, based on your line of work, you need a specific version of a tool (might not be LTS) E.g. to support employees or customers, you need specifically the version they use, but again, probably want the latest patches/security updates.

The list probably goes on, and I can appreciate this could quickly become a complex area. But I wondered if the idea of extending the settings JSON file support to support an include/exclude section that uses symantic versioning semver (just like NodeJS uses a package.json) to define which versions are allowed.

E.g. `{{ "$schema": "https://aka.ms/winget-settings.schema.json",

// For documentation on these settings, see: https://aka.ms/winget-settings
"experimentalFeatures": {
  "dependencies": true,
  "directMSI": false,
  "zipInstall": false,
},
"visual": {
    "progressBar": "rainbow"
},
"source": {
    "autoUpdateIntervalInMinutes": 5
},

"exclude": [
    "Microsoft.Office"
],
"include": {
    "NodeJS": "~18.1.0",
    "Git": "2.39.0",
    "VisualStudioCode": "^1.74.1"
}

}`

Here's a cheatsheet on semver - https://devhints.io/semver This would allow users, where its important for them, to fix package versions to match their needs in a flexible and well established way. Above, I want all patch sets for NodeJS but I've pinned Git and with VSCode, I've stated I want all the new features within V1, but not to install V2* (which isn't true, I'd be the first on v2 if it existed :-) ). With something like this, I can safely use "winget upgrade --all" so any packages I have (or add in the future) are always updated to the latest, but gives me the control to add special handling for specific where the need arises.

I'm sure this idea isn't new, and has already been discussed internally, but just to throw my tu-pence worth in and show my appreciation for this tool!!

This is an intriguing alternative approach to what has been a long-running feature implementation based on fairly important capability (IMHO). I've been tracking this for quite a while hoping for an answer to the limited "upgrade --all" option. This post inspired another thought which hadn't occurred to me before. I apologize if this has been discussed previously; I couldn't find mention of it in a quick search. What if tagging were added to installed packages and the ability to filter the upgrade command based on user-defined tags? I don't have the time atm to write up a full feature suggestion, but thought I'd throw that out there in case it hadn't been mentioned as a solution.

denelon commented 1 year ago

Related:

akitakedits commented 1 year ago

I still can't believe this isn't a feature after so many years of development, it is critical for wider use and adoption. The winget upgrade --all command is a shortcut many users, including myself, would like to be able to use regularly, to actually genuinely use winget as the main means of installing and managing applications.

Unfortunately at the moment, that command is not viable in a lot of cases, as for certain packages, such as the Unity Editor, I do not want to upgrade to a newer version, as having and using a specific version is critical.

Some apps/games may also have their own self-updating process, such as ppy/osu which auto-updates in game, and winget does not seem to detect those updates, and still thinks one is required through it.

denelon commented 1 year ago

What's on the Roadmap?

brainz80 commented 1 year ago

Pinning now seems to be a thing in the experimental features.

winget pin
Windows Package Manager v1.4.10173
Copyright (c) Microsoft Corporation. All rights reserved.

This feature is a work in progress, and may be changed dramatically or removed altogether in the future. To enable it, edit your settings ('winget settings') to include the experimental feature: 'pinning'

Though setting

"experimentalFeatures": {
    "pinning": true
}

didn't seem to enable it for me.

nikolaosginos commented 1 year ago

Thanks for the information!

Looks like you will need to install a pre-release build. The v1.4.10173 you have is the latest stable release.

winget features
This is a stable release of the Windows Package Manager. If you would like to try experimental features, please install a pre-release build. Instructions are available on GitHub at https://github.com/microsoft/winget-cli.
denelon commented 1 year ago

I'm glad to see the excitement here!

Before there is any "material" functionality,

needs to get merged, and we need to make a release available. We will certainly include instructions for the first preview version with pinning available as an experimental feature.

ksl28 commented 1 year ago

I still can't believe this isn't a feature after so many years of development, it is critical for wider use and adoption. The winget upgrade --all command is a shortcut many users, including myself, would like to be able to use regularly, to actually genuinely use winget as the main means of installing and managing applications.

Unfortunately at the moment, that command is not viable in a lot of cases, as for certain packages, such as the Unity Editor, I do not want to upgrade to a newer version, as having and using a specific version is critical.

Some apps/games may also have their own self-updating process, such as ppy/osu which auto-updates in game, and winget does not seem to detect those updates, and still thinks one is required through it.

We are awaiting this feature as well - we were super excited about winget, but this missing feature made is drop the project and switch to Chocolatey instead.

rollingmoai commented 1 year ago

Some apps/games may also have their own self-updating process, such as ppy/osu which auto-updates in game, and winget does not seem to detect those updates, and still thinks one is required through it.

This is an issue with the osu itself. Most apps self-update, and Winget properly detects it (unlike Chocolatey). However, osu does not update the version entry in the "Add or Remove Programs" list when self-updating. The issue should be taken upstream. Discord also has the same problem: https://github.com/microsoft/winget-pkgs/issues/15661

brainz80 commented 1 year ago

Yup, noticed this with Discord. Mighty frustrating.

dominikjeske commented 1 year ago

I have just tested pin packages and it works for "--name"

image

winget pin add --name "Notepad++ (32-bit x86)"

but when I tried

winget pin add --id "Microsoft.WindowsSDK"

I get "No package found matching input criteria." Is there any option for search with wildcards? I looked in docs https://github.com/microsoft/winget-cli/blob/master/doc/specs/%23476%20-%20Package%20Pinning.md but there is no specs for query.

I also noticed that "winget pin list" return onlu partial list of pined packages (but pin for that not listed is working because winget upgrade is not displaying them)

florelis commented 1 year ago

@dominikjeske

winget pin add --id "Microsoft.WindowsSDK" I get "No package found matching input criteria."

I think that's a case of us not providing a clear error message. What I imagine is happening is that you have multiple versions of the Windows SDK installed, but winget can only associate one installed app to each package ID, so we don't know which one to pick and return nothing. So it's not "no package found" but rather "multiple installed packages found, and unable to disambiguate". The solution is probably going to be fixing this on the manifests for the Windows SDK to have one ID per version (besides better messaging).

Is there any option for search with wildcards?

No

I looked in docs https://github.com/microsoft/winget-cli/blob/master/doc/specs/%23476%20-%20Package%20Pinning.md but there is no specs for query.

The queries for pinning work the same as for all other winget commands, that is why it's not specified there.

I also noticed that "winget pin list" return onlu partial list of pined packages

Can you share more about the winget pin list only returning a partial list? It's not supposed to, so it may be a bug.

dominikjeske commented 1 year ago

List looks like below - I have filtered out all Microsoft SDK, Runtime etc. you can see in my previous post but I can't see all pined items

image

BrianL-STCU commented 1 year ago

@nikolaosginos I don't see any instructions for installing a pre-release version at that link. I've enabled pinning in the settings.json in v1.4.10173, but winget still tells me to enable pinning in settings.json when I try to use it.

denelon commented 1 year ago

@BrianL-STCU try https://github.com/microsoft/winget-cli/releases/tag/v1.5.441-preview

lackovic commented 1 year ago

I don't see any instructions for installing a pre-release version at that link. I've enabled pinning in the settings.json in v1.4.10173, but winget still tells me to enable pinning in settings.json when I try to use it.

Pinning functionality is not present in version 1.4.10173, even though the commands for it are. See https://github.com/microsoft/winget-cli/discussions/2979

ksl28 commented 1 year ago

Just had the pleasure of testing the preview version, and the pinning feature is exactly what i was hoping for! But i hope that they will add a way, to specify it by parameter like chocolatey --except - so that it can be invoked to clients, without having to edit the settings.json file

denelon commented 1 year ago

@ksl28 we've released it in a preview as an "experimental" feature. Once this is a stable feature, we will release a version that no longer requires enabling the experimental feature.

We've used this pattern in WinGet so we can continue to iterate on features until they become stable. Pinning is currently experimental so we can get user feedback on how it is working, and hopefully and bugs identified can be fixed before the feature becomes stable.

The open Issues related to winget pin represent the current state of the feature.

norahvii commented 1 year ago

Changed my settings to:

{
    "$schema": "https://aka.ms/winget-settings.schema.json",

    "experimentalFeatures": {
        "pinning": true
    }
}

Still wouldn't allow me to take advantage of the feature. What other steps are needed?

mdanish-kh commented 1 year ago

Changed my settings to:

{
    "$schema": "https://aka.ms/winget-settings.schema.json",

    "experimentalFeatures": {
        "pinning": true
    }
}

Still wouldn't allow me to take advantage of the feature. What other steps are needed?

Did you update your client to the 1.5 preview release?

vrolijken commented 1 year ago

A number of "please add a feature to exclude apps from update --all" issues have been closed as a duplicate of this one. I'd like to point out that they may be different things. For instance Microsoft Teams updates itself, but does not update the version number. I do not want to pin Teams at an old version, but I do want to exclude it from the all updates. Another example is that a number of applications are managed by my organisation. I do not want control over which version they should be, I just know that I should not update them myself.

mdanish-kh commented 1 year ago

@vrolijken Please take a look at Package Pinning Types. Your request can be catered by making the pins as Blocking

norahvii commented 1 year ago

I made a python script that doesn't require external libraries to help with this. It seems to work. Feedback appreicated.

dschulman-repay commented 1 year ago

I'm puzzled by the pinning behavior I'm seeing in WinGet 1.6.1573-preview.

Yesterday, a WinGet package for a nightly build of Node.js was released. I'd prefer to wait for an official release, so added a "gating" pin via winget pin add --id=OpenJS.NodeJS --version=20.* --force. That appeared to work:

winget pin list
Name                                            Id                                Version          Source Pin type Pinned version
---------------------------------------------------------------------------------------------------------------------------------
Microsoft 365 Apps for enterprise - en-us       Microsoft.Office                  16.0.16327.20324 winget Pinning
Microsoft Windows Desktop Runtime - 7.0.8 (x64) Microsoft.DotNet.DesktopRuntime.7 7.0.8            winget Pinning
Node.js                                         OpenJS.NodeJS                     20.4.0           winget Gating   20.*

But subsequent calls to winget upgrade produce

Name    Id            Version Available                        Source
---------------------------------------------------------------------
Node.js OpenJS.NodeJS 20.4.0  21.0.0-nightly202307053ca45cf8c7 winget
1 upgrades available.
1 package(s) have version numbers that cannot be determined. Use --include-unknown to see all results.
2 package(s) have pins that prevent upgrade. Use the 'winget pin' command to view and edit pins. Using the --include-pinned argument may show more results.

The issue appears to be that WinGet allows that nightly build to be displayed since its version doesn't match the gating 20.* regex. Which makes sense - but what, if any, mechanism is available for the desired "don't bug me with nightly builds" behavior?

Or am I missing something here?