diff --git a/doc/admx/DesktopAppInstaller.admx b/doc/admx/DesktopAppInstaller.admx index c692c37061..e248c375be 100644 --- a/doc/admx/DesktopAppInstaller.admx +++ b/doc/admx/DesktopAppInstaller.admx @@ -43,6 +43,16 @@ + + + + + + + + + + diff --git a/doc/admx/en-US/DesktopAppInstaller.adml b/doc/admx/en-US/DesktopAppInstaller.adml index 746b678784..cb4191a723 100644 --- a/doc/admx/en-US/DesktopAppInstaller.adml +++ b/doc/admx/en-US/DesktopAppInstaller.adml @@ -25,6 +25,12 @@ If you disable this setting, users will not be able to change settings for the W If you enable or do not configure this setting, users will be able to enable experimental features for the Windows Package Manager. If you disable this setting, users will not be able to enable experimental features for the Windows Package Manager. + Enable Windows Package Manager Feature Experimentation + This policy controls whether a user will be the recipient of feature experimentation while using the Windows Package Manager. + +If you enable, or do not configure this setting, user may receive experiences intended to analyze features and functionality experiences in the Windows Package Manager. + +If you disable this setting, user will be excluded from receiving any modified experience in the Windows Package Manager. Enable Windows Package Manager Local Manifest Files This policy controls whether users can install packages with local manifest files. diff --git a/schemas/JSON/settings/settings.schema.0.2.json b/schemas/JSON/settings/settings.schema.0.2.json index f2638f417f..8eb9b69a22 100644 --- a/schemas/JSON/settings/settings.schema.0.2.json +++ b/schemas/JSON/settings/settings.schema.0.2.json @@ -305,6 +305,22 @@ "default": false } } + }, + "Experimentation": { + "description": "Feature Experimentation", + "type": "object", + "properties": { + "CDN": { + "description": "Enables the use of an alternative CDN for the winget source", + "type": "boolean", + "default": false + } + } + }, + "AllowExperimentation": { + "description": "Controls whether feature experimentation is allowed or not", + "type": "boolean", + "default": true } }, "allOf": [ @@ -379,6 +395,18 @@ "experimentalFeatures": { "$ref": "#/definitions/Experimental" } }, "additionalItems": true + }, + { + "properties": { + "experimentation": { "$ref": "#/definitions/Experimentation" } + }, + "additionalItems": true + }, + { + "properties": { + "allowExperimentation": { "$ref": "#/definitions/AllowExperimentation" } + }, + "additionalItems": true } ], "additionalProperties": true diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index 3c78e96464..9f4b2d95e8 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -212,6 +212,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deploy {2B00D362-AC92-41F3-A8D2-5B1599BDCA01} = {2B00D362-AC92-41F3-A8D2-5B1599BDCA01} EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{800529ED-3374-49C4-BAD1-9B27647E4359}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Experiment", "Experiment", "{13E55125-0ABF-4975-9B5B-DD6E5527D47F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Experiment", "Internal\Experiment\Experiment.vcxproj", "{98920AB6-27B0-4C0F-B336-FA49DE57A1BA}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Management.Deployment.CsWinRTProjection", "Microsoft.Management.Deployment.CsWinRTProjection\Microsoft.Management.Deployment.CsWinRTProjection.csproj", "{9406322E-6272-487E-902A-9953889719EA}" EndProject Global @@ -1245,6 +1251,36 @@ Global {0BA531C8-CF0C-405B-8221-0FE51BA529D1}.TestRelease|x64.Build.0 = Release|x64 {0BA531C8-CF0C-405B-8221-0FE51BA529D1}.TestRelease|x86.ActiveCfg = Release|Win32 {0BA531C8-CF0C-405B-8221-0FE51BA529D1}.TestRelease|x86.Build.0 = Release|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Debug|ARM64.Build.0 = Debug|ARM64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Debug|x64.ActiveCfg = Debug|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Debug|x64.Build.0 = Debug|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Debug|x86.ActiveCfg = Debug|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Debug|x86.Build.0 = Debug|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Fuzzing|ARM64.ActiveCfg = Fuzzing|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Fuzzing|ARM64.Build.0 = Fuzzing|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Release|ARM64.ActiveCfg = Release|ARM64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Release|ARM64.Build.0 = Release|ARM64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Release|x64.ActiveCfg = Release|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Release|x64.Build.0 = Release|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Release|x86.ActiveCfg = Release|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.Release|x86.Build.0 = Release|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.TestRelease|ARM64.Build.0 = Release|ARM64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.TestRelease|x64.ActiveCfg = Release|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.TestRelease|x64.Build.0 = Release|x64 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.TestRelease|x86.ActiveCfg = Release|Win32 + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA}.TestRelease|x86.Build.0 = Release|Win32 {9406322E-6272-487E-902A-9953889719EA}.Debug|ARM64.ActiveCfg = Debug|Any CPU {9406322E-6272-487E-902A-9953889719EA}.Debug|ARM64.Build.0 = Debug|Any CPU {9406322E-6272-487E-902A-9953889719EA}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -1301,6 +1337,8 @@ Global {5A52D9FC-0059-4A4A-8196-427A7AA0D1C5} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9} {1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4} = {60618CAC-2995-4DF9-9914-45C6FC02C995} {76B26B2C-602A-4AD0-9736-4162D3FCA92A} = {1A5D7A7D-5CB2-47D5-B40D-4E61CAEDC798} + {13E55125-0ABF-4975-9B5B-DD6E5527D47F} = {800529ED-3374-49C4-BAD1-9B27647E4359} + {98920AB6-27B0-4C0F-B336-FA49DE57A1BA} = {13E55125-0ABF-4975-9B5B-DD6E5527D47F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B6FDB70C-A751-422C-ACD1-E35419495857} diff --git a/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj b/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj index f78059aafb..f83c9099fe 100644 --- a/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj +++ b/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj @@ -223,9 +223,9 @@ Disabled _DEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true true @@ -249,7 +249,7 @@ WIN32;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true true @@ -265,10 +265,10 @@ true true NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true true @@ -302,10 +302,10 @@ true true NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true true diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw index 2f870d9078..e8b955b95f 100644 --- a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw +++ b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -897,6 +897,9 @@ They can be configured through the settings file 'winget settings'. Enable Windows App Installer Experimental Features + + Enable Windows Package Manager Feature Experimentation + Enable Windows App Installer Microsoft Store Source diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj index 5bf26983b7..1814be7419 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj @@ -167,8 +167,8 @@ Disabled _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;_DEBUG;%(PreprocessorDefinitions) - $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true false @@ -192,7 +192,7 @@ _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;WIN32;%(PreprocessorDefinitions) - $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true false @@ -212,9 +212,9 @@ true true _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions) - $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true true @@ -279,6 +279,7 @@ + diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters index 5895890272..e74ab6a33a 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters @@ -374,6 +374,9 @@ Source Files\Common + + Source Files\Common + diff --git a/src/AppInstallerCLITests/Experiment.cpp b/src/AppInstallerCLITests/Experiment.cpp new file mode 100644 index 0000000000..898614bcdf --- /dev/null +++ b/src/AppInstallerCLITests/Experiment.cpp @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "TestCommon.h" +#include "TestSettings.h" +#include +#include + +using namespace TestCommon; +using namespace AppInstaller::Settings; +using namespace AppInstaller::Experiment; + +#define ASSERT_EXPERIMENT(_isEnabled_, _toggleSource_) \ + auto testExperimentState = Experiment::GetState(ExperimentKey::TestExperiment); \ + REQUIRE(_isEnabled_ == testExperimentState.IsEnabled()); \ + REQUIRE(_toggleSource_ == testExperimentState.ToggleSource()); + +const std::string s_TestExperimentName = "TestExperiment"; + +TEST_CASE("Experiment_GroupPolicyControl", "[experiment]") +{ + SECTION("Not configured") + { + ExperimentationTest experimentation; + GroupPolicyTestOverride policies; + policies.SetState(TogglePolicy::Policy::Experimentation, PolicyState::NotConfigured); + ASSERT_EXPERIMENT(true, ExperimentToggleSource::Default); + } + + SECTION("Enabled") + { + ExperimentationTest experimentation; + GroupPolicyTestOverride policies; + policies.SetState(TogglePolicy::Policy::Experimentation, PolicyState::Enabled); + ASSERT_EXPERIMENT(true, ExperimentToggleSource::Default); + } + + SECTION("Disabled") + { + ExperimentationTest experimentation; + GroupPolicyTestOverride policies; + policies.SetState(TogglePolicy::Policy::Experimentation, PolicyState::Disabled); + ASSERT_EXPERIMENT(false, ExperimentToggleSource::Policy); + } +} + +TEST_CASE("Experiment_GroupPolicyDisabled_ReturnFalse", "[experiment]") +{ + ExperimentationTest experimentation; + TestUserSettings settings; + settings.Set({{s_TestExperimentName, true}}); + + // If the policy is disabled, then also the user settings should be ignored. + GroupPolicyTestOverride policies; + policies.SetState(TogglePolicy::Policy::Experimentation, PolicyState::Disabled); + ASSERT_EXPERIMENT(false, ExperimentToggleSource::Policy); +} + +TEST_CASE("Experiment_GroupPolicyEnabled", "[experiment]") +{ + SECTION("Global experimentation disabled in user settings") + { + GroupPolicyTestOverride policies; + policies.SetState(TogglePolicy::Policy::Experimentation, PolicyState::Enabled); + ExperimentationTest experimentation; + TestUserSettings settings; + settings.Set(false); + settings.Set({{s_TestExperimentName, true}}); + ASSERT_EXPERIMENT(false, ExperimentToggleSource::UserSettingGlobalControl); + } + + SECTION("Individual experiment disabled in user settings") + { + GroupPolicyTestOverride policies; + policies.SetState(TogglePolicy::Policy::Experimentation, PolicyState::Enabled); + ExperimentationTest experimentation; + TestUserSettings settings; + settings.Set(true); + settings.Set({{s_TestExperimentName, false}}); + ASSERT_EXPERIMENT(false, ExperimentToggleSource::UserSettingIndividualControl); + } +} + +TEST_CASE("Experiment_UserSettingsIndividualControl", "[experiment]") +{ + SECTION("Individual experiment not configured in user settings") + { + // Default value are used + ExperimentationTest experimentation; + ASSERT_EXPERIMENT(true, ExperimentToggleSource::Default); + } + + SECTION("Individual experiment enabled in user settings") + { + ExperimentationTest experimentation; + TestUserSettings settings; + settings.Set({{s_TestExperimentName, true}}); + ASSERT_EXPERIMENT(true, ExperimentToggleSource::UserSettingIndividualControl); + } + + SECTION("Individual experiment disabled in user settings") + { + ExperimentationTest experimentation; + TestUserSettings settings; + settings.Set({{s_TestExperimentName, false}}); + ASSERT_EXPERIMENT(false, ExperimentToggleSource::UserSettingIndividualControl); + } +} + +TEST_CASE("Experiment_UserSettingsGlobalControl", "[experiment]") +{ + SECTION("Global experimentation not configured in user settings") + { + ExperimentationTest experimentation; + TestUserSettings settings; + settings.Set({{s_TestExperimentName, true}}); + ASSERT_EXPERIMENT(true, ExperimentToggleSource::UserSettingIndividualControl); + } + + SECTION("Global experimentation enabled in user settings") + { + ExperimentationTest experimentation; + TestUserSettings settings; + settings.Set(true); + settings.Set({{s_TestExperimentName, true}}); + ASSERT_EXPERIMENT(true, ExperimentToggleSource::UserSettingIndividualControl); + } + + SECTION("Global experimentation disabled in user settings") + { + ExperimentationTest experimentation; + TestUserSettings settings; + settings.Set(false); + settings.Set({{s_TestExperimentName, true}}); + ASSERT_EXPERIMENT(false, ExperimentToggleSource::UserSettingGlobalControl); + } +} diff --git a/src/AppInstallerCLITests/GroupPolicy.cpp b/src/AppInstallerCLITests/GroupPolicy.cpp index 907c55969e..0e9c13fef1 100644 --- a/src/AppInstallerCLITests/GroupPolicy.cpp +++ b/src/AppInstallerCLITests/GroupPolicy.cpp @@ -402,6 +402,7 @@ TEST_CASE("GroupPolicy_AllEnabled", "[groupPolicy]") SetRegistryValue(policiesKey.get(), EnableWindowsPackageManagerCommandLineInterfaces, 1); SetRegistryValue(policiesKey.get(), ConfigurationPolicyValueName, 1); SetRegistryValue(policiesKey.get(), ProxyCommandLineOptionsPolicyValueName, 1); + SetRegistryValue(policiesKey.get(), EnableExperimentationPolicyValueName , 1); GroupPolicy groupPolicy{ policiesKey.get() }; for (const auto& policy : TogglePolicy::GetAllPolicies()) diff --git a/src/AppInstallerCLITests/TestSettings.cpp b/src/AppInstallerCLITests/TestSettings.cpp index 20613c93fa..9fc5a026db 100644 --- a/src/AppInstallerCLITests/TestSettings.cpp +++ b/src/AppInstallerCLITests/TestSettings.cpp @@ -4,6 +4,7 @@ #include "TestCommon.h" #include "TestSettings.h" #include +#include using namespace AppInstaller::Settings; @@ -71,4 +72,9 @@ namespace TestCommon { m_toggles[policy] = state; } -} \ No newline at end of file + + ExperimentationTest::~ExperimentationTest() + { + AppInstaller::Logging::Telemetry().ResetExperimentCache(); + } +} diff --git a/src/AppInstallerCLITests/TestSettings.h b/src/AppInstallerCLITests/TestSettings.h index 7da1a728ef..26f64fa045 100644 --- a/src/AppInstallerCLITests/TestSettings.h +++ b/src/AppInstallerCLITests/TestSettings.h @@ -3,6 +3,7 @@ #pragma once #include #include +#include #include #include @@ -23,6 +24,7 @@ namespace TestCommon const std::wstring EnableWindowsPackageManagerCommandLineInterfaces = L"EnableWindowsPackageManagerCommandLineInterfaces"; const std::wstring ConfigurationPolicyValueName = L"EnableWindowsPackageManagerConfiguration"; const std::wstring ProxyCommandLineOptionsPolicyValueName = L"EnableWindowsPackageManagerProxyCommandLineOptions"; + const std::wstring EnableExperimentationPolicyValueName = L"EnableExperimentation"; const std::wstring SourceUpdateIntervalPolicyValueName = L"SourceAutoUpdateInterval"; const std::wstring SourceUpdateIntervalPolicyOldValueName = L"SourceAutoUpdateIntervalInMinutes"; @@ -47,6 +49,11 @@ namespace TestCommon { }; + struct ExperimentationTest + { + ~ExperimentationTest(); + }; + struct GroupPolicyTestOverride : AppInstaller::Settings::GroupPolicy { GroupPolicyTestOverride() : GroupPolicyTestOverride(RegCreateVolatileTestRoot().get()) {} @@ -90,4 +97,4 @@ namespace TestCommon }; #define REQUIRE_POLICY_EXCEPTION(_expr_, _policy_) REQUIRE_THROWS_MATCHES(_expr_, AppInstaller::Settings::GroupPolicyException, TestCommon::GroupPolicyExceptionMatcher(_policy_)) -} \ No newline at end of file +} diff --git a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj index bfaf4d6669..e1f7c73c03 100644 --- a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj +++ b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj @@ -252,9 +252,9 @@ Disabled _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;_DEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) true true true @@ -278,7 +278,7 @@ _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;WIN32;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) true true true @@ -294,10 +294,10 @@ true true _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) true true true @@ -331,10 +331,10 @@ true true _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories) true true true @@ -372,7 +372,7 @@ true true _NO_ASYNCRTIMP;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD;WINGET_DISABLE_FOR_FUZZING;_DISABLE_VECTOR_ANNOTATION;_DISABLE_STRING_ANNOTATION - $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\AppInstallerSharedLib;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\binver;$(ProjectDir)..\YamlCppLib\libyaml\include;$(ProjectDir)..\Internal;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\PureLib\pure;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) true stdcpp17 MultiThreaded @@ -426,6 +426,7 @@ + @@ -473,6 +474,7 @@ + @@ -540,6 +542,9 @@ {f3f6e699-bc5d-4950-8a05-e49dd9eb0d51} + + {98920ab6-27b0-4c0f-b336-fa49de57a1ba} + diff --git a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters index 2c5d80bc70..3eb875dff9 100644 --- a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters +++ b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters @@ -207,6 +207,9 @@ Public\winget + + Public\winget + Public\winget @@ -377,6 +380,9 @@ Source Files + + Source Files + Source Files diff --git a/src/AppInstallerCommonCore/AppInstallerTelemetry.cpp b/src/AppInstallerCommonCore/AppInstallerTelemetry.cpp index 589e35ebc7..aef59e401b 100644 --- a/src/AppInstallerCommonCore/AppInstallerTelemetry.cpp +++ b/src/AppInstallerCommonCore/AppInstallerTelemetry.cpp @@ -11,6 +11,7 @@ #define AICLI_TraceLoggingStringView(_sv_,_name_) TraceLoggingCountedUtf8String(_sv_.data(), static_cast(_sv_.size()), _name_) #define AICLI_TraceLoggingWStringView(_sv_,_name_) TraceLoggingCountedWideString(_sv_.data(), static_cast(_sv_.size()), _name_) +#define AICLI_TraceLoggingJsonWString(_sv_, _name_) TraceLoggingPackedFieldEx(_sv_.c_str(), static_cast((_sv_.size() + 1) * sizeof(wchar_t)), TlgInUNICODESTRING, TlgOutJSON, _name_) #define AICLI_TraceLoggingWriteActivity(_eventName_,...) TraceLoggingWriteActivity(\ g_hTraceProvider,\ @@ -18,12 +19,14 @@ _eventName_,\ s_useGlobalTelemetryActivityId ? &s_globalTelemetryLoggerActivityId : GetActivityId(),\ nullptr,\ TraceLoggingCountedUtf8String(m_caller.c_str(), static_cast(m_caller.size()), "Caller"),\ -TraceLoggingPackedFieldEx(m_telemetryCorrelationJsonW.c_str(), static_cast((m_telemetryCorrelationJsonW.size() + 1) * sizeof(wchar_t)), TlgInUNICODESTRING, TlgOutJSON, "CvJson"),\ +AICLI_TraceLoggingJsonWString(m_telemetryCorrelationJsonW, "CvJson"),\ __VA_ARGS__) namespace AppInstaller::Logging { using namespace Utility; + using namespace Settings; + using namespace Experiment; namespace { @@ -77,6 +80,19 @@ namespace AppInstaller::Logging return "unknown"sv; } } + + std::wstring GetExperimentationJson(const Settings:: ExperimentStateCache& experimentation) + { + Json::Value root; + for (const auto& experiment : experimentation) + { + auto name = std::string(Settings::Experiment::GetExperiment(experiment.first).JsonName()); + root[name] = experiment.second.ToJson(); + } + + Json::StreamWriterBuilder builder; + return Utility::ConvertToUTF16(Json::writeString(builder, root)); + } } TelemetrySummary::TelemetrySummary(const TelemetrySummary& other) @@ -760,6 +776,23 @@ namespace AppInstaller::Logging AICLI_LOG(CLI, Error, << type << " repair failed: " << errorCode); } + Settings::ExperimentState TelemetryTraceLogger::GetExperimentState(ExperimentKey key) + { + auto it = m_summary.ExperimentCache.find(key); + if (it == m_summary.ExperimentCache.end()) + { + it = m_summary.ExperimentCache.emplace(key, Settings::Experiment::GetStateInternal(key)).first; + } + return it->second; + } + +#ifndef AICLI_DISABLE_TEST_HOOKS + void TelemetryTraceLogger::ResetExperimentCache() + { + m_summary.ExperimentCache.clear(); + } +#endif + TelemetryTraceLogger::~TelemetryTraceLogger() { if (IsTelemetryEnabled()) @@ -773,6 +806,8 @@ namespace AppInstaller::Logging if (m_useSummary) { + auto experimentationJson = GetExperimentationJson(m_summary.ExperimentCache); + TraceLoggingWriteActivity( g_hTraceProvider, "SummaryV2", @@ -780,7 +815,7 @@ namespace AppInstaller::Logging GetParentActivityId(), // From member fields or program info. AICLI_TraceLoggingStringView(m_caller, "Caller"), - TraceLoggingPackedFieldEx(m_telemetryCorrelationJsonW.c_str(), static_cast((m_telemetryCorrelationJsonW.size() + 1) * sizeof(wchar_t)), TlgInUNICODESTRING, TlgOutJSON, "CvJson"), + AICLI_TraceLoggingJsonWString(m_telemetryCorrelationJsonW, "CvJson"), TraceLoggingCountedString(version->c_str(), static_cast(version->size()), "ClientVersion"), TraceLoggingCountedString(packageVersion->c_str(), static_cast(packageVersion->size()), "ClientPackageVersion"), TraceLoggingBool(Runtime::IsReleaseBuild(), "IsReleaseBuild"), @@ -838,6 +873,7 @@ namespace AppInstaller::Logging AICLI_TraceLoggingStringView(m_summary.RepairExecutionType, "RepairExecutionType"), TraceLoggingUInt32(m_summary.RepairErrorCode, "RepairErrorCode"), TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance | PDT_ProductAndServiceUsage | PDT_SoftwareSetupAndInventory), + AICLI_TraceLoggingJsonWString(experimentationJson, "ExperimentationJson"), TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } } diff --git a/src/AppInstallerCommonCore/Experiment.cpp b/src/AppInstallerCommonCore/Experiment.cpp new file mode 100644 index 0000000000..bb778d30e5 --- /dev/null +++ b/src/AppInstallerCommonCore/Experiment.cpp @@ -0,0 +1,116 @@ + +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "winget/Experiment.h" +#include "winget/UserSettings.h" +#include "Experiment/Experiment.h" +#include "AppInstallerTelemetry.h" + +namespace AppInstaller::Settings +{ + using namespace Experiment; + + namespace + { + ExperimentState GetExperimentStateInternal(ExperimentKey key, const UserSettings& userSettings) + { + if (key == ExperimentKey::None) + { + return { false, ExperimentToggleSource::Default }; + } + + auto experiment = Experiment::GetExperiment(key); + if (!GroupPolicies().IsEnabled(TogglePolicy::Policy::Experimentation)) + { + AICLI_LOG(Core, Verbose, << "Experiment " << experiment.Name() << + " is disabled due to group policy: " << TogglePolicy::GetPolicy(TogglePolicy::Policy::Experimentation).RegValueName()); + return { false, ExperimentToggleSource::Policy }; + } + + auto experimentJsonName = experiment.JsonName(); + if (!userSettings.Get()) + { + AICLI_LOG(Core, Verbose, << "Experiment " << experiment.Name() << + " is disabled due to experimentation not allowed from user settings"); + return { false, ExperimentToggleSource::UserSettingGlobalControl }; + } + + auto userSettingsExperimentation = userSettings.Get(); + auto userSettingsExperimentIter = userSettingsExperimentation.find(experimentJsonName); + if (userSettingsExperimentIter != userSettingsExperimentation.end()) + { + auto isEnabled = userSettingsExperimentIter->second; + AICLI_LOG(Core, Verbose, << "Experiment " << experiment.Name() << " is set to " << (isEnabled ? "true" : "false") << " in user settings"); + return { isEnabled, ExperimentToggleSource::UserSettingIndividualControl }; + } + + auto isEnabled = AppInstaller::Experiment::IsEnabled(experiment.GetKey()); + AICLI_LOG(Core, Verbose, << "Experiment " << experiment.Name() << " is set to " << (isEnabled ? "true" : "false")); + return { isEnabled, ExperimentToggleSource::Default }; + } + + std::string ExperimentToggleSourceToString(ExperimentToggleSource source) + { + switch (source) + { + case ExperimentToggleSource::Default: + return "Default"; + case ExperimentToggleSource::Policy: + return "Policy"; + case ExperimentToggleSource::UserSettingIndividualControl: + return "UserSettingIndividualControl"; + case ExperimentToggleSource::UserSettingGlobalControl: + return "UserSettingGlobalControl"; + default: + return "Unknown"; + } + } + } + + std::string ExperimentState::ToJson() const + { + Json::Value root; + root["IsEnabled"] = m_isEnabled; + root["ToggleSource"] = ExperimentToggleSourceToString(m_toggleSource); + Json::StreamWriterBuilder builder; + return Json::writeString(builder, root); + } + + ExperimentState Experiment::GetStateInternal(ExperimentKey key) + { + return GetExperimentStateInternal(key, User()); + } + + ExperimentState Experiment::GetState(ExperimentKey key) + { + return Logging::Telemetry().GetExperimentState(key); + } + + Experiment Experiment::GetExperiment(ExperimentKey key) + { + switch (key) + { + case ExperimentKey::CDN: + return Experiment{ "winget source CDN experiment", "CDN", "https://aka.ms/winget-settings", ExperimentKey::CDN}; +#ifndef AICLI_DISABLE_TEST_HOOKS + case ExperimentKey::TestExperiment: + return Experiment{ "Test experiment", "TestExperiment", "https://aka.ms/winget-settings", ExperimentKey::TestExperiment }; +#endif + default: + THROW_HR(E_UNEXPECTED); + } + } + + std::vector Experiment::GetExperimentation() + { + std::vector result; + + for (Key_t i = 0x1; i < static_cast(ExperimentKey::Max); ++i) + { + result.emplace_back(GetExperiment(static_cast(i))); + } + + return result; + } +} diff --git a/src/AppInstallerCommonCore/Public/AppInstallerTelemetry.h b/src/AppInstallerCommonCore/Public/AppInstallerTelemetry.h index 9d7452e0ff..404ee96402 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerTelemetry.h +++ b/src/AppInstallerCommonCore/Public/AppInstallerTelemetry.h @@ -3,6 +3,7 @@ #pragma once #include #include +#include #include #include @@ -11,6 +12,7 @@ namespace AppInstaller::Settings { struct UserSettings; + typedef std::map ExperimentStateCache; } namespace AppInstaller::Logging @@ -128,6 +130,8 @@ namespace AppInstaller::Logging // LogNonFatalDOError std::string DOUrl; HRESULT DOHResult = S_OK; + + Settings::ExperimentStateCache ExperimentCache; }; // This type contains the registration lifetime of the telemetry trace logging provider. @@ -267,6 +271,12 @@ namespace AppInstaller::Logging void LogNonFatalDOError(std::string_view url, HRESULT hr) const noexcept; + Settings::ExperimentState GetExperimentState(AppInstaller::Experiment::ExperimentKey key); + +#ifndef AICLI_DISABLE_TEST_HOOKS + void ResetExperimentCache(); +#endif + protected: bool IsTelemetryEnabled() const noexcept; diff --git a/src/AppInstallerCommonCore/Public/winget/Experiment.h b/src/AppInstallerCommonCore/Public/winget/Experiment.h new file mode 100644 index 0000000000..c394d03613 --- /dev/null +++ b/src/AppInstallerCommonCore/Public/winget/Experiment.h @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include +#include +#include "Experiment/Experiment.h" +#include "AppInstallerStrings.h" + +namespace AppInstaller::Settings +{ + enum ExperimentToggleSource + { + Default = 0, + Policy, + UserSettingIndividualControl, + UserSettingGlobalControl, + }; + + struct ExperimentState + { + ExperimentState() = default; + ExperimentState(bool isEnabled, ExperimentToggleSource toggleSource) : m_isEnabled(isEnabled), m_toggleSource(toggleSource) {} + + // Gets a value indicating whether the experiment is enabled. + // Note: This API expects an experiment to be disabled by default and will + // always return false if the user opts out of the experiment from the + // user settings or group policy. + bool IsEnabled() const { return m_isEnabled; } + ExperimentToggleSource ToggleSource() const { return m_toggleSource; } + std::string ToJson() const; + private: + ExperimentToggleSource m_toggleSource; + bool m_isEnabled; + }; + + struct Experiment + { + using Key_t = std::underlying_type_t; + + Experiment(std::string name, std::string jsonName, std::string link, AppInstaller::Experiment::ExperimentKey key) : + m_name(std::move(name)), m_jsonName(std::move(jsonName)), m_link(std::move(link)), m_key(std::move((key))) {} + + static ExperimentState GetState(AppInstaller::Experiment::ExperimentKey feature); + static ExperimentState GetStateInternal(AppInstaller::Experiment::ExperimentKey feature); + static Experiment GetExperiment(AppInstaller::Experiment::ExperimentKey key); + static std::vector GetExperimentation(); + + const std::string Name() const { return m_name; } + const std::string JsonName() const { return m_jsonName; } + const std::string Link() const { return m_link; } + const AppInstaller::Experiment::ExperimentKey GetKey() const { return m_key; } + + private: + std::string m_name; + std::string m_jsonName; + std::string m_link; + AppInstaller::Experiment::ExperimentKey m_key; + }; +} diff --git a/src/AppInstallerCommonCore/Public/winget/UserSettings.h b/src/AppInstallerCommonCore/Public/winget/UserSettings.h index d13d3e8f46..fa5495a989 100644 --- a/src/AppInstallerCommonCore/Public/winget/UserSettings.h +++ b/src/AppInstallerCommonCore/Public/winget/UserSettings.h @@ -112,6 +112,9 @@ namespace AppInstaller::Settings ConfigureDefaultModuleRoot, // Interactivity InteractivityDisable, + // Experimentation + Experimentation, + AllowExperimentation, #ifndef AICLI_DISABLE_TEST_HOOKS // Debug EnableSelfInitiatedMinidump, @@ -204,7 +207,12 @@ namespace AppInstaller::Settings SETTINGMAPPING_SPECIALIZATION(Setting::LoggingChannelPreference, std::vector, Logging::Channel, Logging::Channel::Defaults, ".logging.channels"sv); // Interactivity SETTINGMAPPING_SPECIALIZATION(Setting::InteractivityDisable, bool, bool, false, ".interactivity.disable"sv); - + + // Experimentation + using Experimentation_t = std::map; + SETTINGMAPPING_SPECIALIZATION(Setting::Experimentation, Experimentation_t, Experimentation_t, {}, ".experimentation"sv); + SETTINGMAPPING_SPECIALIZATION(Setting::AllowExperimentation, bool, bool, true, ".allowExperimentation"sv); + // Used to deduce the SettingVariant type; making a variant that includes std::monostate and all SettingMapping types. template inline auto Deduce(std::index_sequence) { return std::variant(I)>::value_t...>{}; } diff --git a/src/AppInstallerCommonCore/UserSettings.cpp b/src/AppInstallerCommonCore/UserSettings.cpp index d6879e9b9a..d701abedee 100644 --- a/src/AppInstallerCommonCore/UserSettings.cpp +++ b/src/AppInstallerCommonCore/UserSettings.cpp @@ -75,6 +75,32 @@ namespace AppInstaller::Settings return convertedValue; } + template<> + std::string GetValueString(std::map value) + { + std::stringstream convertedValue; + convertedValue << "{"; + + bool first = true; + for (auto const& entry : value) + { + if (first) + { + first = false; + } + else + { + convertedValue << ", "; + } + + convertedValue << "'" << entry.first << "' = " << entry.second; + } + + convertedValue << "}"; + + return convertedValue.str(); + } + std::optional ParseSettingsContent(const std::string& content, std::string_view settingName, std::vector& warnings) { Json::Value root; @@ -278,6 +304,8 @@ namespace AppInstaller::Settings WINGET_VALIDATE_PASS_THROUGH(UninstallPurgePortablePackage) WINGET_VALIDATE_PASS_THROUGH(NetworkWingetAlternateSourceURL) WINGET_VALIDATE_PASS_THROUGH(MaxResumes) + WINGET_VALIDATE_PASS_THROUGH(Experimentation) + WINGET_VALIDATE_PASS_THROUGH(AllowExperimentation) #ifndef AICLI_DISABLE_TEST_HOOKS WINGET_VALIDATE_PASS_THROUGH(EnableSelfInitiatedMinidump) diff --git a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj index d70fb30e56..43cd7411c5 100644 --- a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj +++ b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj @@ -222,9 +222,9 @@ Disabled _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;_DEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true true @@ -248,7 +248,7 @@ _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;WIN32;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true true @@ -264,10 +264,10 @@ true true _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true true @@ -301,10 +301,10 @@ true true _NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) true true true diff --git a/src/AppInstallerRepositoryCore/SourceList.cpp b/src/AppInstallerRepositoryCore/SourceList.cpp index 1eb0e8ba95..b7807463fa 100644 --- a/src/AppInstallerRepositoryCore/SourceList.cpp +++ b/src/AppInstallerRepositoryCore/SourceList.cpp @@ -8,10 +8,12 @@ #include #include +#include #include using namespace AppInstaller::Settings; using namespace std::string_view_literals; +using namespace AppInstaller::Experiment; namespace AppInstaller::Repository { @@ -36,6 +38,7 @@ namespace AppInstaller::Repository constexpr std::string_view s_Source_WingetCommunityDefault_Name = "winget"sv; constexpr std::string_view s_Source_WingetCommunityDefault_Arg = "https://cdn.winget.microsoft.com/cache"sv; + constexpr std::string_view s_Source_WingetCommunityExperimental_Arg = "https://cdn2.winget.microsoft.com/cache"sv; constexpr std::string_view s_Source_WingetCommunityDefault_Data = "Microsoft.Winget.Source_8wekyb3d8bbwe"sv; constexpr std::string_view s_Source_WingetCommunityDefault_Identifier = "Microsoft.Winget.Source_8wekyb3d8bbwe"sv; @@ -207,6 +210,16 @@ namespace AppInstaller::Repository { return details.IsTombstone || details.Origin == SourceOrigin::Metadata || !details.IsVisible; } + + std::string_view GetWingetCommunitySource() + { + if (Settings::Experiment::GetState(ExperimentKey::CDN).IsEnabled()) + { + return s_Source_WingetCommunityExperimental_Arg; + } + + return s_Source_WingetCommunityDefault_Arg; + } } void SourceDetailsInternal::CopyMetadataFieldsTo(SourceDetailsInternal& target) @@ -246,19 +259,18 @@ namespace AppInstaller::Repository return {}; } - std::string_view GetWellKnownSourceArg(WellKnownSource source) + bool IsWellKnownSourceArg(std::string_view arg, WellKnownSource source) { switch (source) { case WellKnownSource::WinGet: - return s_Source_WingetCommunityDefault_Arg; + return Utility::CaseInsensitiveEquals(arg, s_Source_WingetCommunityDefault_Arg) || Utility::CaseInsensitiveEquals(arg, s_Source_WingetCommunityExperimental_Arg); case WellKnownSource::MicrosoftStore: - return s_Source_MSStoreDefault_Arg; + return Utility::CaseInsensitiveEquals(arg, s_Source_MSStoreDefault_Arg); case WellKnownSource::DesktopFrameworks: - return s_Source_DesktopFrameworks_Arg; + return Utility::CaseInsensitiveEquals(arg, s_Source_DesktopFrameworks_Arg); } - - return {}; + return false; } std::string_view GetWellKnownSourceIdentifier(WellKnownSource source) @@ -278,17 +290,17 @@ namespace AppInstaller::Repository std::optional CheckForWellKnownSourceMatch(std::string_view name, std::string_view arg, std::string_view type) { - if (name == s_Source_WingetCommunityDefault_Name && arg == s_Source_WingetCommunityDefault_Arg && type == Microsoft::PreIndexedPackageSourceFactory::Type()) + if (name == s_Source_WingetCommunityDefault_Name && IsWellKnownSourceArg(arg, WellKnownSource::WinGet) && type == Microsoft::PreIndexedPackageSourceFactory::Type()) { return WellKnownSource::WinGet; } - if (name == s_Source_MSStoreDefault_Name && arg == s_Source_MSStoreDefault_Arg && type == Rest::RestSourceFactory::Type()) + if (name == s_Source_MSStoreDefault_Name && IsWellKnownSourceArg(arg, WellKnownSource::MicrosoftStore) && type == Rest::RestSourceFactory::Type()) { return WellKnownSource::MicrosoftStore; } - if (name == s_Source_DesktopFrameworks_Name && arg == s_Source_DesktopFrameworks_Arg && type == Microsoft::PreIndexedPackageSourceFactory::Type()) + if (name == s_Source_DesktopFrameworks_Name && IsWellKnownSourceArg(arg, WellKnownSource::DesktopFrameworks) && type == Microsoft::PreIndexedPackageSourceFactory::Type()) { return WellKnownSource::DesktopFrameworks; } @@ -306,7 +318,7 @@ namespace AppInstaller::Repository details.Origin = SourceOrigin::Default; details.Name = s_Source_WingetCommunityDefault_Name; details.Type = Microsoft::PreIndexedPackageSourceFactory::Type(); - details.Arg = s_Source_WingetCommunityDefault_Arg; + details.Arg = GetWingetCommunitySource(); details.Data = s_Source_WingetCommunityDefault_Data; details.Identifier = s_Source_WingetCommunityDefault_Identifier; details.TrustLevel = SourceTrustLevel::Trusted | SourceTrustLevel::StoreOrigin; diff --git a/src/AppInstallerRepositoryCore/SourceList.h b/src/AppInstallerRepositoryCore/SourceList.h index b8808be3c7..29e2dc48b8 100644 --- a/src/AppInstallerRepositoryCore/SourceList.h +++ b/src/AppInstallerRepositoryCore/SourceList.h @@ -8,8 +8,8 @@ namespace AppInstaller::Repository { // Built-in values for default sources + bool IsWellKnownSourceArg(std::string_view arg, WellKnownSource source); std::string_view GetWellKnownSourceName(WellKnownSource source); - std::string_view GetWellKnownSourceArg(WellKnownSource source); std::string_view GetWellKnownSourceIdentifier(WellKnownSource source); std::optional CheckForWellKnownSourceMatch(std::string_view name, std::string_view arg, std::string_view type); diff --git a/src/AppInstallerRepositoryCore/SourcePolicy.cpp b/src/AppInstallerRepositoryCore/SourcePolicy.cpp index 8df191947d..f3d59c9f02 100644 --- a/src/AppInstallerRepositoryCore/SourcePolicy.cpp +++ b/src/AppInstallerRepositoryCore/SourcePolicy.cpp @@ -110,14 +110,12 @@ namespace AppInstaller::Repository // - Check only against the source argument and type as the user source may have a different name. // - Do a case-insensitive check as the domain portion of the URL is case-insensitive, // and we don't need case sensitivity for the rest as we control the domain. - if (Utility::CaseInsensitiveEquals(arg, GetWellKnownSourceArg(WellKnownSource::WinGet)) && - Utility::CaseInsensitiveEquals(type, Microsoft::PreIndexedPackageSourceFactory::Type())) + if (IsWellKnownSourceArg(arg, WellKnownSource::WinGet) && Utility::CaseInsensitiveEquals(type, Microsoft::PreIndexedPackageSourceFactory::Type())) { return IsWellKnownSourceEnabled(WellKnownSource::WinGet) ? TogglePolicy::Policy::None : TogglePolicy::Policy::DefaultSource; } - if (Utility::CaseInsensitiveEquals(arg, GetWellKnownSourceArg(WellKnownSource::MicrosoftStore)) && - Utility::CaseInsensitiveEquals(type, Rest::RestSourceFactory::Type())) + if (IsWellKnownSourceArg(arg, WellKnownSource::MicrosoftStore) && Utility::CaseInsensitiveEquals(type, Rest::RestSourceFactory::Type())) { return IsWellKnownSourceEnabled(WellKnownSource::MicrosoftStore) ? TogglePolicy::Policy::None : TogglePolicy::Policy::MSStoreSource; } diff --git a/src/AppInstallerSharedLib/GroupPolicy.cpp b/src/AppInstallerSharedLib/GroupPolicy.cpp index 862c1ccce4..ca16c91a36 100644 --- a/src/AppInstallerSharedLib/GroupPolicy.cpp +++ b/src/AppInstallerSharedLib/GroupPolicy.cpp @@ -326,6 +326,8 @@ namespace AppInstaller::Settings return TogglePolicy(policy, "EnableWindowsPackageManagerConfiguration"sv, String::PolicyEnableWinGetConfiguration); case TogglePolicy::Policy::ProxyCommandLineOptions: return TogglePolicy(policy, "EnableWindowsPackageManagerProxyCommandLineOptions"sv, String::PolicyEnableProxyCommandLineOptions); + case TogglePolicy::Policy::Experimentation: + return TogglePolicy(policy, "EnableExperimentation"sv, String::PolicyEnableExperimentation); default: THROW_HR(E_UNEXPECTED); } diff --git a/src/AppInstallerSharedLib/JsonUtil.cpp b/src/AppInstallerSharedLib/JsonUtil.cpp index 00d598b9db..221eccba6d 100644 --- a/src/AppInstallerSharedLib/JsonUtil.cpp +++ b/src/AppInstallerSharedLib/JsonUtil.cpp @@ -67,6 +67,28 @@ namespace AppInstaller::JSON return std::nullopt; } + + template<> + std::optional> GetValue(const Json::Value& node) + { + std::map result; + + if (node.isObject()) + { + for (const auto& entry : node.getMemberNames()) + { + auto& value = node[entry]; + if (value.isBool()) + { + result[entry] = value.asBool(); + } + } + + return result; + } + + return std::nullopt; + } #ifndef WINGET_DISABLE_FOR_FUZZING utility::string_t GetUtilityString(std::string_view nodeName) diff --git a/src/AppInstallerSharedLib/Public/winget/GroupPolicy.h b/src/AppInstallerSharedLib/Public/winget/GroupPolicy.h index 850526f60c..2fa6e3fe4c 100644 --- a/src/AppInstallerSharedLib/Public/winget/GroupPolicy.h +++ b/src/AppInstallerSharedLib/Public/winget/GroupPolicy.h @@ -47,6 +47,7 @@ namespace AppInstaller::Settings WinGetCommandLineInterfaces, Configuration, ProxyCommandLineOptions, + Experimentation, Max, }; diff --git a/src/AppInstallerSharedLib/Public/winget/JsonUtil.h b/src/AppInstallerSharedLib/Public/winget/JsonUtil.h index f433417e18..559252c223 100644 --- a/src/AppInstallerSharedLib/Public/winget/JsonUtil.h +++ b/src/AppInstallerSharedLib/Public/winget/JsonUtil.h @@ -33,6 +33,9 @@ namespace AppInstaller::JSON template<> std::optional> GetValue>(const Json::Value& node); + + template<> + std::optional> GetValue>(const Json::Value& node); #ifndef WINGET_DISABLE_FOR_FUZZING // For cpprestsdk JSON diff --git a/src/AppInstallerSharedLib/Public/winget/Resources.h b/src/AppInstallerSharedLib/Public/winget/Resources.h index dc6591abd0..b252837580 100644 --- a/src/AppInstallerSharedLib/Public/winget/Resources.h +++ b/src/AppInstallerSharedLib/Public/winget/Resources.h @@ -60,6 +60,7 @@ namespace AppInstaller WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableWindowsPackageManagerCommandLineInterfaces); WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableWinGetConfiguration); WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableProxyCommandLineOptions); + WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableExperimentation); WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningInvalidFieldFormat); WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningInvalidFieldValue); diff --git a/src/Internal/Experiment/Experiment.cpp b/src/Internal/Experiment/Experiment.cpp new file mode 100644 index 0000000000..7ba1d62161 --- /dev/null +++ b/src/Internal/Experiment/Experiment.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "Experiment.h" + +namespace AppInstaller::Experiment +{ + bool IsEnabled(const ExperimentKey& key) + { +#ifndef AICLI_DISABLE_TEST_HOOKS + if (key == ExperimentKey::TestExperiment) + { + return true; + } +#endif + return false; + } +} diff --git a/src/Internal/Experiment/Experiment.h b/src/Internal/Experiment/Experiment.h new file mode 100644 index 0000000000..a57bb6d59e --- /dev/null +++ b/src/Internal/Experiment/Experiment.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once + +#include + +namespace AppInstaller::Experiment +{ + enum class ExperimentKey : unsigned + { + None = 0, + CDN, + Max, + +#ifndef AICLI_DISABLE_TEST_HOOKS + TestExperiment = 0xFFFFFFFF, +#endif + }; + + bool IsEnabled(const ExperimentKey& experimentKey); +} diff --git a/src/Internal/Experiment/Experiment.vcxproj b/src/Internal/Experiment/Experiment.vcxproj new file mode 100644 index 0000000000..64034b8fb4 --- /dev/null +++ b/src/Internal/Experiment/Experiment.vcxproj @@ -0,0 +1,393 @@ + + + + + + true + true + true + 15.0 + {98920ab6-27b0-4c0f-b336-fa49de57a1ba} + Win32Proj + Experiment + 10.0.22621.0 + 10.0.17763.0 + true + true + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Fuzzing + x64 + + + Fuzzing + Win32 + + + ReleaseStatic + ARM + + + ReleaseStatic + ARM64 + + + ReleaseStatic + Win32 + + + ReleaseStatic + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + StaticLibrary + v140 + v141 + v142 + v143 + Unicode + + + true + true + + + false + true + false + + + false + true + false + + + false + false + false + true + + + Spectre + + + + + + + + + + + + true + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + ..\..\CodeAnalysis.ruleset + + + true + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + ..\..\CodeAnalysis.ruleset + + + true + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + ..\..\CodeAnalysis.ruleset + + + true + $(SolutionDir)x86\$(Configuration)\$(ProjectName)\ + true + true + ..\..\CodeAnalysis.ruleset + + + false + $(SolutionDir)x86\$(Configuration)\$(ProjectName)\ + true + false + ..\..\CodeAnalysis.ruleset + + + false + $(SolutionDir)x86\$(Configuration)\$(ProjectName)\ + true + false + ..\..\CodeAnalysis.ruleset + + + false + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + true + false + ..\..\CodeAnalysis.ruleset + + + false + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + true + false + ..\..\CodeAnalysis.ruleset + + + false + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)x86\$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + true + false + ..\..\CodeAnalysis.ruleset + + + false + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + true + false + ..\..\CodeAnalysis.ruleset + + + false + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + true + false + ..\..\CodeAnalysis.ruleset + + + false + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + true + false + ..\..\CodeAnalysis.ruleset + + + + NotUsing + _CONSOLE;%(PreprocessorDefinitions) + Level4 + %(AdditionalOptions) /permissive- /D _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING + + + + + Disabled + _NO_ASYNCRTIMP;_DEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + true + true + true + true + true + true + true + true + true + false + false + false + + + false + Windows + Windows + Windows + + + + + _NO_ASYNCRTIMP;WIN32;%(PreprocessorDefinitions);CLICOREDLLBUILD + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + true + true + true + false + + + Windows + + + + + MaxSpeed + true + true + _NO_ASYNCRTIMP;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + true + true + true + true + true + true + true + true + false + false + false + false + false + false + false + false + + + true + true + false + Windows + Windows + Windows + Windows + + + + + MaxSpeed + true + true + _NO_ASYNCRTIMP;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + true + true + true + true + true + true + true + true + false + false + false + false + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + false + false + false + false + + + true + true + false + Windows + Windows + Windows + Windows + + + + + MaxSpeed + true + true + _NO_ASYNCRTIMP;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD;WINGET_DISABLE_FOR_FUZZING;_DISABLE_VECTOR_ANNOTATION;_DISABLE_STRING_ANNOTATION + $(ProjectDir);$(ProjectDir)..\..\AppInstallerSharedLib;$(ProjectDir)..\..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + true + stdcpp17 + MultiThreaded + %(AdditionalOptions) /fsanitize=address /fsanitize-coverage=inline-8bit-counters /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div + false + + + true + true + false + Windows + + + + + AICLI_DISABLE_TEST_HOOKS;%(PreprocessorDefinitions) + + + + + WINGET_DISABLE_EXPERIMENTAL_FEATURES;%(PreprocessorDefinitions) + + + + + WINGET_ENABLE_RELEASE_BUILD;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/src/Internal/Experiment/Experiment.vcxproj.filters b/src/Internal/Experiment/Experiment.vcxproj.filters new file mode 100644 index 0000000000..1c381b05ef --- /dev/null +++ b/src/Internal/Experiment/Experiment.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + Source Files + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj b/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj index 57f0161936..ecfa8938e2 100644 --- a/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj +++ b/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj @@ -127,7 +127,7 @@ true _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) - $(ProjectDir)..\AppInstallerCLICore;$(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) + $(ProjectDir)..\AppInstallerCLICore;$(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerSharedLib\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\Internal;%(AdditionalIncludeDirectories) Console diff --git a/src/PowerShell/Microsoft.WinGet.SharedLib/Extensions/EnumPolicyExtension.cs b/src/PowerShell/Microsoft.WinGet.SharedLib/Extensions/EnumPolicyExtension.cs index 08dc136e03..2c9eef9457 100644 --- a/src/PowerShell/Microsoft.WinGet.SharedLib/Extensions/EnumPolicyExtension.cs +++ b/src/PowerShell/Microsoft.WinGet.SharedLib/Extensions/EnumPolicyExtension.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -50,6 +50,8 @@ public static string GetResourceString(this Policy policy) return GroupPolicyResource.PolicyEnableWindowsPackageManagerCommandLineInterfaces; case Policy.Configuration: return GroupPolicyResource.PolicyEnableWinGetConfiguration; + case Policy.Experimentation: + return GroupPolicyResource.PolicyEnableExperimentation; default: return string.Empty; } diff --git a/src/PowerShell/Microsoft.WinGet.SharedLib/PolicySettings/Enums.cs b/src/PowerShell/Microsoft.WinGet.SharedLib/PolicySettings/Enums.cs index d4121f040d..832f632e58 100644 --- a/src/PowerShell/Microsoft.WinGet.SharedLib/PolicySettings/Enums.cs +++ b/src/PowerShell/Microsoft.WinGet.SharedLib/PolicySettings/Enums.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -96,6 +96,11 @@ public enum Policy /// Enabled configuration. /// Configuration, + + /// + /// Enabled experimentation. + /// + Experimentation, } /// diff --git a/src/PowerShell/Microsoft.WinGet.SharedLib/PolicySettings/TogglePolicy.cs b/src/PowerShell/Microsoft.WinGet.SharedLib/PolicySettings/TogglePolicy.cs index 481d80e2a9..dba34eaff5 100644 --- a/src/PowerShell/Microsoft.WinGet.SharedLib/PolicySettings/TogglePolicy.cs +++ b/src/PowerShell/Microsoft.WinGet.SharedLib/PolicySettings/TogglePolicy.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -125,6 +125,8 @@ internal static TogglePolicy Create(Policy policy) return new TogglePolicy(policy, "EnableWindowsPackageManagerCommandLineInterfaces", GroupPolicyResource.PolicyEnableWindowsPackageManagerCommandLineInterfaces); case Policy.Configuration: return new TogglePolicy(policy, "EnableWindowsPackageManagerConfiguration", GroupPolicyResource.PolicyEnableWinGetConfiguration); + case Policy.Experimentation: + return new TogglePolicy(policy, "EnableExperimentation", GroupPolicyResource.PolicyEnableExperimentation); default: throw new ArgumentException(null, nameof(policy)); } diff --git a/src/PowerShell/Microsoft.WinGet.SharedLib/Resources/GroupPolicyResource.Designer.cs b/src/PowerShell/Microsoft.WinGet.SharedLib/Resources/GroupPolicyResource.Designer.cs index 13d57659f4..b47191a290 100644 --- a/src/PowerShell/Microsoft.WinGet.SharedLib/Resources/GroupPolicyResource.Designer.cs +++ b/src/PowerShell/Microsoft.WinGet.SharedLib/Resources/GroupPolicyResource.Designer.cs @@ -114,6 +114,15 @@ internal static string PolicyEnableExperimentalFeatures { } } + /// + /// Looks up a localized string similar to Enable Windows Package Manager Feature Experimentation. + /// + internal static string PolicyEnableExperimentation { + get { + return ResourceManager.GetString("PolicyEnableExperimentation", resourceCulture); + } + } + /// /// Looks up a localized string similar to Enable Windows App Installer Hash Override. /// diff --git a/src/PowerShell/Microsoft.WinGet.SharedLib/Resources/GroupPolicyResource.resx b/src/PowerShell/Microsoft.WinGet.SharedLib/Resources/GroupPolicyResource.resx index 60d79c6e0f..c25decaa15 100644 --- a/src/PowerShell/Microsoft.WinGet.SharedLib/Resources/GroupPolicyResource.resx +++ b/src/PowerShell/Microsoft.WinGet.SharedLib/Resources/GroupPolicyResource.resx @@ -1,4 +1,4 @@ - +