Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WinGet COM API for Repair #4736

Conversation

Madhusudhan-MSFT
Copy link
Contributor

@Madhusudhan-MSFT Madhusudhan-MSFT commented Aug 15, 2024

This PR introduces the COM API for WinGet Repair Operation. Key updates include:

  • PackageManager.IDL updates for Repair API contracts.
  • Implementation of Repair COM API methods in PackageManager runtime class.
  • Addition of runtime classes for RepairOptions and RepairResults.
  • Integration logic connecting COM API with existing Repair Workflow.
  • Updates to WinGetCLIPackage manifest for Repair COM API GUIDs.
  • Changes to Microsoft.Management.Deployment.InProc to support E2E testing of Repair COM API interops.

Add Repair-WinGetPackage powershell cmdlet to Microsoft.WinGet.Client

  • Introduced a new cmdlet Repair-WinGetPackage to the Microsoft.WinGet.Client PowerShell module

[Tests:]
Added E2E tests for Winget COM Repair API:

  • Introduced RepairInterop.cs for InProc & Out of Proc COM Repair APIs.
  • Extended GroupPolicyForInterop.cs to cover COM Repair API scenarios.

Added PowerShell pester tests for Repair-WinGetPackage cmdlet.

[Validation:]

  • Executed RepairInterop E2E tests and confirmed all tests passed.
  • Executed GroupPolicyForInterop E2E tests and confirmed all tests passed.
  • Executed RepairCommand E2E tests and confirmed all tests passed.

image

  • Executed the Repair-WinGetPackage PowerShell cmdlet manually for a set of test packages and confirmed that it returns the expected results. ex:
- AppInstallerTest.TestMsixInstaller
  - Install-WinGetPackage -Id AppInstallerTest.TestMsixInstaller - return status OK
  - Repair-WinGetPackage -Id AppInstallerTest.TestMsixInstaller - return status OK 
  - Uninstall-WinGetPackage -Id AppInstallerTest.TestMsixInstaller - return status OK
- AppInstallerTest.TestModifyRepair
  - Install-WinGetPackage -Id AppInstallerTest.TestModifyRepair - return status OK
  - Repair-WinGetPackage -Id AppInstallerTest.TestModifyRepair - return status OK
  - Uninstall-WinGetPackage -Id AppInstallerTest.TestModifyRepair - return status OK

Related issue #4246


Microsoft Reviewers: Open in CodeFlow

This commit includes:
1. Necessary additions and updates to PackageManager.idl to define repair-specific COM API contracts and runtime class declarations.
2. Implementation of repair-specific runtime class and PackageManager runtime class repair contract methods skeleton.
3. GUID mapping for In-proc and Out-of-proc COM API class definitions.
4. Updates to `Package.appxmanifest` and `Microsoft.Management.Deployment.InProc.dll.manifest` to include new COM class entries for `RepairOptions`.
5. Updates to `ComClsids.cpp` and `ComClsids.h` to include CLSID definitions and redirection logic for `RepairOptions`.
6. Modifications to `ClassesDefinition.cs` and `WinGetProjectionFactory.cs` to define and create instances of `RepairOptions`and repair com api support for C# winrt projection interop library.
This commit includes:
- A sample interop test to invoke the Winget repair out-of-proc COM API.
- Validation to ensure the COM API endpoint is invocable.
… InstallerErrorCode

- Updated `RepairResultStatus` enum to include `DownloadError`.
- Renamed `InstallerErrorCode` to `RepairErrorCode` in `RepairResult`.
- Added  inline comments for `LogOutputPath` property for directing log output.
- Updated `RepairResult.cpp` and `RepairResult.h` for renaming.
- Integrated Repair COM APIs with workflow.
- Added `COMRepairCommand` class.
- Updated `ContextOrchestrator` with `CreateItemForRepair`.
- Added `GetManifestRepairScope` in `Converters`.
- Enhanced `PackageManager` with repair functions and async methods.
- Introduced RepairInterop.cs for InProc & Out of Proc COM Repair APIs.
- Extended GroupPolicyForInterop.cs to cover COM Repair API scenarios.
Adjusted test assertion in RepairCommand.cs to check for the more general string "Microsoft.Paint" instead of "Microsoft.Paint_8wekyb3d8bbwe". This change ensures compatibility with version-specific output variations.
- Changed `PackageMatchField` from `Name` to `Id`.
- Updated search value from `"Paint"` to `"Microsoft.Paint_8wekyb3d8bbwe"` to ensure accurate package identification.
These changes ensure the test only proceeds if a package is found, preventing false failures and improving test accuracy.
The following tests failed in the Azure pipeline due to ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED (0x8A15007D):
- DisableWinGetCommandLineInterfacesPolicy
- RepairBurnInstallerWithModifyBehavior
- RepairExeInstallerWithUninstallerBehavior
- RepairNullsoftInstallerWithUninstallerBehavior

The problem is due to the OOP COM Server running as admin in the pipeline, which is not the case for local test runs. This discrepancy may indicate different test configurations in the pipeline. This prevents the repair of user-scope installed packages. The solution is to install the test package to system scope, similar to In-Proc tests.

-  Made minor optimizations to the replacement arguments string building logic.
@Madhusudhan-MSFT Madhusudhan-MSFT marked this pull request as ready for review August 16, 2024 20:12
@Madhusudhan-MSFT Madhusudhan-MSFT requested a review from a team as a code owner August 16, 2024 20:12
Copy link
Member

@JohnMcPMS JohnMcPMS left a comment

Choose a reason for hiding this comment

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

Microsoft.Management.Deployment.OutOfProc needs to be updated as well.

src/Microsoft.Management.Deployment/PackageManager.idl Outdated Show resolved Hide resolved
@JohnMcPMS
Copy link
Member

JohnMcPMS commented Aug 19, 2024

Could you please explain a bit more about the comment 'Microsoft.Management.Deployment.OutOfProc needs to be updated as well'? Where is it located, and what exactly needs to be updated?

https://github.com/microsoft/winget-cli/blob/master/src/Microsoft.Management.Deployment.OutOfProc/Factory.cpp #Resolved

The DownloadDirectory parameter and its associated logic have been
removed from WinGet COM Repair logic.

This includes:
- Removal of the DownloadDirectory from the interface definition in
  PackageManager.idl.
- Removal of the code that adds the DownloadDirectory argument to
  the context in PackageManager.cpp.
- Removal of the getter and setter methods in RepairOptions.cpp.
- Removal of the m_downloadPath member variable in RepairOptions.h.
@Madhusudhan-MSFT
Copy link
Contributor Author

Madhusudhan-MSFT commented Aug 20, 2024

Could you please explain a bit more about the comment 'Microsoft.Management.Deployment.OutOfProc needs to be updated as well'? Where is it located, and what exactly needs to be updated?

https://github.com/microsoft/winget-cli/blob/master/src/Microsoft.Management.Deployment.OutOfProc/Factory.cpp

Thank you for pointing this out. It seems my branch is out of date, and I'm missing some of the changes you've introduced. I'll pull the latest updates and make the necessary adjustments. #Resolved

…roc Factory.cpp

Introduce a new CLSID for RepairOptions in the Microsoft::Management::Deployment::OutOfProc namespace. Update the s_nameCLSIDPairs array to include the new NameCLSIDPair for RepairOptions, increasing the array size from 8 to 9. This change enables the system to recognize and work with RepairOptions similarly to other components.
JohnMcPMS
JohnMcPMS previously approved these changes Aug 20, 2024
Introduced a new cmdlet `Repair-WinGetPackage` to the Microsoft.WinGet.Client PowerShell module. This cmdlet allows users to repair packages with different modes (Default, Silent, Interactive) and provides detailed results of the repair operation.

Key changes:
- Added new classes and methods to support the repair functionality.
- Updated `Format.ps1xml` to include a new view definition for `PSRepairResult`.
- Added new localized strings for repair operations.
- Updated `README.md` and added a sample script `Sample_RepairPackage.ps1`.
- Included `Repair-WinGetPackage` in the list of exported cmdlets in `Microsoft.WinGet.Client.psd1`.

This comment has been minimized.

…llCheck error

Renamed the parameter `pSCatalogPackage` to `psCatalogPackage` in the
`RepairPackageCommand` constructor and updated all references to
ensure consistency and improve readability with camelCase naming.
Reformatted XML structure in Format.ps1xml file to resolve 'Node TableRowEntries is missing' error. Adjusted the <TableRowEntries> and its nested elements accordingly.
- Introduced `Install|Repair|Uninstall-WinGetPackage` test suite in `Microsoft.WinGet.Client.Tests.ps1` to cover installation, repair, and uninstallation of MSIX, Burn Installer, and Exe Installer packages.
- Each test verifies expected results, including non-null results, correct package Ids, names, sources, error codes, statuses, and reboot requirements.
- `BeforeAll` block adds a test source, and `AfterAll` block ensures cleanup by uninstalling test packages.
- Added `Validate-WinGetResultCommonFields` and `Validate-WinGetPackageOperationResult` functions in `Microsoft.WinGet.Client.Tests.ps1` to validate common fields and specific operation results for WinGet package operations.
- Refactor install, repair, and uninstall test cases to use these functions, removing individual validation steps and adding contexts for better organization.
- Simplify test logic by creating an expected result object and passing it to the validation function.
…ets:

- Added BeforeEach block to define expected result objects.
- Replaced inline assertions with Validate-WinGetPackageOperationResult.
- Centralized validation logic to improve readability and maintainability.
Changed the namespace for the `PSPackageRepairMode` enum from `Microsoft.WinGet.Client.Cmdlets.Cmdlets.PSObjects` to `Microsoft.WinGet.Client.PSObjects`. Updated `RepairPackageCmdlet.cs` to reflect this change, ensuring correct references.
Updated `Microsoft.WinGet.Client.md` to include the new `Repair-WinGetPackage` cmdlet. Created `Repair-WinGetPackage.md` to document the cmdlet, including synopsis, syntax, detailed description, examples, parameter descriptions, common parameters, input/output types, and related links.

This comment has been minimized.

…l check error fix.

Corrected the type definition of the -Confirm parameter from
'SSystem.Management.Automation.witchParameter' to
'System.Management.Automation.SwitchParameter' in the
Repair-WinGetPackage.md file.
Madhusudhan-MSFT and others added 4 commits September 4, 2024 13:13
Added new interfaces in the `Microsoft.Management.Deployment`
namespace within the `PackageManager.idl` file. Added interfaces
for handling collections of `RepairOptions` and `RepairResult`:
- `Windows.Foundation.Collections.IVector<RepairOptions>`
- `Windows.Foundation.Collections.IVectorView<RepairOptions>`
- `Windows.Foundation.Collections.IVector<RepairResult>`
- `Windows.Foundation.Collections.IVectorView<RepairResult>`

These changes enhance the functionality related to repair operations
in the package management system by allowing manipulation and viewing
of these collections.
…ethods

- Updated the comment in `PackageManager.idl` to clarify that `CorrelationData` is used for the repair process.
- In `RepairPackageCommand.cs`, replaced the method call to `PackageManagerWrapper.Instance.RepairPackageAsync` with `this.RepairPackageAsync`.
- Renamed `RepairResultAsync` to `RepairPackageAsync` for better clarity.
Revised the contract version from 11 to 12 for repair-specific implementations because version 11 conflicted with the previous addition but code wasn't in sync.
Madhusudhan-MSFT and others added 7 commits September 9, 2024 14:48
- The GetRepairProgress method has been removed from both the implementation file (PackageManager.cpp) and the interface definition file (PackageManager.idl).
- This method was designed to return the progress of a repair operation for a given package and catalog information to allow another client to find asynchronously. However, we currently do not have a practical use case for this functionality. If this requirement arises in the future, we will consider adding it back.
Updated `Converters.h` to use `NoApplicableRepairer` instead of `NoApplicableInstallers`. Added handling for `AllowHashMismatch`, `BypassIsStoreClientBlockedPolicyCheck`, and `Force` in `PackageManager.cpp` and `PackageManager.idl`.
- Renamed `NoApplicableInstallers` to `NoApplicableRepairer` and `RepairErrorCode` to `RepairerErrorCode` in `PackageManager.idl`.

Added getter and setter methods for new options in `RepairOptions.cpp` and declarations in `RepairOptions.h`. Updated `RepairResult.cpp` and `RepairResult.h` to use `repairerErrorCode`. Enhanced `RepairPackageCmdlet.cs` and `RepairPackageCommand.cs` to handle new parameters. Updated `PSRepairResult.cs` to use `RepairerErrorCode`.
- Updated `RepairOptionsIid` GUID in `ManagementDeploymentFactory` to align with WinRT MIDL-generated interface ID for `RepairOptions` resulted from API review feedback changes in last commit.

This resolves COMException: Failed to create instance: -2147467262 when PowerShell tests invoke Repair-WinGetPackage cmdlet.

- Corrected XML documentation for `CreateRepairOptions` method to accurately describe it creates an instance of `RepairOptions` class instead of `PackageMatchFilter` class.
- Introduced a new exception class `WinGetRepairPackageException` in `WinGetRepairPackageException.cs` to encapsulate various error scenarios during the repair operation.
- Updated `RepairPackageCommand.cs` to throw `WinGetRepairPackageException` when specific error conditions are met during the repair process.
- Added new error codes in `ErrorCode.cs` to represent different repair-related errors such as `NoRepairInfoFound`, `RepairNotApplicable`, `RepairerFailure`, `RepairNotSupported`, and `AdminContextRepairProhibited`.
- Enhanced `Resources.Designer.cs` and `Resources.resx` with new localized strings to provide user-friendly error messages for the new error codes.
- Modified the `RepairPackageCommand.cs` to handle and throw exceptions with detailed error messages based on the new error codes and localized strings.
.github/actions/spelling/allow.txt Outdated Show resolved Hide resolved
src/AppInstallerCLICore/ContextOrchestrator.h Show resolved Hide resolved
src/Microsoft.Management.Deployment/Converters.h Outdated Show resolved Hide resolved
src/Microsoft.Management.Deployment/PackageManager.cpp Outdated Show resolved Hide resolved
{
// Repair the specified package
Windows.Foundation.IAsyncOperationWithProgress<RepairResult, RepairProgress> RepairPackageAsync(CatalogPackage package, RepairOptions options);
}
Copy link
Contributor

@yao-msft yao-msft Oct 4, 2024

Choose a reason for hiding this comment

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

Missing GetRepairProgress #WontFix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

During the API review process, we decided against including GetRepairProgress as we couldn't identify a scenario where another client would need to track the asynchronous operation for repair.

- Added inline comment for `COMRepairCommand` in `COMCommand.cpp`.
- Updated inline comments in `ContextOrchestrator.cpp` and `ContextOrchestrator.h` to reflect repair commands specific changes.
- Introduced `ModifyRepairInstaller` constant in `Constants.cs` and refactored related files for consistency.
- Modified `Converters.h` to map error codes for repair operations.
- Removed an unnecessary `Natvis` include from `Microsoft.Management.Deployment.vcxproj.filters`.
- Corrected a comment in `PackageManager.cpp` about repair requirements.
- Enhanced `RepairPackageCommand.cs` to search both local and remote catalogs.
- Updated resource strings in `Resources.Designer.cs` and `Resources.resx` for clarity in error messages.
- Removed the GetRepairProgress method from the PackageManager class
- Updated the CompositeSearchBehavior in RepairPackageCommand.cs to use AllCatalogs, broadening the scope of package searches.
- Also, added a newline for readability in PackageManager.cpp.
@Madhusudhan-MSFT Madhusudhan-MSFT merged commit 27f9000 into microsoft:master Oct 7, 2024
9 checks passed
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.

5 participants