Skip to content

Conversation

@JohnMcPMS
Copy link
Member

@JohnMcPMS JohnMcPMS commented Oct 29, 2025

Fixes #5826 and #5827

Issue

A previous change introduced a COM API to retrieve the WinGet version. The PowerShell methods to get the version were updated to try using it before invoking the existing method (run winget --version).

This caused Repair-WGPM to use COM for the first time (IFF a version specifier was provided [which includes -Latest]). This caused the two linked issues:

  1. Repair-WinGetPackageManager -Latest fails on the new PowerShell module v1.12.350 #5826 :: In .NET Framework (Windows PowerShell), the .winmd file must be found in order to generate the COM type information at runtime. This is required when jit'ing the new version API, used only when a version specifier is provided. This doesn't affect .NET Core (PowerShell 7) because exceptions are swallowed to support backward compat and the types are all pre-generated by CsWinRT. Only commands deriving from a specific type were doing the initialization required.
  2. Repair-WinGetPackageManager failing on version 1.12.350 #5827 :: Calling a COM API means that the server is active, making attempts to install the package fail due to an in-use error. This required -Force to be provided, again only if a version specifier was provided.

Change

The larger part of this change reworks the existing assert and repair state machine to better re-use the call to winget --version that is actually attempting to probe for WinGet CLI functionality. We keep that result around and use it when comparing to the supplied target version rather than attempting to retrieve the version again. If the version is not correct, we attach it to the exception that is thrown so that we can re-use it once again during the attempt to install the different version.

Since the first attempt to call winget --version has to succeed in order to get to the code that would check the current version, we can successfully avoid the COM call in this path every time. Ultimately this means that if WinGet is already installed properly, attempting to change the version with Repair only gets the version once instead of the previous 3 times.

The final portion of the change updates the base command for Repair and Assert to the one that provides the COM initialization. While this shouldn't be necessary with the other portion, it is preferable to supply -Force as a workaround than to simply wait for a resolution if the type cannot be loaded.

Validation

Manually confirmed flow of saved version information with debugger and the lack of COM server running.
Additional tests are planned for the internal build to better test the real flow due to the complexity.

Microsoft Reviewers: Open in CodeFlow

…hat it shouldn't actually use COM to get the version (nor need to get the version *3* times when changing versions)
public static WinGetCLICommandResult RunWinGetVersionFromCLI(PowerShellCmdlet pwshCmdlet, bool fullPath = true)
{
var wingetCliWrapper = new WingetCLIWrapper(fullPath);
return wingetCliWrapper.RunCommand(pwshCmdlet, "--version");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before running the command, perhaps check if winget is actually callable?
Ref #4005 / #5793

@JohnMcPMS
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@JohnMcPMS JohnMcPMS merged commit 419875b into microsoft:master Oct 31, 2025
9 checks passed
@JohnMcPMS JohnMcPMS deleted the repair-version branch October 31, 2025 18:37
JohnMcPMS added a commit to JohnMcPMS/winget-cli that referenced this pull request Nov 4, 2025
…rosoft#5842)

Fixes microsoft#5826 and microsoft#5827

## Issue
A previous change introduced a COM API to retrieve the WinGet version.
The PowerShell methods to get the version were updated to try using it
before invoking the existing method (run `winget --version`).

This caused Repair-WGPM to use COM for the first time (IFF a version
specifier was provided [which includes `-Latest`]). This caused the two
linked issues:
1. microsoft#5826 :: In .NET Framework (Windows PowerShell), the .winmd file must
be found in order to generate the COM type information at runtime. This
is required when jit'ing the new version API, used only when a version
specifier is provided. This doesn't affect .NET Core (PowerShell 7)
because exceptions are swallowed to support backward compat and the
types are all pre-generated by CsWinRT. Only commands deriving from a
specific type were doing the initialization required.
2. microsoft#5827 :: Calling a COM API means that the server is active, making
attempts to install the package fail due to an in-use error. This
required `-Force` to be provided, again only if a version specifier was
provided.

## Change
The larger part of this change reworks the existing assert and repair
state machine to better re-use the call to `winget --version` that is
actually attempting to probe for WinGet CLI functionality. We keep that
result around and use it when comparing to the supplied target version
rather than attempting to retrieve the version again. If the version is
not correct, we attach it to the exception that is thrown so that we can
re-use it once again during the attempt to install the different
version.

Since the first attempt to call `winget --version` has to succeed in
order to get to the code that would check the current version, we can
successfully avoid the COM call in this path every time. Ultimately this
means that if WinGet is already installed properly, attempting to change
the version with Repair only gets the version once instead of the
previous 3 times.

The final portion of the change updates the base command for Repair and
Assert to the one that provides the COM initialization. While this
shouldn't be necessary with the other portion, it is preferable to
supply `-Force` as a workaround than to simply wait for a resolution if
the type cannot be loaded.
JohnMcPMS added a commit that referenced this pull request Nov 4, 2025
…to 1.12) (#5858)

CP of #5842

## Issue
A previous change introduced a COM API to retrieve the WinGet version.
The PowerShell methods to get the version were updated to try using it
before invoking the existing method (run `winget --version`).

This caused Repair-WGPM to use COM for the first time (IFF a version
specifier was provided [which includes `-Latest`]). This caused the two
linked issues:
1. #5826 :: In .NET Framework (Windows PowerShell), the .winmd file must
be found in order to generate the COM type information at runtime. This
is required when jit'ing the new version API, used only when a version
specifier is provided. This doesn't affect .NET Core (PowerShell 7)
because exceptions are swallowed to support backward compat and the
types are all pre-generated by CsWinRT. Only commands deriving from a
specific type were doing the initialization required.
2. #5827 :: Calling a COM API means that the server is active, making
attempts to install the package fail due to an in-use error. This
required `-Force` to be provided, again only if a version specifier was
provided.

## Change
The larger part of this change reworks the existing assert and repair
state machine to better re-use the call to `winget --version` that is
actually attempting to probe for WinGet CLI functionality. We keep that
result around and use it when comparing to the supplied target version
rather than attempting to retrieve the version again. If the version is
not correct, we attach it to the exception that is thrown so that we can
re-use it once again during the attempt to install the different
version.

Since the first attempt to call `winget --version` has to succeed in
order to get to the code that would check the current version, we can
successfully avoid the COM call in this path every time. Ultimately this
means that if WinGet is already installed properly, attempting to change
the version with Repair only gets the version once instead of the
previous 3 times.

The final portion of the change updates the base command for Repair and
Assert to the one that provides the COM initialization. While this
shouldn't be necessary with the other portion, it is preferable to
supply `-Force` as a workaround than to simply wait for a resolution if
the type cannot be loaded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Repair-WinGetPackageManager -Latest fails on the new PowerShell module v1.12.350

3 participants