winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 9f3511b1b46e6e475124653be9befa39671ccbb0
parent 190b81298eec67c993f62cb3c05bd5d13cb7e8b9
Author: Flor Chacón <14323496+florelis@users.noreply.github.com>
Date:   Wed, 25 Oct 2023 11:25:11 -0700

Extend Configuration COM API for export (#3787)


Diffstat:
Msrc/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw | 3+++
Msrc/AppInstallerSharedLib/Errors.cpp | 1+
Msrc/AppInstallerSharedLib/Public/AppInstallerErrors.h | 1+
Msrc/Microsoft.Management.Configuration.Processor/DscModules/DscModuleV2.cs | 2+-
Msrc/Microsoft.Management.Configuration.Processor/Unit/ConfigurationUnitProcessor.cs | 1-
Asrc/Microsoft.Management.Configuration.Processor/Unit/GetAllSettingsResult.cs | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs | 2--
Msrc/Microsoft.Management.Configuration.UnitTests/Helpers/Errors.cs | 16++++++++++++++++
Asrc/Microsoft.Management.Configuration.UnitTests/Helpers/GetAllSettingsResultInstance.cs | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs | 12++++++++++++
Msrc/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs | 1-
Asrc/Microsoft.Management.Configuration.UnitTests/Helpers/TestGetAllSettingsConfigurationUnitProcessor.cs | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs | 6+-----
Asrc/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorGetAllTests.cs | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorGetTests.cs | 207+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorTestTests.cs | 5-----
Msrc/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationUnitProcessorTests.cs | 1+
Dsrc/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs | 208-------------------------------------------------------------------------------
Msrc/Microsoft.Management.Configuration/ConfigurationProcessor.cpp | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Microsoft.Management.Configuration/ConfigurationProcessor.h | 6++++++
Asrc/Microsoft.Management.Configuration/GetAllConfigurationUnitSettingsResult.cpp | 33+++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Configuration/GetAllConfigurationUnitSettingsResult.h | 27+++++++++++++++++++++++++++
Msrc/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl | 43++++++++++++++++++++++++++++++++++++++++++-
Msrc/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj | 2++
Msrc/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters | 6++++++
Msrc/Microsoft.Management.Configuration/Telemetry/Telemetry.h | 1+
26 files changed, 727 insertions(+), 224 deletions(-)

diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -2581,6 +2581,9 @@ Please specify one of them using the --source option to proceed.</value> <data name="WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT" xml:space="preserve"> <value>A unit contains a setting that requires the config root.</value> </data> + <data name="WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR" xml:space="preserve"> + <value>Operation is not supported by the configuration processor.</value> + </data> <data name="Unavailable" xml:space="preserve"> <value>Unavailable</value> </data> diff --git a/src/AppInstallerSharedLib/Errors.cpp b/src/AppInstallerSharedLib/Errors.cpp @@ -262,6 +262,7 @@ namespace AppInstaller WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT, "The configuration unit returned an unexpected result during execution."), WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT, "A unit contains a setting that requires the config root."), WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN, "Loading the module for the configuration unit failed because it requires administrator privileges to run."), + WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR, "Operation is not supported by the configuration processor."), // Errors without the error bit set WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE, "The install location is not applicable."), diff --git a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h @@ -195,6 +195,7 @@ #define WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT ((HRESULT)0x8A15C109) #define WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT ((HRESULT)0x8A15C110) #define WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN ((HRESULT)0x8A15C111) +#define WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR ((HRESULT)0x8A15C112) namespace AppInstaller { diff --git a/src/Microsoft.Management.Configuration.Processor/DscModules/DscModuleV2.cs b/src/Microsoft.Management.Configuration.Processor/DscModules/DscModuleV2.cs @@ -6,12 +6,12 @@ namespace Microsoft.Management.Configuration.Processor.DscModule { + using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Management.Automation; - using System.Text; using Microsoft.Management.Configuration.Processor.DscResourcesInfo; using Microsoft.Management.Configuration.Processor.Exceptions; using Microsoft.Management.Configuration.Processor.Extensions; diff --git a/src/Microsoft.Management.Configuration.Processor/Unit/ConfigurationUnitProcessor.cs b/src/Microsoft.Management.Configuration.Processor/Unit/ConfigurationUnitProcessor.cs @@ -7,7 +7,6 @@ namespace Microsoft.Management.Configuration.Processor.Unit { using System; - using System.Collections.Generic; using Microsoft.Management.Configuration; using Microsoft.Management.Configuration.Processor.Exceptions; using Microsoft.Management.Configuration.Processor.Extensions; diff --git a/src/Microsoft.Management.Configuration.Processor/Unit/GetAllSettingsResult.cs b/src/Microsoft.Management.Configuration.Processor/Unit/GetAllSettingsResult.cs @@ -0,0 +1,46 @@ +// ----------------------------------------------------------------------------- +// <copyright file="GetAllSettingsResult.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.Processor.Unit +{ + using System.Collections.Generic; + using Microsoft.Management.Configuration; + using Windows.Foundation.Collections; + + /// <summary> + /// Implements IGetAllSettingsResult. + /// </summary> + internal class GetAllSettingsResult : IGetAllSettingsResult + { + /// <summary> + /// Initializes a new instance of the <see cref="GetAllSettingsResult"/> class. + /// </summary> + /// <param name="unit">The configuration unit that the result is for.</param> + public GetAllSettingsResult(ConfigurationUnit unit) + { + this.Unit = unit; + } + + /// <summary> + /// Gets the configuration unit that the result is for. + /// </summary> + public ConfigurationUnit Unit { get; private set; } + + /// <inheritdoc/> + public IConfigurationUnitResultInformation ResultInformation + { + get { return this.InternalResult; } + } + + /// <summary> + /// Gets the implementation object for ResultInformation. + /// </summary> + public ConfigurationUnitResultInformation InternalResult { get; } = new ConfigurationUnitResultInformation(); + + /// <inheritdoc/> + public IList<ValueSet>? Settings { get; internal set; } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs @@ -7,9 +7,7 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers { using System; - using Microsoft.CodeAnalysis.Emit; using Microsoft.Management.Configuration.UnitTests.Fixtures; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Windows.Storage.Streams; using Xunit; using Xunit.Abstractions; diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/Errors.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/Errors.cs @@ -29,6 +29,22 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers public static readonly int WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE = unchecked((int)0x8A15C00C); public static readonly int WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE = unchecked((int)0x8A15C00D); public static readonly int WINGET_CONFIG_ERROR_MISSING_FIELD = unchecked((int)0x8A15C00E); + public static readonly int WINGET_CONFIG_ERROR_TEST_FAILED = unchecked((int)0x8A15C00F); + public static readonly int WINGET_CONFIG_ERROR_TEST_NOT_RUN = unchecked((int)0x8A15C010); + + // Configuration Processor Errors + public static readonly int WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED = unchecked((int)0x8A15C101); + public static readonly int WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY = unchecked((int)0x8A15C102); + public static readonly int WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES = unchecked((int)0x8A15C103); + public static readonly int WINGET_CONFIG_ERROR_UNIT_INVOKE_GET = unchecked((int)0x8A15C104); + public static readonly int WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST = unchecked((int)0x8A15C105); + public static readonly int WINGET_CONFIG_ERROR_UNIT_INVOKE_SET = unchecked((int)0x8A15C106); + public static readonly int WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT = unchecked((int)0x8A15C107); + public static readonly int WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE = unchecked((int)0x8A15C108); + public static readonly int WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT = unchecked((int)0x8A15C109); + public static readonly int WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT = unchecked((int)0x8A15C110); + public static readonly int WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN = unchecked((int)0x8A15C111); + public static readonly int WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR = unchecked((int)0x8A15C112); #pragma warning restore SA1025 // Code should not contain multiple whitespace in a row #pragma warning restore SA1600 // Elements should be documented diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/GetAllSettingsResultInstance.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/GetAllSettingsResultInstance.cs @@ -0,0 +1,46 @@ +// ----------------------------------------------------------------------------- +// <copyright file="GetAllSettingsResultInstance.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Helpers +{ + using System.Collections.Generic; + using Microsoft.Management.Configuration; + using Windows.Foundation.Collections; + + /// <summary> + /// Implements IGetAllSettingsResult. + /// </summary> + internal sealed class GetAllSettingsResultInstance : IGetAllSettingsResult + { + /// <summary> + /// Initializes a new instance of the <see cref="GetAllSettingsResultInstance"/> class. + /// </summary> + /// <param name="unit">The configuration unit that the result is for.</param> + public GetAllSettingsResultInstance(ConfigurationUnit unit) + { + this.Unit = unit; + } + + /// <summary> + /// Gets the configuration unit that the result is for. + /// </summary> + public ConfigurationUnit Unit { get; private set; } + + /// <inheritdoc/> + public IConfigurationUnitResultInformation ResultInformation + { + get { return this.InternalResult; } + } + + /// <summary> + /// Gets the implementation object for ResultInformation. + /// </summary> + public TestConfigurationUnitResultInformation InternalResult { get; } = new TestConfigurationUnitResultInformation(); + + /// <inheritdoc/> + public IList<ValueSet>? Settings { get; internal set; } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs @@ -96,6 +96,18 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers } /// <summary> + /// Creates a new test processor that supports GetAllSettings for the given unit. + /// </summary> + /// <param name="unit">The unit.</param> + /// <returns>The configuration unit processor.</returns> + internal TestGetAllSettingsConfigurationUnitProcessor CreateGetAllSettingsTestProcessor(ConfigurationUnit unit) + { + var processor = new TestGetAllSettingsConfigurationUnitProcessor(unit); + this.Processors[unit] = processor; + return processor; + } + + /// <summary> /// Creates a new unit processor details for the given unit. /// </summary> /// <param name="unit">The unit.</param> diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs @@ -6,7 +6,6 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers { - using System; using System.Collections.Generic; /// <summary> diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestGetAllSettingsConfigurationUnitProcessor.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestGetAllSettingsConfigurationUnitProcessor.cs @@ -0,0 +1,56 @@ +// ----------------------------------------------------------------------------- +// <copyright file="TestGetAllSettingsConfigurationUnitProcessor.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Helpers +{ + /// <summary> + /// A test implementation of IConfigurationProcessorFactory. + /// </summary> + internal class TestGetAllSettingsConfigurationUnitProcessor : TestConfigurationUnitProcessor, IGetAllSettingsConfigurationUnitProcessor + { + /// <summary> + /// Initializes a new instance of the <see cref="TestGetAllSettingsConfigurationUnitProcessor"/> class. + /// </summary> + /// <param name="unit">The unit.</param> + internal TestGetAllSettingsConfigurationUnitProcessor(ConfigurationUnit unit) + : base(unit) + { + } + + /// <summary> + /// The delegate for GetAllSettings. + /// </summary> + /// <returns>The result.</returns> + internal delegate IGetAllSettingsResult GetAllSettingsDelegateType(); + + /// <summary> + /// Gets or sets the delegate object for GetAllSettings. + /// </summary> + internal GetAllSettingsDelegateType? GetAllSettingsDelegate { get; set; } + + /// <summary> + /// Gets the number of times GetAllSettings is called. + /// </summary> + internal int GetAllSettingsCalls { get; private set; } = 0; + + /// <summary> + /// Calls the GetAllSettingsDelegate if one is provided; returns success if not (with no settings values). + /// </summary> + /// <returns>The result.</returns> + public IGetAllSettingsResult GetAllSettings() + { + ++this.GetAllSettingsCalls; + if (this.GetAllSettingsDelegate != null) + { + return this.GetAllSettingsDelegate(); + } + else + { + return new GetAllSettingsResultInstance(this.Unit); + } + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs @@ -7,22 +7,18 @@ namespace Microsoft.Management.Configuration.UnitTests.Tests { using System; - using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; - using System.Runtime.InteropServices; using System.Threading; - using Microsoft.CodeAnalysis.Emit; using Microsoft.Management.Configuration.UnitTests.Fixtures; using Microsoft.Management.Configuration.UnitTests.Helpers; using Microsoft.VisualBasic; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Xunit; using Xunit.Abstractions; /// <summary> - /// Unit tests for running test on the processor. + /// Unit tests for running apply on the processor. /// </summary> [Collection("UnitTestCollection")] [OutOfProc] diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorGetAllTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorGetAllTests.cs @@ -0,0 +1,146 @@ +// ----------------------------------------------------------------------------- +// <copyright file="ConfigurationProcessorGetAllTests.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Tests +{ + using System.Collections.Generic; + using System.IO; + using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Microsoft.Management.Configuration.UnitTests.Helpers; + using Microsoft.VisualBasic; + using Windows.Foundation.Collections; + using Xunit; + using Xunit.Abstractions; + + /// <summary> + /// Unit tests for getting details on processors. + /// </summary> + [Collection("UnitTestCollection")] + [OutOfProc] + public class ConfigurationProcessorGetAllTests : ConfigurationProcessorTestBase + { + /// <summary> + /// Initializes a new instance of the <see cref="ConfigurationProcessorGetAllTests"/> class. + /// </summary> + /// <param name="fixture">Unit test fixture.</param> + /// <param name="log">Log helper.</param> + public ConfigurationProcessorGetAllTests(UnitTestFixture fixture, ITestOutputHelper log) + : base(fixture, log) + { + } + + /// <summary> + /// The unit settings processor returns an error HRESULT. + /// </summary> + [Fact] + public void GetAllSettings_ProcessorSettingsError() + { + ConfigurationUnit configurationUnit = this.ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + var unitProcessor = factory.NullProcessor.CreateGetAllSettingsTestProcessor(configurationUnit); + unitProcessor.GetAllSettingsDelegate = () => throw new FileNotFoundException(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetAllConfigurationUnitSettingsResult result = processor.GetAllUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.Null(result.Settings); + Assert.NotNull(result.ResultInformation); + Assert.NotNull(result.ResultInformation.ResultCode); + Assert.IsType<FileNotFoundException>(result.ResultInformation.ResultCode); + } + + /// <summary> + /// The unit settings processor returns an error in its result. + /// </summary> + [Fact] + public void GetAllSettings_ProcessorSettingsFailedResult() + { + ConfigurationUnit configurationUnit = this.ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + var unitProcessor = factory.NullProcessor.CreateGetAllSettingsTestProcessor(configurationUnit); + + GetAllSettingsResultInstance getAllSettingsResult = new GetAllSettingsResultInstance(configurationUnit); + getAllSettingsResult.InternalResult.ResultCode = new InvalidDataException(); + getAllSettingsResult.InternalResult.Description = "We fail because we must"; + unitProcessor.GetAllSettingsDelegate = () => getAllSettingsResult; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetAllConfigurationUnitSettingsResult result = processor.GetAllUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.Null(result.Settings); + Assert.NotNull(result.ResultInformation); + Assert.Equal(getAllSettingsResult.ResultInformation.ResultCode.HResult, result.ResultInformation.ResultCode.HResult); + Assert.Equal(getAllSettingsResult.ResultInformation.Description, result.ResultInformation.Description); + } + + /// <summary> + /// The unit settings processor returns good settings. + /// </summary> + [Fact] + public void GetAllSettings_ProcessorSettingsSuccess() + { + ConfigurationUnit configurationUnit = this.ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + var unitProcessor = factory.NullProcessor.CreateGetAllSettingsTestProcessor(configurationUnit); + + GetAllSettingsResultInstance getAllSettingsResult = new GetAllSettingsResultInstance(configurationUnit); + getAllSettingsResult.Settings = new List<ValueSet>() + { + new ValueSet + { + { "key", "value" }, + }, + }; + unitProcessor.GetAllSettingsDelegate = () => getAllSettingsResult; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetAllConfigurationUnitSettingsResult result = processor.GetAllUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.NotNull(result.ResultInformation); + Assert.Null(result.ResultInformation.ResultCode); + Assert.Empty(result.ResultInformation.Description); + Assert.NotNull(result.Settings); + Assert.Equal(1, result.Settings.Count); + Assert.Contains("key", result.Settings[0]); + Assert.IsType<string>(result.Settings[0]["key"]); + Assert.Equal("value", (string)result.Settings[0]["key"]); + } + + /// <summary> + /// The unit settings processor does not support GetAllSettings. + /// </summary> + [Fact] + public void GetAllSettings_UnsupportedByProcessor() + { + ConfigurationUnit configurationUnit = this.ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + var unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetAllConfigurationUnitSettingsResult result = processor.GetAllUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.NotNull(result.ResultInformation); + Assert.NotNull(result.ResultInformation.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR, result.ResultInformation.ResultCode.HResult); + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorGetTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorGetTests.cs @@ -0,0 +1,207 @@ +// ----------------------------------------------------------------------------- +// <copyright file="ConfigurationProcessorGetTests.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Tests +{ + using System.Collections.Generic; + using System.IO; + using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Microsoft.Management.Configuration.UnitTests.Helpers; + using Microsoft.VisualBasic; + using Xunit; + using Xunit.Abstractions; + + /// <summary> + /// Unit tests for getting details on processors. + /// </summary> + [Collection("UnitTestCollection")] + [OutOfProc] + public class ConfigurationProcessorGetTests : ConfigurationProcessorTestBase + { + /// <summary> + /// Initializes a new instance of the <see cref="ConfigurationProcessorGetTests"/> class. + /// </summary> + /// <param name="fixture">Unit test fixture.</param> + /// <param name="log">Log helper.</param> + public ConfigurationProcessorGetTests(UnitTestFixture fixture, ITestOutputHelper log) + : base(fixture, log) + { + } + + /// <summary> + /// Getting unit details throws an error. + /// </summary> + [Fact] + public void GetUnitDetailsError() + { + ConfigurationUnit configurationUnitThrows = this.ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + var thrownException = new FileNotFoundException(); + factory.NullProcessor.Exceptions.Add(configurationUnitThrows, thrownException); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetConfigurationUnitDetailsResult result = processor.GetUnitDetails(configurationUnitThrows, ConfigurationUnitDetailFlags.Local); + + Assert.Null(result.Details); + Assert.Equal(configurationUnitThrows, result.Unit); + Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult); + Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource); + } + + /// <summary> + /// Getting unit details retrieves a value. + /// </summary> + [Fact] + public void GetUnitDetailsSuccess() + { + ConfigurationUnit configurationUnit = this.ConfigurationUnit(); + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + Assert.Null(configurationUnit.Details); + processor.GetUnitDetails(configurationUnit, ConfigurationUnitDetailFlags.Local); + Assert.NotNull(configurationUnit.Details); + } + + /// <summary> + /// Getting set details throws an error. + /// </summary> + [Fact] + public void GetSetDetailsError() + { + ConfigurationSet configurationSet = this.ConfigurationSet(); + ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit(); + ConfigurationUnit configurationUnitThrows = this.ConfigurationUnit(); + configurationSet.Units = new ConfigurationUnit[] { configurationUnitWorks, configurationUnitThrows }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + var thrownException = new InvalidDataException(); + setProcessor.Exceptions.Add(configurationUnitThrows, thrownException); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetConfigurationSetDetailsResult result = processor.GetSetDetails(configurationSet, ConfigurationUnitDetailFlags.Local); + var unitResults = result.UnitResults; + Assert.Equal(2, unitResults.Count); + + Assert.Equal(configurationUnitWorks, unitResults[0].Unit); + Assert.Null(unitResults[0].ResultInformation.ResultCode); + Assert.NotNull(configurationUnitWorks.Details); + + Assert.Equal(configurationUnitThrows, unitResults[1].Unit); + Assert.NotNull(unitResults[1].ResultInformation.ResultCode); + Assert.Equal(thrownException.HResult, unitResults[1].ResultInformation.ResultCode.HResult); + Assert.Null(configurationUnitThrows.Details); + } + + /// <summary> + /// Getting set details retrieves all values. + /// </summary> + [Fact] + public void GetSetDetailsSuccess() + { + ConfigurationSet configurationSet = this.ConfigurationSet(); + ConfigurationUnit configurationUnit1 = this.ConfigurationUnit(); + ConfigurationUnit configurationUnit2 = this.ConfigurationUnit(); + configurationSet.Units = new ConfigurationUnit[] { configurationUnit1, configurationUnit2 }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + processor.GetSetDetails(configurationSet, ConfigurationUnitDetailFlags.Local); + Assert.NotNull(configurationUnit1.Details); + Assert.NotNull(configurationUnit2.Details); + } + + /// <summary> + /// The unit settings processor returns an error HRESULT. + /// </summary> + [Fact] + public void GetSettings_ProcessorSettingsError() + { + ConfigurationUnit configurationUnit = this.ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); + unitProcessor.GetSettingsDelegate = () => throw new FileNotFoundException(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.NotNull(result.Settings); + Assert.NotNull(result.ResultInformation); + Assert.NotNull(result.ResultInformation.ResultCode); + Assert.IsType<FileNotFoundException>(result.ResultInformation.ResultCode); + } + + /// <summary> + /// The unit settings processor returns an error in it's result. + /// </summary> + [Fact] + public void GetSettings_ProcessorSettingsFailedResult() + { + ConfigurationUnit configurationUnit = this.ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); + GetSettingsResultInstance getSettingsResult = new GetSettingsResultInstance(configurationUnit); + getSettingsResult.InternalResult.ResultCode = new InvalidDataException(); + getSettingsResult.InternalResult.Description = "We fail because we must"; + unitProcessor.GetSettingsDelegate = () => getSettingsResult; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.Null(result.Settings); + Assert.NotNull(result.ResultInformation); + Assert.Equal(getSettingsResult.ResultInformation.ResultCode.HResult, result.ResultInformation.ResultCode.HResult); + Assert.Equal(getSettingsResult.ResultInformation.Description, result.ResultInformation.Description); + } + + /// <summary> + /// The unit settings processor returns good settings. + /// </summary> + [Fact] + public void GetSettings_ProcessorSettingsSuccess() + { + ConfigurationUnit configurationUnit = this.ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); + GetSettingsResultInstance getSettingsResult = new GetSettingsResultInstance(configurationUnit); + getSettingsResult.Settings = new Windows.Foundation.Collections.ValueSet(); + getSettingsResult.Settings.Add("key", "value"); + unitProcessor.GetSettingsDelegate = () => getSettingsResult; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.NotNull(result.ResultInformation); + Assert.Null(result.ResultInformation.ResultCode); + Assert.Empty(result.ResultInformation.Description); + Assert.NotNull(result.Settings); + Assert.NotEmpty(result.Settings); + Assert.Contains("key", result.Settings); + Assert.IsType<string>(result.Settings["key"]); + Assert.Equal("value", (string)result.Settings["key"]); + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorTestTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorTestTests.cs @@ -7,16 +7,11 @@ namespace Microsoft.Management.Configuration.UnitTests.Tests { using System; - using System.Collections; - using System.Collections.Generic; using System.IO; using System.Linq; - using System.Runtime.InteropServices; - using Microsoft.CodeAnalysis.Emit; using Microsoft.Management.Configuration.UnitTests.Fixtures; using Microsoft.Management.Configuration.UnitTests.Helpers; using Microsoft.VisualBasic; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Xunit; using Xunit.Abstractions; diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationUnitProcessorTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationUnitProcessorTests.cs @@ -8,6 +8,7 @@ namespace Microsoft.Management.Configuration.UnitTests.Tests { using System; using System.Collections.Generic; + using System.Linq; using System.Management.Automation; using Microsoft.Management.Configuration; using Microsoft.Management.Configuration.Processor.DscResourcesInfo; diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs @@ -1,208 +0,0 @@ -// ----------------------------------------------------------------------------- -// <copyright file="ProcessorGetTests.cs" company="Microsoft Corporation"> -// Copyright (c) Microsoft Corporation. Licensed under the MIT License. -// </copyright> -// ----------------------------------------------------------------------------- - -namespace Microsoft.Management.Configuration.UnitTests.Tests -{ - using System.IO; - using System.Runtime.InteropServices; - using Microsoft.Management.Configuration.UnitTests.Fixtures; - using Microsoft.Management.Configuration.UnitTests.Helpers; - using Microsoft.VisualBasic; - using Xunit; - using Xunit.Abstractions; - using Xunit.Sdk; - - /// <summary> - /// Unit tests for getting details on processors. - /// </summary> - [Collection("UnitTestCollection")] - [OutOfProc] - public class ProcessorGetTests : ConfigurationProcessorTestBase - { - /// <summary> - /// Initializes a new instance of the <see cref="ProcessorGetTests"/> class. - /// </summary> - /// <param name="fixture">Unit test fixture.</param> - /// <param name="log">Log helper.</param> - public ProcessorGetTests(UnitTestFixture fixture, ITestOutputHelper log) - : base(fixture, log) - { - } - - /// <summary> - /// Getting unit details throws an error. - /// </summary> - [Fact] - public void GetUnitDetailsError() - { - ConfigurationUnit configurationUnitThrows = this.ConfigurationUnit(); - - TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); - factory.NullProcessor = new TestConfigurationSetProcessor(null); - var thrownException = new FileNotFoundException(); - factory.NullProcessor.Exceptions.Add(configurationUnitThrows, thrownException); - - ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); - - GetConfigurationUnitDetailsResult result = processor.GetUnitDetails(configurationUnitThrows, ConfigurationUnitDetailFlags.Local); - - Assert.Null(result.Details); - Assert.Equal(configurationUnitThrows, result.Unit); - Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult); - Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource); - } - - /// <summary> - /// Getting unit details retrieves a value. - /// </summary> - [Fact] - public void GetUnitDetailsSuccess() - { - ConfigurationUnit configurationUnit = this.ConfigurationUnit(); - TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); - - ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); - - Assert.Null(configurationUnit.Details); - processor.GetUnitDetails(configurationUnit, ConfigurationUnitDetailFlags.Local); - Assert.NotNull(configurationUnit.Details); - } - - /// <summary> - /// Getting set details throws an error. - /// </summary> - [Fact] - public void GetSetDetailsError() - { - ConfigurationSet configurationSet = this.ConfigurationSet(); - ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit(); - ConfigurationUnit configurationUnitThrows = this.ConfigurationUnit(); - configurationSet.Units = new ConfigurationUnit[] { configurationUnitWorks, configurationUnitThrows }; - - TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); - TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); - var thrownException = new InvalidDataException(); - setProcessor.Exceptions.Add(configurationUnitThrows, thrownException); - - ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); - - GetConfigurationSetDetailsResult result = processor.GetSetDetails(configurationSet, ConfigurationUnitDetailFlags.Local); - var unitResults = result.UnitResults; - Assert.Equal(2, unitResults.Count); - - Assert.Equal(configurationUnitWorks, unitResults[0].Unit); - Assert.Null(unitResults[0].ResultInformation.ResultCode); - Assert.NotNull(configurationUnitWorks.Details); - - Assert.Equal(configurationUnitThrows, unitResults[1].Unit); - Assert.NotNull(unitResults[1].ResultInformation.ResultCode); - Assert.Equal(thrownException.HResult, unitResults[1].ResultInformation.ResultCode.HResult); - Assert.Null(configurationUnitThrows.Details); - } - - /// <summary> - /// Getting set details retrieves all values. - /// </summary> - [Fact] - public void GetSetDetailsSuccess() - { - ConfigurationSet configurationSet = this.ConfigurationSet(); - ConfigurationUnit configurationUnit1 = this.ConfigurationUnit(); - ConfigurationUnit configurationUnit2 = this.ConfigurationUnit(); - configurationSet.Units = new ConfigurationUnit[] { configurationUnit1, configurationUnit2 }; - - TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); - - ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); - - processor.GetSetDetails(configurationSet, ConfigurationUnitDetailFlags.Local); - Assert.NotNull(configurationUnit1.Details); - Assert.NotNull(configurationUnit2.Details); - } - - /// <summary> - /// The unit settings processor returns an error HRESULT. - /// </summary> - [Fact] - public void GetSettings_ProcessorSettingsError() - { - ConfigurationUnit configurationUnit = this.ConfigurationUnit(); - - TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); - factory.NullProcessor = new TestConfigurationSetProcessor(null); - TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); - unitProcessor.GetSettingsDelegate = () => throw new FileNotFoundException(); - - ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); - - GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); - - Assert.NotNull(result); - Assert.NotNull(result.Settings); - Assert.NotNull(result.ResultInformation); - Assert.NotNull(result.ResultInformation.ResultCode); - Assert.IsType<FileNotFoundException>(result.ResultInformation.ResultCode); - } - - /// <summary> - /// The unit settings processor returns an error in it's result. - /// </summary> - [Fact] - public void GetSettings_ProcessorSettingsFailedResult() - { - ConfigurationUnit configurationUnit = this.ConfigurationUnit(); - - TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); - factory.NullProcessor = new TestConfigurationSetProcessor(null); - TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); - GetSettingsResultInstance getSettingsResult = new GetSettingsResultInstance(configurationUnit); - getSettingsResult.InternalResult.ResultCode = new InvalidDataException(); - getSettingsResult.InternalResult.Description = "We fail because we must"; - unitProcessor.GetSettingsDelegate = () => getSettingsResult; - - ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); - - GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); - - Assert.NotNull(result); - Assert.Null(result.Settings); - Assert.NotNull(result.ResultInformation); - Assert.Equal(getSettingsResult.ResultInformation.ResultCode.HResult, result.ResultInformation.ResultCode.HResult); - Assert.Equal(getSettingsResult.ResultInformation.Description, result.ResultInformation.Description); - } - - /// <summary> - /// The unit settings processor returns good settings. - /// </summary> - [Fact] - public void GetSettings_ProcessorSettingsSuccess() - { - ConfigurationUnit configurationUnit = this.ConfigurationUnit(); - - TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); - factory.NullProcessor = new TestConfigurationSetProcessor(null); - TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); - GetSettingsResultInstance getSettingsResult = new GetSettingsResultInstance(configurationUnit); - getSettingsResult.Settings = new Windows.Foundation.Collections.ValueSet(); - getSettingsResult.Settings.Add("key", "value"); - unitProcessor.GetSettingsDelegate = () => getSettingsResult; - - ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); - - GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); - - Assert.NotNull(result); - Assert.NotNull(result.ResultInformation); - Assert.Null(result.ResultInformation.ResultCode); - Assert.Empty(result.ResultInformation.Description); - Assert.NotNull(result.Settings); - Assert.NotEmpty(result.Settings); - Assert.Contains("key", result.Settings); - Assert.IsType<string>(result.Settings["key"]); - Assert.Equal("value", (string)result.Settings["key"]); - } - } -} diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp @@ -13,6 +13,7 @@ #include "TestConfigurationUnitResult.h" #include "ConfigurationUnitResultInformation.h" #include "GetConfigurationUnitSettingsResult.h" +#include "GetAllConfigurationUnitSettingsResult.h" #include "ExceptionResultHelpers.h" #include "ConfigurationSetChangeData.h" #include "GetConfigurationUnitDetailsResult.h" @@ -633,6 +634,78 @@ namespace winrt::Microsoft::Management::Configuration::implementation return *result; } + Configuration::GetAllConfigurationUnitSettingsResult ConfigurationProcessor::GetAllUnitSettings(const ConfigurationUnit& unit) + { + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + return GetAllUnitSettingsImpl(unit); + } + + Windows::Foundation::IAsyncOperation<Configuration::GetAllConfigurationUnitSettingsResult> ConfigurationProcessor::GetAllUnitSettingsAsync(const ConfigurationUnit& unit) + { + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + + auto strong_this{ get_strong() }; + ConfigurationUnit localUnit = unit; + + co_await winrt::resume_background(); + + co_return GetAllUnitSettingsImpl(localUnit, { co_await winrt::get_cancellation_token() }); + } + + Configuration::GetAllConfigurationUnitSettingsResult ConfigurationProcessor::GetAllUnitSettingsImpl( + const ConfigurationUnit& unit, + AppInstaller::WinRT::AsyncCancellation cancellation) + { + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); + auto result = make_self<wil::details::module_count_wrapper<implementation::GetAllConfigurationUnitSettingsResult>>(); + auto unitResult = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>(); + result->ResultInformation(*unitResult); + + cancellation.ThrowIfCancelled(); + + IConfigurationUnitProcessor unitProcessor; + + try + { + // TODO: Directives overlay to prevent running elevated for test + unitProcessor = setProcessor.CreateUnitProcessor(unit); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult); + } + + cancellation.ThrowIfCancelled(); + + IGetAllSettingsConfigurationUnitProcessor getAllSettingsUnitProcessor; + if (unitProcessor.try_as<IGetAllSettingsConfigurationUnitProcessor>(getAllSettingsUnitProcessor)) + { + cancellation.ThrowIfCancelled(); + + try + { + IGetAllSettingsResult allSettingsResult = getAllSettingsUnitProcessor.GetAllSettings(); + result->Settings(allSettingsResult.Settings()); + result->ResultInformation(allSettingsResult.ResultInformation()); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult); + } + + m_threadGlobals.GetTelemetryLogger().LogConfigUnitRunIfAppropriate(GUID_NULL, unit, ConfigurationUnitIntent::Inform, TelemetryTraceLogger::ExportAction, result->ResultInformation()); + } + else + { + AICLI_LOG(Config, Error, << "Unit Processor does not support GetAllSettings operation"); + unitResult->Initialize(WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR, hstring{}); + } + + return *result; + } + HRESULT STDMETHODCALLTYPE ConfigurationProcessor::SetLifetimeWatcher(IUnknown* watcher) { return AppInstaller::WinRT::LifetimeWatcherBase::SetLifetimeWatcher(watcher); diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h @@ -24,6 +24,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation using TestConfigurationSetResult = Configuration::TestConfigurationSetResult; using TestConfigurationUnitResult = Configuration::TestConfigurationUnitResult; using GetConfigurationUnitSettingsResult = Configuration::GetConfigurationUnitSettingsResult; + using GetAllConfigurationUnitSettingsResult = Configuration::GetAllConfigurationUnitSettingsResult; using GetConfigurationSetDetailsResult = Configuration::GetConfigurationSetDetailsResult; using GetConfigurationUnitDetailsResult = Configuration::GetConfigurationUnitDetailsResult; @@ -79,6 +80,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation GetConfigurationUnitSettingsResult GetUnitSettings(const ConfigurationUnit& unit); Windows::Foundation::IAsyncOperation<GetConfigurationUnitSettingsResult> GetUnitSettingsAsync(const ConfigurationUnit& unit); + GetAllConfigurationUnitSettingsResult GetAllUnitSettings(const ConfigurationUnit& unit); + Windows::Foundation::IAsyncOperation<GetAllConfigurationUnitSettingsResult> GetAllUnitSettingsAsync(const ConfigurationUnit& unit); + HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(IUnknown* watcher); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) @@ -112,6 +116,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation GetConfigurationUnitSettingsResult GetUnitSettingsImpl(const ConfigurationUnit& unit, AppInstaller::WinRT::AsyncCancellation cancellation = {}); + GetAllConfigurationUnitSettingsResult GetAllUnitSettingsImpl(const ConfigurationUnit& unit, AppInstaller::WinRT::AsyncCancellation cancellation = {}); + void SendDiagnosticsImpl(const IDiagnosticInformation& information); IConfigurationSetProcessorFactory m_factory = nullptr; diff --git a/src/Microsoft.Management.Configuration/GetAllConfigurationUnitSettingsResult.cpp b/src/Microsoft.Management.Configuration/GetAllConfigurationUnitSettingsResult.cpp @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "GetAllConfigurationUnitSettingsResult.h" +#include "ConfigurationUnitResultInformation.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + GetAllConfigurationUnitSettingsResult::GetAllConfigurationUnitSettingsResult() : + m_resultInformation(*make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>()) + { + } + + void GetAllConfigurationUnitSettingsResult::ResultInformation(const IConfigurationUnitResultInformation& resultInformation) + { + m_resultInformation = resultInformation; + } + + IConfigurationUnitResultInformation GetAllConfigurationUnitSettingsResult::ResultInformation() const + { + return m_resultInformation; + } + + Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet> GetAllConfigurationUnitSettingsResult::Settings() + { + return m_settings; + } + + void GetAllConfigurationUnitSettingsResult::Settings(Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet>&& value) + { + m_settings = std::move(value); + } +} diff --git a/src/Microsoft.Management.Configuration/GetAllConfigurationUnitSettingsResult.h b/src/Microsoft.Management.Configuration/GetAllConfigurationUnitSettingsResult.h @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "GetAllConfigurationUnitSettingsResult.g.h" +#include <winrt/Windows.Foundation.Collections.h> + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct GetAllConfigurationUnitSettingsResult : GetAllConfigurationUnitSettingsResultT<GetAllConfigurationUnitSettingsResult> + { + GetAllConfigurationUnitSettingsResult(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void ResultInformation(const IConfigurationUnitResultInformation& resultInformation); + void Settings(Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet>&& value); +#endif + + IConfigurationUnitResultInformation ResultInformation() const; + Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet> Settings(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + IConfigurationUnitResultInformation m_resultInformation; + Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet> m_settings; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -268,7 +268,7 @@ namespace Microsoft.Management.Configuration // The change event was for the unit state. All ConfigurationSetChangeData properties are valid. UnitStateChanged, }; - + // The change data sent about changes to a specific set. [contract(Microsoft.Management.Configuration.Contract, 1)] runtimeclass ConfigurationSetChangeData @@ -455,6 +455,21 @@ namespace Microsoft.Management.Configuration IConfigurationUnitResultInformation ResultInformation{ get; }; } + // The result of getting the settings for all instances of a configuration unit. + [contract(Microsoft.Management.Configuration.Contract, 2)] + interface IGetAllSettingsResult + { + // The configuration unit. + ConfigurationUnit Unit{ get; }; + + // The current state of the system for all the instances of the configuration unit. + Windows.Foundation.Collections.IVector<Windows.Foundation.Collections.ValueSet> Settings{ get; }; + + // The result of getting the configuration unit settings. + // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings. + IConfigurationUnitResultInformation ResultInformation{ get; }; + } + // Provides access to a specific configuration unit within the runtime. [contract(Microsoft.Management.Configuration.Contract, 1)] interface IConfigurationUnitProcessor @@ -472,6 +487,13 @@ namespace Microsoft.Management.Configuration IApplySettingsResult ApplySettings(); } + [contract(Microsoft.Management.Configuration.Contract, 2)] + interface IGetAllSettingsConfigurationUnitProcessor requires IConfigurationUnitProcessor + { + // Gets the current system state for all the instances of the configuration unit, each of which has their own settings. + IGetAllSettingsResult GetAllSettings(); + } + // Controls the lifetime of operations for a single configuration set. [contract(Microsoft.Management.Configuration.Contract, 1)] interface IConfigurationSetProcessor @@ -728,6 +750,18 @@ namespace Microsoft.Management.Configuration Windows.Foundation.Collections.ValueSet Settings { get; }; } + // The result of getting the settings for all the instances of a configuration unit. + [contract(Microsoft.Management.Configuration.Contract, 2)] + runtimeclass GetAllConfigurationUnitSettingsResult + { + // The result of getting the settings for all the instances of the configuration unit. + // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings. + IConfigurationUnitResultInformation ResultInformation{ get; }; + + // The current state of the system for all the instances of the configuration unit. + Windows.Foundation.Collections.IVector<Windows.Foundation.Collections.ValueSet> Settings { get; }; + } + // The configuration processor is responsible for the interactions with the system. [contract(Microsoft.Management.Configuration.Contract, 1)] runtimeclass ConfigurationProcessor @@ -784,6 +818,13 @@ namespace Microsoft.Management.Configuration // Gets the current configuration unit settings. GetConfigurationUnitSettingsResult GetUnitSettings(ConfigurationUnit unit); Windows.Foundation.IAsyncOperation<GetConfigurationUnitSettingsResult> GetUnitSettingsAsync(ConfigurationUnit unit); + + [contract(Microsoft.Management.Configuration.Contract, 2)] + { + // Gets the current settings for all the instances of a configuration unit. + GetAllConfigurationUnitSettingsResult GetAllUnitSettings(ConfigurationUnit unit); + Windows.Foundation.IAsyncOperation<GetAllConfigurationUnitSettingsResult> GetAllUnitSettingsAsync(ConfigurationUnit unit); + } } // Top level entry point for configuration, enabling easier usage in out-of-process scenarios. diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -214,6 +214,7 @@ <ClInclude Include="ConfigurationUnitResultInformation.h" /> <ClInclude Include="DiagnosticInformationInstance.h" /> <ClInclude Include="ExceptionResultHelpers.h" /> + <ClInclude Include="GetAllConfigurationUnitSettingsResult.h" /> <ClInclude Include="GetConfigurationSetDetailsResult.h" /> <ClInclude Include="GetConfigurationUnitDetailsResult.h" /> <ClInclude Include="GetConfigurationUnitSettingsResult.h" /> @@ -246,6 +247,7 @@ <ClCompile Include="ConfigurationUnit.cpp" /> <ClCompile Include="ConfigurationUnitResultInformation.cpp" /> <ClCompile Include="DiagnosticInformationInstance.cpp" /> + <ClCompile Include="GetAllConfigurationUnitSettingsResult.cpp" /> <ClCompile Include="GetConfigurationSetDetailsResult.cpp" /> <ClCompile Include="GetConfigurationUnitDetailsResult.cpp" /> <ClCompile Include="GetConfigurationUnitSettingsResult.cpp" /> diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters @@ -78,6 +78,9 @@ <ClCompile Include="DiagnosticInformationInstance.cpp"> <Filter>Internals</Filter> </ClCompile> + <ClCompile Include="GetAllConfigurationUnitSettingsResult.cpp"> + <Filter>API Source</Filter> + </ClCompile> <ClCompile Include="ConfigurationParameter.cpp"> <Filter>API Source</Filter> </ClCompile> @@ -171,6 +174,9 @@ <ClInclude Include="DiagnosticInformationInstance.h"> <Filter>Internals</Filter> </ClInclude> + <ClInclude Include="GetAllConfigurationUnitSettingsResult.h"> + <Filter>API Headers</Filter> + </ClInclude> <ClInclude Include="ConfigurationParameter.h"> <Filter>API Headers</Filter> </ClInclude> diff --git a/src/Microsoft.Management.Configuration/Telemetry/Telemetry.h b/src/Microsoft.Management.Configuration/Telemetry/Telemetry.h @@ -49,6 +49,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation static constexpr std::string_view GetAction = "get"; static constexpr std::string_view ApplyAction = "apply"; static constexpr std::string_view TestAction = "test"; + static constexpr std::string_view ExportAction = "export"; // Logs information about running a configuration unit. // The caller is expected to only call this for failures from publicly available units.