Skip to content

Commit

Permalink
WinGet Source COM Api (#4813)
Browse files Browse the repository at this point in the history
WinGet Source COM API Support

### This update includes the following changes:

1. Implementation of WinGet COM Package Catalog Management APIs:
- PackageManager.AddPackageCatalogAsync: Allows adding a new Package
Catalog repository to the Windows Package Manager access list.
Administrative rights are required to execute this API..
- PackageManager.RemovePackageCatalogAsync: Enables the removal of an
existing Package Catalog from the Windows Package Manager access list.
Administrative rights are required to execute this API.
- By default, the 'PreserveData' field is set to false, removing both
the PackageCatalog registration data and system artifacts.
- When 'PreserveData' is set to true, only the PackageCatalog
registration data is removed, while system artifacts remain.
- PackageCatalogReference.RefreshPackageCatalogAsync: Allows updating an
existing Package Catalog repository.
2. Necessary C# WinRT Projection to invoke the above API calls from the
test classes.
3. PackageCatalogInterop E2E Inproc and OutOfproc Test Cases to
validate:
    - AddPackageCatalogAsync
    - RemovePackageCatalogAsync
    - RefreshPackageCatalogAsync
4. Added a CallbackDispatcherSink struct that handles and dispatches
progress callbacks for the scenario described above, ensuring progress
is reported to the caller.
5. Updated Package.appxmanifest and
Microsoft.Management.Deployment.InProc.dll.manifest to include the
necessary COM RuntimeClass CLSIDs related to the aforementioned APIs

### How Validated:

1. Compiled AppInstaller.sln
2. Deployed AppInstallerCLIPackage
3. Copied Microsoft.Management.Deployment.winmd next to dot.exe process
that runs test cases
4. Executed InProc tests locally and verified all tests pass.


![image](https://github.com/user-attachments/assets/1c677b85-6610-4b52-bf34-d784ba86d9db)

related: #4170

- [x] I have signed the [Contributor License
Agreement](https://cla.opensource.microsoft.com/microsoft/winget-pkgs).
- [x] This pull request is related to an issue.

-----

###### Microsoft Reviewers: [Open in
CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/microsoft/winget-cli/pull/4813)
  • Loading branch information
Madhusudhan-MSFT authored Oct 28, 2024
1 parent fe939b8 commit f926640
Show file tree
Hide file tree
Showing 35 changed files with 1,538 additions and 9 deletions.
78 changes: 78 additions & 0 deletions src/AppInstallerCLIE2ETests/Interop/GroupPolicyForInterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace AppInstallerCLIE2ETests.Interop
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AppInstallerCLIE2ETests.Helpers;
using Microsoft.Management.Deployment;
Expand Down Expand Up @@ -51,6 +52,16 @@ public void CleanUp()
GroupPolicyHelper.DeleteExistingPolicies();
}

/// <summary>
/// Test class Tear down.
/// </summary>
[OneTimeTearDown]
public void TestClassTearDown()
{
// Restore the tests source if it was removed as the affects subsequent tests.
TestCommon.SetupTestSource();
}

/// <summary>
/// Validates disabling WinGetPolicy should block COM/WinRT Objects creation (InProcess and OutOfProcess).
/// </summary>
Expand Down Expand Up @@ -91,6 +102,14 @@ public void DisableWinGetPolicy()
Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);
Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);

groupPolicyException = Assert.Catch<GroupPolicyException>(() => { AddPackageCatalogOptions packageManagerSettings = this.TestFactory.CreateAddPackageCatalogOptions(); });
Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);
Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);

groupPolicyException = Assert.Catch<GroupPolicyException>(() => { RemovePackageCatalogOptions packageManagerSettings = this.TestFactory.CreateRemovePackageCatalogOptions(); });
Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);
Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);

// PackageManagerSettings is not implemented in context OutOfProcDev
if (this.TestFactory.Context == ClsidContext.InProc)
{
Expand Down Expand Up @@ -159,6 +178,65 @@ public async Task DisableWinGetCommandLineInterfacesPolicy()
var packageVersion = "2.0.0.0";
string downloadDir = Path.Combine(TestCommon.GetDefaultDownloadDirectory(), $"{Constants.ModifyRepairInstaller}_{packageVersion}");
TestCommon.AssertInstallerDownload(downloadDir, "TestModifyRepair", packageVersion, ProcessorArchitecture.X86, TestCommon.Scope.Unknown, PackageInstallerType.Burn, "en-US");

// Add, update and remove package catalog
await this.AddUpdateRemovePackageCatalog();
}

private async Task AddUpdateRemovePackageCatalog()
{
// Remove the tests source if it exists.
await this.RemovePackageCatalog();

PackageManager packageManager = this.TestFactory.CreatePackageManager();

// Add package catalog
AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();
options.SourceUri = Constants.TestSourceUrl;
options.Name = Constants.TestSourceName;
options.TrustLevel = PackageCatalogTrustLevel.Trusted;

var addCatalogResult = await packageManager.AddPackageCatalogAsync(options);
Assert.IsNotNull(addCatalogResult);
Assert.AreEqual(AddPackageCatalogStatus.Ok, addCatalogResult.Status);

// Get package catalog
var packageCatalog = packageManager.GetPackageCatalogByName(options.Name);

Assert.IsNotNull(packageCatalog);
Assert.AreEqual(options.Name, packageCatalog.Info.Name);
Assert.AreEqual(options.SourceUri, packageCatalog.Info.Argument);
var lastUpdatedTime = packageCatalog.Info.LastUpdateTime;

// Update package catalog
// Sleep for 30 seconds to make sure the last updated time is different after the refresh.
Thread.Sleep(TimeSpan.FromSeconds(30));

var updateResult = await packageCatalog.RefreshPackageCatalogAsync();
Assert.IsNotNull(updateResult);
Assert.AreEqual(RefreshPackageCatalogStatus.Ok, updateResult.Status);

packageCatalog = packageManager.GetPackageCatalogByName(options.Name);
Assert.IsTrue(packageCatalog.Info.LastUpdateTime > lastUpdatedTime);

// Remove package catalog
await this.RemovePackageCatalog();
}

private async Task RemovePackageCatalog()
{
PackageManager packageManager = this.TestFactory.CreatePackageManager();

// Remove the tests source if it exists.
RemovePackageCatalogOptions removePackageCatalogOptions = this.TestFactory.CreateRemovePackageCatalogOptions();
removePackageCatalogOptions.Name = Constants.TestSourceName;

var removeCatalogResult = await packageManager.RemovePackageCatalogAsync(removePackageCatalogOptions);
Assert.IsNotNull(removeCatalogResult);
Assert.AreEqual(RemovePackageCatalogStatus.Ok, removeCatalogResult.Status);

var packageCatalog = packageManager.GetPackageCatalogByName(removePackageCatalogOptions.Name);
Assert.IsNull(packageCatalog);
}
}
}
Loading

0 comments on commit f926640

Please sign in to comment.