winget-cli

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

commit 33bc04e3d97bcfcffac252a45ab7486bbbf15758
parent 17fc527b3541a5088bd4a36278e80f533dd3f51d
Author: jamespik <48262337+jamespik@users.noreply.github.com>
Date:   Mon, 25 Oct 2021 12:22:53 -0700

Introduce Managed Interop and merged manifest classes to WingetUtil nuget  (#1621)

* Add new interop dll and update nuspec/targets

* Add tests. Update Nuget Publish pipeline.

* Fix typos

* update word list

* PR Comments

* Correct path in build.

* Fix folder path
Diffstat:
M.github/actions/spelling/allow.txt | 21+++++++++++++++++++++
MWinGetUtil.nuspec | 8++++++++
Mazure-pipelines.nuget.yml | 1+
Mazure-pipelines.yml | 20++++++++++++++++++++
Msrc/AppInstallerCLI.sln | 233+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/Common/DisplayTestMethodNameAttribute.cs | 33+++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/ManifestUnitTest/ManifestEqualityUnitTests.cs | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs | 334+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/AllEquality.yaml | 28++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/AllEqualityWithDescription.yaml | 29+++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/DifferentId.yaml | 28++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/OneInstaller.yaml | 19+++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/SomeEquality.yaml | 13+++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/SomeEqualityWithLocalization.yaml | 18++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/SomeEqualityWithoutInstallers.yaml | 6++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/SomeEqualityWithoutSwitches.yaml | 9+++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/Test_yaml_with_bom.yaml | 14++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/Test_yaml_without_bom.yaml | 14++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/V1ManifestInfoMissingRequiredPackageLocale.yaml | 20++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/V1ManifestMerged.yaml | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/V1ManifestNoLocalization.yaml | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/TestCollateral/V1_1ManifestMerged.yaml | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop.UnitTests/WinGetUtilInterop.UnitTests.csproj | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Build/Microsoft.WindowsPackageManager.Utils.targets | 9+++++++++
Asrc/WinGetUtilInterop/Helpers/WinGetUtilWrapperManifest.cs | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/Preview/InstallerSwitches.cs | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/Preview/Manifest.cs | 281+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/Preview/ManifestInstaller.cs | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/Preview/ManifestLocalization.cs | 34++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/InstallerArpEntry.cs | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/InstallerDependency.cs | 37+++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/InstallerExpectedReturnCode.cs | 25+++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/InstallerMarkets.cs | 27+++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/InstallerPackageDependency.cs | 26++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/InstallerSwitches.cs | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/Manifest.cs | 466+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs | 248+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/ManifestLocalization.cs | 162+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/MinManifestInfo.cs | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/Manifest/V1/PackageAgreement.cs | 30++++++++++++++++++++++++++++++
Asrc/WinGetUtilInterop/WinGetUtilInterop.csproj | 15+++++++++++++++
41 files changed, 3548 insertions(+), 0 deletions(-)

diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt @@ -26,6 +26,7 @@ argc args argv ARRAYSIZE +artifactstagingdirectory aspirational aspnet authn @@ -66,6 +67,8 @@ conemu config Configurability constexpr +contosa +contosainstaller Contoso copyable COSTDEFERRED @@ -98,6 +101,7 @@ Demitrius denelon depersist deque +deserialize Deserialize deserializer deserializing @@ -109,6 +113,7 @@ distro dll dllexport dllmain +Dlls docx dotnet downlevel @@ -131,6 +136,8 @@ errorlevel errstr esrp etag +etcoreapp +etstandard ETW EULA EVENTTAG @@ -149,6 +156,7 @@ EXTRAFLAGS FAILIFTHERE fakeswitch FATALEXIT +FEBAB FIELDTAG FILEFLAGS FILEFLAGSMASK @@ -196,9 +204,12 @@ IAppx IAsync IBuffer icu +IDeserializer IDisposable IDX IEnumerable +IEquatable +IEquitable IFACEMETHOD ifdef ifndef @@ -207,8 +218,10 @@ IInput IInspectable IIS ILogger +IManifest impl Inet +inheritdoc inno INotify INPROC @@ -230,10 +243,12 @@ IProgress IRandom IRest ISAPPROVEDFOROUTPUT +ISet ISource isspace istream istringstream +ITest IUnknown json junit @@ -274,6 +289,7 @@ Minimatch MINORVERSION mkdir monostate +Moq motw mrm msbuild @@ -284,6 +300,7 @@ msiexec msix msixbundle msixinfo +msixmgr msixsdk msixsdkx msixtest @@ -296,6 +313,7 @@ namespace namespaces Nelon netcoreapp +netstandard newid NOCLOSEPROCESS nodiscard @@ -471,6 +489,7 @@ stoll storeedgefd storepreview stoull +stpkgmanvalwestustest strcoll streamoff streampos @@ -551,6 +570,7 @@ UNICODESTRING uninstall uninstalling Unregister +untimes updatemanifest UPLEVEL upvote @@ -622,6 +642,7 @@ XName XResource xsd XTOKEN +xunit yaml yml yy diff --git a/WinGetUtil.nuspec b/WinGetUtil.nuspec @@ -12,6 +12,11 @@ <description>The utility binary for use with the WinGet CLI.</description> <copyright>© Microsoft Corporation. All rights reserved.</copyright> <tags>winget</tags> + <dependencies> + <group targetFramework=".NETStandard2.0"> + <dependency id="YamlDotNet" version="8.1.2" exclude="Build,Analyzers" /> + </group> + </dependencies> </metadata> <files> <file src="src\x64\Release\WinGetUtil\WinGetUtil.dll" target="runtimes\win-x64\native\WinGetUtil.dll"/> @@ -19,5 +24,8 @@ <file src="src\x86\Release\WinGetUtil\WinGetUtil.dll" target="runtimes\win-x86\native\WinGetUtil.dll"/> <file src="src\x86\Release\WinGetUtil\WinGetUtil.pdb" target="runtimes\win-x86\native\WinGetUtil.pdb"/> <file src="schemas\JSON\manifests\**" target="content\schemas\JSON\manifests" /> + <file src="src\WinGetUtilInterop\bin\Release\netstandard2.0\WinGetUtilInterop.dll" target="lib/netstandard2.0/WinGetUtilInterop.dll" /> + <file src="src\WinGetUtilInterop\bin\Release\netstandard2.0\WinGetUtilInterop.pdb" target="lib/netstandard2.0/WinGetUtilInterop.pdb" /> + <file src="src\WinGetUtilInterop\build\Microsoft.WindowsPackageManager.Utils.targets" target="build/Microsoft.WindowsPackageManager.Utils.targets" /> </files> </package> \ No newline at end of file diff --git a/azure-pipelines.nuget.yml b/azure-pipelines.nuget.yml @@ -79,6 +79,7 @@ jobs: FolderPath: src Pattern: | *\$(buildConfiguration)\WinGetUtil\WinGetUtil.dll + WinGetUtilInterop\bin\$(buildConfiguration)\netstandard2.0\WinGetUtilInterop.dll UseMinimatch: true signConfigType: inlineSignParams inlineOperation: | diff --git a/azure-pipelines.yml b/azure-pipelines.yml @@ -332,6 +332,26 @@ jobs: runSettingsFile: 'src\x86\Release\PackagedTests\Test.runsettings' condition: succeededOrFailed() + - task: CopyFiles@2 + displayName: 'Copy Files: WinGetUtilInterop.UnitTests' + inputs: + SourceFolder: '$(Build.SourcesDirectory)\src\WinGetUtilInterop.UnitTests\bin\$(BuildConfiguration)\netcoreapp3.1' + TargetFolder: '$(build.artifactstagingdirectory)\WinGetUtilInterop.UnitTests\' + CleanTargetFolder: true + OverWrite: true + condition: succeededOrFailed() + + - task: VSTest@2 + displayName: 'Run tests: WinGetUtilInterop.UnitTests' + inputs: + testSelector: 'testAssemblies' + testAssemblyVer2: 'WinGetUtilInterop.UnitTests.dll' + searchFolder: '$(build.artifactstagingdirectory)\WinGetUtilInterop.UnitTests' + codeCoverageEnabled: true + platform: 'Any CPU' + configuration: '$(BuildConfiguration)' + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 displayName: Publish CLI Binary inputs: diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln @@ -137,6 +137,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackagedTests", "PackagedTe {7DE2CFC7-5AAE-4F89-BF42-8D231E389687} = {7DE2CFC7-5AAE-4F89-BF42-8D231E389687} EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinGetUtilInterop", "WinGetUtilInterop\WinGetUtilInterop.csproj", "{846FB88B-BF1B-4F33-9883-E589CEC99739}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinGetUtilInterop.UnitTests", "WinGetUtilInterop.UnitTests\WinGetUtilInterop.UnitTests.csproj", "{68808357-902B-406C-8C19-E8E26A69DE8A}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ManifestSchema\ManifestSchema.vcxitems*{1622da16-914f-4f57-a259-d5169003cc8c}*SharedItemsImports = 4 @@ -159,24 +163,31 @@ Global ManifestSchema\ManifestSchema.vcxitems*{fb313532-38b0-4676-9303-ab200aa13576}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|ARM = Debug|ARM Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Fuzzing|Any CPU = Fuzzing|Any CPU Fuzzing|ARM = Fuzzing|ARM Fuzzing|ARM64 = Fuzzing|ARM64 Fuzzing|x64 = Fuzzing|x64 Fuzzing|x86 = Fuzzing|x86 + Release|Any CPU = Release|Any CPU Release|ARM = Release|ARM Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 + TestRelease|Any CPU = TestRelease|Any CPU TestRelease|ARM = TestRelease|ARM TestRelease|ARM64 = TestRelease|ARM64 TestRelease|x64 = TestRelease|x64 TestRelease|x86 = TestRelease|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.ActiveCfg = Debug|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.Build.0 = Debug|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.Deploy.0 = Debug|ARM @@ -189,10 +200,16 @@ Global {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.ActiveCfg = Debug|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Build.0 = Debug|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Deploy.0 = Debug|x86 + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.ActiveCfg = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.Build.0 = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.Deploy.0 = Release|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|ARM.ActiveCfg = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x64.ActiveCfg = Release|x64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x86.ActiveCfg = Release|x86 + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.Build.0 = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.Deploy.0 = Release|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.ActiveCfg = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.Build.0 = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.Deploy.0 = Release|ARM @@ -205,10 +222,14 @@ Global {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.ActiveCfg = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Build.0 = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Deploy.0 = Release|x86 + {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|Any CPU.Build.0 = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|Any CPU.Deploy.0 = Release|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|ARM.ActiveCfg = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|x64.ActiveCfg = Release|x64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|x86.ActiveCfg = Release|x86 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.ActiveCfg = Debug|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.Build.0 = Debug|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -217,10 +238,13 @@ Global {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x64.Build.0 = Debug|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.ActiveCfg = Debug|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.Build.0 = Debug|Win32 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|Any CPU.Build.0 = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|ARM.ActiveCfg = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x64.ActiveCfg = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x86.ActiveCfg = Release|Win32 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|Any CPU.ActiveCfg = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM.ActiveCfg = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM.Build.0 = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -229,10 +253,13 @@ Global {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x64.Build.0 = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.ActiveCfg = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.Build.0 = Release|Win32 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|Any CPU.Build.0 = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|ARM.ActiveCfg = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|x64.ActiveCfg = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|x86.ActiveCfg = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|Any CPU.ActiveCfg = Debug|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.ActiveCfg = Debug|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.Build.0 = Debug|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -241,10 +268,13 @@ Global {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x64.Build.0 = Debug|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.ActiveCfg = Debug|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.Build.0 = Debug|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|Any CPU.Build.0 = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|ARM.ActiveCfg = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x64.ActiveCfg = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x86.ActiveCfg = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|Any CPU.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM.ActiveCfg = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM.Build.0 = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -253,6 +283,8 @@ Global {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x64.Build.0 = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.Build.0 = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|Any CPU.Build.0 = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM.ActiveCfg = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM.Build.0 = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM64.ActiveCfg = Release|ARM64 @@ -261,6 +293,7 @@ Global {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x64.Build.0 = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x86.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x86.Build.0 = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.ActiveCfg = Debug|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.Build.0 = Debug|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -269,10 +302,13 @@ Global {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x64.Build.0 = Debug|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.ActiveCfg = Debug|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.Build.0 = Debug|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|Any CPU.Build.0 = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|ARM.ActiveCfg = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x64.ActiveCfg = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x86.ActiveCfg = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|Any CPU.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM.ActiveCfg = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM.Build.0 = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -281,6 +317,8 @@ Global {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x64.Build.0 = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.Build.0 = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|Any CPU.Build.0 = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM.ActiveCfg = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM.Build.0 = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM64.ActiveCfg = Release|ARM64 @@ -289,26 +327,33 @@ Global {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x64.Build.0 = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x86.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x86.Build.0 = Release|Win32 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|Any CPU.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM64.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.ActiveCfg = Debug|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.Build.0 = Debug|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.Build.0 = Debug|Win32 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|Any CPU.ActiveCfg = Release|x64 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|Any CPU.Build.0 = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|ARM.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|ARM64.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x86.ActiveCfg = Release|Win32 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|Any CPU.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM64.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.Build.0 = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.Build.0 = Release|Win32 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|Any CPU.ActiveCfg = Release|x64 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|Any CPU.Build.0 = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|ARM.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|ARM64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|x86.ActiveCfg = Release|Win32 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|Any CPU.ActiveCfg = Debug|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.ActiveCfg = Debug|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.Build.0 = Debug|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -317,11 +362,13 @@ Global {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x64.Build.0 = Debug|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x86.ActiveCfg = Debug|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x86.Build.0 = Debug|Win32 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|ARM.ActiveCfg = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x64.Build.0 = Fuzzing|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x86.ActiveCfg = Release|Win32 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|Any CPU.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM.ActiveCfg = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM.Build.0 = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -330,6 +377,8 @@ Global {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x64.Build.0 = Release|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.Build.0 = Release|Win32 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|Any CPU.ActiveCfg = Fuzzing|ARM + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|Any CPU.Build.0 = Fuzzing|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM.ActiveCfg = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM.Build.0 = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM64.ActiveCfg = Release|ARM64 @@ -338,6 +387,7 @@ Global {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x64.Build.0 = Release|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x86.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x86.Build.0 = Release|Win32 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.ActiveCfg = Debug|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.Build.0 = Debug|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -346,11 +396,13 @@ Global {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x64.Build.0 = Debug|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.ActiveCfg = Debug|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.Build.0 = Debug|Win32 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|ARM.ActiveCfg = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.Build.0 = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x86.ActiveCfg = Release|Win32 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|Any CPU.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM.ActiveCfg = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM.Build.0 = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -359,6 +411,8 @@ Global {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x64.Build.0 = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.Build.0 = Release|Win32 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|Any CPU.ActiveCfg = Release|x64 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|Any CPU.Build.0 = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM.ActiveCfg = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM.Build.0 = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM64.ActiveCfg = Release|ARM64 @@ -367,6 +421,7 @@ Global {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x64.Build.0 = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x86.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x86.Build.0 = Release|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.Debug|Any CPU.ActiveCfg = Debug|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.ActiveCfg = Debug|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.Build.0 = Debug|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -375,10 +430,13 @@ Global {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x64.Build.0 = Debug|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.ActiveCfg = Debug|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.Build.0 = Debug|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|Any CPU.Build.0 = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|ARM.ActiveCfg = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x64.ActiveCfg = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x86.ActiveCfg = Release|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.Release|Any CPU.ActiveCfg = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM.ActiveCfg = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM.Build.0 = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -387,10 +445,13 @@ Global {FB313532-38B0-4676-9303-AB200AA13576}.Release|x64.Build.0 = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.ActiveCfg = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.Build.0 = Release|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|Any CPU.Build.0 = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|ARM.ActiveCfg = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|x64.ActiveCfg = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|x86.ActiveCfg = Release|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|Any CPU.ActiveCfg = Debug|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.ActiveCfg = Debug|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.Build.0 = Debug|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -399,10 +460,13 @@ Global {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x64.Build.0 = Debug|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.ActiveCfg = Debug|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.Build.0 = Debug|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|Any CPU.Build.0 = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|ARM.ActiveCfg = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x64.ActiveCfg = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x86.ActiveCfg = Release|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|Any CPU.ActiveCfg = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM.ActiveCfg = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM.Build.0 = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -411,30 +475,41 @@ Global {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x64.Build.0 = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.ActiveCfg = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.Build.0 = Release|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|Any CPU.Build.0 = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|ARM.ActiveCfg = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|x64.ActiveCfg = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|x86.ActiveCfg = Release|Win32 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|Any CPU.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM64.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.ActiveCfg = Debug|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.Build.0 = Debug|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.Build.0 = Debug|x86 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|Any CPU.ActiveCfg = TestOnly|x64 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|Any CPU.Build.0 = TestOnly|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|ARM.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x86.ActiveCfg = Release|x86 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|Any CPU.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|ARM.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|ARM64.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.Build.0 = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.Build.0 = Release|x86 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|Any CPU.ActiveCfg = TestOnly|x64 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|Any CPU.Build.0 = TestOnly|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|ARM.ActiveCfg = TestOnly|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|ARM64.ActiveCfg = TestOnly|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|x86.ActiveCfg = Release|x86 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.ActiveCfg = Debug|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Build.0 = Debug|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Deploy.0 = Debug|ARM @@ -447,10 +522,16 @@ Global {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.ActiveCfg = Debug|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Build.0 = Debug|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Deploy.0 = Debug|x86 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.ActiveCfg = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.Build.0 = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.Deploy.0 = Release|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|ARM.ActiveCfg = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x64.ActiveCfg = Release|x64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x86.ActiveCfg = Release|x86 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.Build.0 = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.Deploy.0 = Release|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.ActiveCfg = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.Build.0 = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.Deploy.0 = Release|ARM @@ -463,46 +544,64 @@ Global {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.ActiveCfg = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Build.0 = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Deploy.0 = Release|x86 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|Any CPU.Build.0 = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|Any CPU.Deploy.0 = Release|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|ARM.ActiveCfg = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|x64.ActiveCfg = Release|x64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|x86.ActiveCfg = Release|x86 + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|Any CPU.ActiveCfg = Debug + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|Any CPU.Build.0 = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM64.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x64.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x86.ActiveCfg = Debug + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|Any CPU.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|Any CPU.Build.0 = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x86.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|Any CPU.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|Any CPU.Build.0 = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x86.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|Any CPU.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|Any CPU.Build.0 = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|x86.ActiveCfg = Release + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|Any CPU.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM64.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.ActiveCfg = Debug|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.Build.0 = Debug|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.Build.0 = Debug|x86 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|Any CPU.ActiveCfg = Release|x64 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|Any CPU.Build.0 = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|ARM.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x86.ActiveCfg = Release|x86 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|Any CPU.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|ARM.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|ARM64.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.Build.0 = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.Build.0 = Release|x86 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|Any CPU.ActiveCfg = Release|x64 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|Any CPU.Build.0 = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|ARM.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|ARM64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|x86.ActiveCfg = Release|x86 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|Any CPU.ActiveCfg = Debug|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.ActiveCfg = Debug|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.Build.0 = Debug|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -511,11 +610,13 @@ Global {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x64.Build.0 = Debug|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x86.ActiveCfg = Debug|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x86.Build.0 = Debug|Win32 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|ARM.ActiveCfg = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x64.Build.0 = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x86.ActiveCfg = Release|Win32 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|Any CPU.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM.ActiveCfg = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM.Build.0 = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -524,6 +625,8 @@ Global {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x64.Build.0 = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.Build.0 = Release|Win32 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|Any CPU.ActiveCfg = Release|x64 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|Any CPU.Build.0 = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM.ActiveCfg = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM.Build.0 = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM64.ActiveCfg = Release|ARM64 @@ -532,44 +635,57 @@ Global {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x64.Build.0 = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x86.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x86.Build.0 = Release|Win32 + {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|Any CPU.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x64.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x64.Build.0 = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x86.ActiveCfg = Fuzzing|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.Build.0 = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x86.ActiveCfg = Fuzzing|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|Any CPU.ActiveCfg = Debug|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|Any CPU.Build.0 = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x86.ActiveCfg = Fuzzing|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|Any CPU.ActiveCfg = Debug|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|Any CPU.Build.0 = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|ARM.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|ARM64.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|x64.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|x86.ActiveCfg = Debug|x64 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|Any CPU.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM64.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.ActiveCfg = Debug|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.Build.0 = Debug|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.Build.0 = Debug|x86 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|Any CPU.ActiveCfg = Release|x64 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|Any CPU.Build.0 = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|ARM.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x86.ActiveCfg = Release|x86 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|Any CPU.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|ARM.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|ARM64.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.Build.0 = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.Build.0 = Release|x86 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|Any CPU.ActiveCfg = Release|x64 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|Any CPU.Build.0 = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|ARM.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|ARM64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|x86.ActiveCfg = Release|x86 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|Any CPU.ActiveCfg = Debug|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.ActiveCfg = Debug|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.Build.0 = Debug|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -578,10 +694,13 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x64.Build.0 = Debug|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x86.ActiveCfg = Debug|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x86.Build.0 = Debug|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|Any CPU.Build.0 = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|ARM.ActiveCfg = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|x64.ActiveCfg = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|x86.ActiveCfg = Release|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|Any CPU.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM.ActiveCfg = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM.Build.0 = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -590,6 +709,8 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x64.Build.0 = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.Build.0 = Release|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|Any CPU.Build.0 = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM.ActiveCfg = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM.Build.0 = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM64.ActiveCfg = Release|ARM64 @@ -598,6 +719,7 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x64.Build.0 = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x86.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x86.Build.0 = Release|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|Any CPU.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.ActiveCfg = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.Build.0 = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -606,10 +728,13 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x64.Build.0 = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.Build.0 = Debug|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|Any CPU.Build.0 = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM.ActiveCfg = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x64.ActiveCfg = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|Any CPU.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.ActiveCfg = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.Build.0 = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -618,6 +743,8 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x64.Build.0 = Release|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.Build.0 = Release|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|Any CPU.Build.0 = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM.ActiveCfg = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM.Build.0 = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM64.ActiveCfg = Release|ARM64 @@ -626,6 +753,7 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x64.Build.0 = Release|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x86.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x86.Build.0 = Release|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|Any CPU.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.ActiveCfg = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.Build.0 = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -634,10 +762,13 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.Build.0 = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.Build.0 = Debug|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|Any CPU.Build.0 = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM.ActiveCfg = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x64.ActiveCfg = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|Any CPU.ActiveCfg = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.ActiveCfg = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.Build.0 = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -646,10 +777,13 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.Build.0 = Release|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.ActiveCfg = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.Build.0 = Release|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|Any CPU.Build.0 = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|ARM.ActiveCfg = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|x64.ActiveCfg = Release|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|x86.ActiveCfg = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|Any CPU.ActiveCfg = Debug|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.ActiveCfg = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.Build.0 = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -658,10 +792,13 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x64.Build.0 = Debug|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.ActiveCfg = Debug|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.Build.0 = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|Any CPU.Build.0 = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM.ActiveCfg = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x64.ActiveCfg = Debug|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|Any CPU.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.ActiveCfg = Release|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.Build.0 = Release|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -670,6 +807,8 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|Any CPU.Build.0 = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|ARM.ActiveCfg = Release|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|ARM.Build.0 = Release|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|ARM64.ActiveCfg = Release|ARM64 @@ -678,18 +817,24 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|x64.Build.0 = Release|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|x86.Build.0 = Release|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|Any CPU.ActiveCfg = Debug|Win32 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM.ActiveCfg = Debug|ARM {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM64.ActiveCfg = Debug|ARM64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x64.ActiveCfg = Debug|x64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x86.ActiveCfg = Debug|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|Any CPU.Build.0 = Release|Win32 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM.ActiveCfg = Debug|ARM {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x64.ActiveCfg = Debug|x64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|Any CPU.ActiveCfg = Release|Win32 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM.ActiveCfg = Release|ARM {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM64.ActiveCfg = Release|ARM64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x64.ActiveCfg = Release|x64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x86.ActiveCfg = Release|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|Any CPU.ActiveCfg = Release|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|Any CPU.Build.0 = Release|Win32 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|ARM.ActiveCfg = Release|ARM {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|ARM.Build.0 = Release|ARM {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|ARM64.ActiveCfg = Release|ARM64 @@ -698,18 +843,26 @@ Global {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|x64.Build.0 = Release|x64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|x86.ActiveCfg = Release|Win32 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|x86.Build.0 = Release|Win32 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|Any CPU.ActiveCfg = Debug|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.ActiveCfg = Debug|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.ActiveCfg = Debug|ARM64 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.ActiveCfg = Debug|x64 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.ActiveCfg = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|Any CPU.ActiveCfg = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|Any CPU.Build.0 = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|Any CPU.Deploy.0 = Release|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.ActiveCfg = Debug|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x64.ActiveCfg = Debug|x64 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.ActiveCfg = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|Any CPU.ActiveCfg = Release|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.ActiveCfg = Release|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.ActiveCfg = Release|ARM64 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.ActiveCfg = Release|x64 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.ActiveCfg = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|Any CPU.ActiveCfg = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|Any CPU.Build.0 = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|Any CPU.Deploy.0 = Release|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|ARM.ActiveCfg = Release|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|ARM.Build.0 = Release|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|ARM.Deploy.0 = Release|ARM @@ -722,6 +875,86 @@ Global {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|x86.ActiveCfg = Release|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|x86.Build.0 = Release|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|x86.Deploy.0 = Release|x86 + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|Any CPU.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM64.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x64.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x64.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x86.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x86.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|Any CPU.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|Any CPU.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|ARM.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|ARM.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|ARM64.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|ARM64.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x64.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x64.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x86.ActiveCfg = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x86.Build.0 = Debug|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|Any CPU.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|Any CPU.Build.0 = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM.Build.0 = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM64.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM64.Build.0 = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x64.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x64.Build.0 = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x86.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x86.Build.0 = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|Any CPU.Build.0 = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|ARM.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|ARM.Build.0 = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|ARM64.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|ARM64.Build.0 = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|x64.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|x64.Build.0 = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|x86.ActiveCfg = Release|Any CPU + {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|x86.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|ARM.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|ARM.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|ARM64.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x64.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x64.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x86.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x86.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|Any CPU.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|Any CPU.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|ARM.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|ARM.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|ARM64.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|ARM64.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x64.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x64.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x86.ActiveCfg = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x86.Build.0 = Debug|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|Any CPU.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|ARM.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|ARM.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|ARM64.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|ARM64.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x64.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x64.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x86.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x86.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|Any CPU.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|ARM.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|ARM.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|ARM64.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|ARM64.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|x64.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|x64.Build.0 = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|x86.ActiveCfg = Release|Any CPU + {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/WinGetUtilInterop.UnitTests/Common/DisplayTestMethodNameAttribute.cs b/src/WinGetUtilInterop.UnitTests/Common/DisplayTestMethodNameAttribute.cs @@ -0,0 +1,33 @@ +// ----------------------------------------------------------------------- +// <copyright file="DisplayTestMethodNameAttribute.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.UnitTests.Common.Logging +{ + using System; + using System.Reflection; + using Microsoft.Msix.Utils.Logger; + using Xunit.Sdk; + + /// <summary> + /// This will log the name the method in OWC utils logger. + /// </summary> + internal class DisplayTestMethodNameAttribute : BeforeAfterTestAttribute + { + /// <inheritdoc/> + public override void Before(MethodInfo methodUnderTest) + { + Logger.Info("-----------------------------------------------------------------------"); + Logger.Info($"Starting test {methodUnderTest.Name}{Environment.NewLine}"); + } + + /// <inheritdoc/> + public override void After(MethodInfo methodUnderTest) + { + Logger.Info($"{Environment.NewLine}Finish test {methodUnderTest.Name}"); + Logger.Info("-----------------------------------------------------------------------\n"); + } + } +} diff --git a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/ManifestEqualityUnitTests.cs b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/ManifestEqualityUnitTests.cs @@ -0,0 +1,156 @@ +// ----------------------------------------------------------------------- +// <copyright file="ManifestEqualityUnitTests.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.UnitTests.ManifestUnitTest +{ + using System.IO; + using System.Reflection; + using Microsoft.WinGetUtil.Models.Preview; + using Microsoft.WinGetUtil.UnitTests.Common.Logging; + using Xunit; + using Xunit.Abstractions; + + /// <summary> + /// Manifest equality tests. + /// </summary> + public class ManifestEqualityUnitTests + { + private ITestOutputHelper log; + + /// <summary> + /// Initializes a new instance of the <see cref="ManifestEqualityUnitTests"/> class. + /// </summary> + /// <param name="log">Output Helper.</param> + public ManifestEqualityUnitTests(ITestOutputHelper log) + { + this.log = log; + } + + /// <summary> + /// All manifest are equal but some manifest are more equal than others. + /// </summary> + [Fact] + [DisplayTestMethodName] + public void ManifestEquals() + { + // All equality properties. + Manifest allEquality = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.AllEquality)); + Manifest otherAllEquality = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.AllEquality)); + AssertEquivalence(allEquality, allEquality); + AssertEquivalence(allEquality, otherAllEquality); + + // With all equality properties and non equality properties. + Manifest allEqualityWithDescription = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.AllEqualityWithDescription)); + AssertEquivalence(allEquality, allEqualityWithDescription); + + // With some equality properties. + Manifest someEquality = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEquality)); + Manifest otherSomeEquality = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEquality)); + AssertEquivalence(someEquality, otherSomeEquality); + + // With some equality properties and some non equality properties + Manifest someEqualityWithLocalization = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEqualityWithLocalization)); + AssertEquivalence(someEquality, someEqualityWithLocalization); + + // Equality where a Switch object is not serialized + Manifest someEqualityWithoutSwitch = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEqualityWithoutSwitches)); + Manifest otherSomeEqualityWithoutSwitch = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEqualityWithoutSwitches)); + AssertEquivalence(someEqualityWithoutSwitch, otherSomeEqualityWithoutSwitch); + + // Equality where Installers list is not serialized + Manifest someEqualityWithoutInstaller = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEqualityWithoutInstallers)); + Manifest otherSomeEqualityWithoutInstaller = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEqualityWithoutInstallers)); + AssertEquivalence(someEqualityWithoutInstaller, otherSomeEqualityWithoutInstaller); + } + + /// <summary> + /// Every manifest is unique in its own way. + /// </summary> + [Fact] + [DisplayTestMethodName] + public void ManifestNotEquals() + { + // All equality properties. + Manifest allEquality = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.AllEquality)); + Assert.False(allEquality == null); + + Manifest allEqualityOther = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.DifferentId)); + AssertNotEquivalent(allEquality, allEqualityOther); + + Manifest someEquality = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEquality)); + Manifest withoutSwitches = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEqualityWithoutSwitches)); + AssertNotEquivalent(someEquality, withoutSwitches); + + Manifest withoutInstaller = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.SomeEqualityWithoutSwitches)); + AssertNotEquivalent(someEquality, withoutInstaller); + + Manifest oneInstaller = Manifest.CreateManifestFromString(ReadFile(ManifestStrings.OneInstaller)); + AssertNotEquivalent(allEquality, oneInstaller); + } + + private static string ReadFile(string fileName) + { + string location = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + return File.ReadAllText(Path.Combine(location, "TestCollateral", fileName)); + } + + private static void AssertEquivalence(Manifest first, Manifest second) + { + Assert.True(first.IsManifestEquivalent(second)); + } + + private static void AssertNotEquivalent(Manifest first, Manifest second) + { + Assert.False(first.IsManifestEquivalent(second)); + } + + /// <summary> + /// Helper class with manifest strings. + /// </summary> + internal class ManifestStrings + { + /// <summary> + /// Manifest with all properties that provide equality. + /// </summary> + public const string AllEquality = "AllEquality.yaml"; + + /// <summary> + /// Manifest with all properties that provide equality. + /// </summary> + public const string AllEqualityWithDescription = "AllEqualityWithDescription.yaml"; + + /// <summary> + /// Manifest with some properties that provide equality. + /// </summary> + public const string SomeEquality = "SomeEquality.yaml"; + + /// <summary> + /// Manifest with some properties that provide equality. + /// </summary> + public const string SomeEqualityWithLocalization = "SomeEqualityWithLocalization.yaml"; + + /// <summary> + /// Manifest with some properties specifically without switches. + /// </summary> + public const string SomeEqualityWithoutSwitches = "SomeEqualityWithoutSwitches.yaml"; + + /// <summary> + /// Manifest with some properties specifically without installers. + /// </summary> + public const string SomeEqualityWithoutInstallers = "SomeEqualityWithoutInstallers.yaml"; + + /// <summary> + /// Manifest with all properties that provide equality. + /// </summary> + public const string DifferentId = "DifferentId.yaml"; + + /// <summary> + /// Manifest with all properties that provide equality. + /// </summary> + public const string OneInstaller = "OneInstaller.yaml"; + } + } +} diff --git a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs @@ -0,0 +1,334 @@ +// ----------------------------------------------------------------------- +// <copyright file="V1ManifestReadTest.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.UnitTests.ManifestUnitTest +{ + using System.IO; + using System.Reflection; + using Microsoft.WinGetUtil.Models.V1; + using Microsoft.WinGetUtil.UnitTests.Common.Logging; + using Xunit; + using Xunit.Abstractions; + + /// <summary> + /// Manifest equality tests. + /// </summary> + public class V1ManifestReadTest + { + private ITestOutputHelper log; + + /// <summary> + /// Initializes a new instance of the <see cref="V1ManifestReadTest"/> class. + /// </summary> + /// <param name="log">Output Helper.</param> + public V1ManifestReadTest(ITestOutputHelper log) + { + this.log = log; + } + + private enum TestManifestVersion + { + V100, + V110, + } + + /// <summary> + /// Read v1 manifest. + /// </summary> + [Fact] + [DisplayTestMethodName] + public void ReadV1ManifestsAndVerifyContents() + { + Manifest v100manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V100ManifestMerged)); + + this.ValidateManifestFields(v100manifest, TestManifestVersion.V100); + + Manifest v110manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V110ManifestMerged)); + + this.ValidateManifestFields(v110manifest, TestManifestVersion.V110); + } + + /// <summary> + /// Read v1 manifest without additional localization. + /// </summary> + [Fact] + [DisplayTestMethodName] + public void ReadV1ManifestNoLocalization() + { + Manifest v1manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V1ManifestNoLocalization)); + + // Calling GetURIs() on manifest without localization should not fail. + v1manifest.GetURIs(); + } + + /// <summary> + /// Read bad min manifest info. + /// </summary> + [Fact] + [DisplayTestMethodName] + public void ReadV1LocaleManifestInfoNoPackageLocale() + { + Assert.Throws<InvalidDataException>( + () => + { + _ = MinManifestInfo.CreateManifestInfoFromPath( + Path.Combine( + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + "TestCollateral", + ManifestStrings.V1ManifestInfoMissingRequiredPackageLocale)); + }); + } + + private void ValidateManifestFields(Manifest manifest, TestManifestVersion manifestVersion) + { + Assert.Equal("microsoft.msixsdk", manifest.Id); + Assert.Equal("1.7.32", manifest.Version); + + // Default locale + Assert.Equal("en-US", manifest.PackageLocale); + Assert.Equal("Microsoft", manifest.Publisher); + Assert.Equal("https://www.microsoft.com", manifest.PublisherUrl); + Assert.Equal("https://www.microsoft.com/support", manifest.PublisherSupportUrl); + Assert.Equal("https://www.microsoft.com/privacy", manifest.PrivacyUrl); + Assert.Equal("Microsoft", manifest.Author); + Assert.Equal("MSIX SDK", manifest.PackageName); + Assert.Equal("https://www.microsoft.com/msixsdk/home", manifest.PackageUrl); + Assert.Equal("MIT License", manifest.License); + Assert.Equal("https://www.microsoft.com/msixsdk/license", manifest.LicenseUrl); + Assert.Equal("Copyright Microsoft Corporation", manifest.Copyright); + Assert.Equal("https://www.microsoft.com/msixsdk/copyright", manifest.CopyrightUrl); + Assert.Equal("This is MSIX SDK", manifest.ShortDescription); + Assert.Equal("The MSIX SDK project is an effort to enable developers", manifest.Description); + Assert.Equal("msixsdk", manifest.Moniker); + Assert.Equal(2, manifest.Tags.Count); + Assert.Equal("appxsdk", manifest.Tags[0]); + Assert.Equal("msixsdk", manifest.Tags[1]); + + if (manifestVersion >= TestManifestVersion.V110) + { + Assert.Equal("Default release notes", manifest.ReleaseNotes); + Assert.Equal("https://DefaultReleaseNotes.net", manifest.ReleaseNotesUrl); + Assert.Single(manifest.Agreements); + Assert.Equal("DefaultLabel", manifest.Agreements[0].AgreementLabel); + Assert.Equal("DefaultText", manifest.Agreements[0].Agreement); + Assert.Equal("https://DefaultAgreementUrl.net", manifest.Agreements[0].AgreementUrl); + } + + // Default installer + Assert.Equal("en-US", manifest.InstallerLocale); + Assert.Equal(2, manifest.Platform.Count); + Assert.Equal("Windows.Desktop", manifest.Platform[0]); + Assert.Equal("Windows.Universal", manifest.Platform[1]); + Assert.Equal("10.0.0.0", manifest.MinimumOSVersion); + Assert.Equal("zip", manifest.InstallerType); + Assert.Equal("machine", manifest.Scope); + Assert.Equal(3, manifest.InstallModes.Count); + Assert.Equal("interactive", manifest.InstallModes[0]); + Assert.Equal("silent", manifest.InstallModes[1]); + Assert.Equal("silentWithProgress", manifest.InstallModes[2]); + + var defaultSwitches = manifest.Switches; + Assert.Equal("/custom", defaultSwitches.Custom); + Assert.Equal("/silentwithprogress", defaultSwitches.SilentWithProgress); + Assert.Equal("/silence", defaultSwitches.Silent); + Assert.Equal("/interactive", defaultSwitches.Interactive); + Assert.Equal("/log=<LOGPATH>", defaultSwitches.Log); + Assert.Equal("/dir=<INSTALLPATH>", defaultSwitches.InstallLocation); + Assert.Equal("/upgrade", defaultSwitches.Upgrade); + + Assert.Equal(2, manifest.InstallerSuccessCodes.Count); + Assert.Equal(1, manifest.InstallerSuccessCodes[0]); + Assert.Equal(0x80070005, manifest.InstallerSuccessCodes[1]); + Assert.Equal("uninstallPrevious", manifest.UpgradeBehavior); + Assert.Equal(2, manifest.Commands.Count); + Assert.Equal("makemsix", manifest.Commands[0]); + Assert.Equal("makeappx", manifest.Commands[1]); + Assert.Equal(2, manifest.Protocols.Count); + Assert.Equal("protocol1", manifest.Protocols[0]); + Assert.Equal("protocol2", manifest.Protocols[1]); + Assert.Equal(4, manifest.FileExtensions.Count); + Assert.Equal("appx", manifest.FileExtensions[0]); + Assert.Equal("msix", manifest.FileExtensions[1]); + Assert.Equal("appxbundle", manifest.FileExtensions[2]); + Assert.Equal("msixbundle", manifest.FileExtensions[3]); + + Assert.Single(manifest.Dependencies.WindowsFeatures); + Assert.Equal("IIS", manifest.Dependencies.WindowsFeatures[0]); + Assert.Single(manifest.Dependencies.WindowsLibraries); + Assert.Equal("VC Runtime", manifest.Dependencies.WindowsLibraries[0]); + Assert.Single(manifest.Dependencies.PackageDependencies); + Assert.Equal("Microsoft.MsixSdkDep", manifest.Dependencies.PackageDependencies[0].PackageIdentifier); + Assert.Equal("1.0.0", manifest.Dependencies.PackageDependencies[0].MinimumVersion); + Assert.Single(manifest.Dependencies.ExternalDependencies); + Assert.Equal("Outside dependencies", manifest.Dependencies.ExternalDependencies[0]); + + Assert.Single(manifest.Capabilities); + Assert.Equal("internetClient", manifest.Capabilities[0]); + Assert.Single(manifest.RestrictedCapabilities); + Assert.Equal("runFullTrust", manifest.RestrictedCapabilities[0]); + Assert.Equal("Microsoft.DesktopAppInstaller_8wekyb3d8bbwe", manifest.PackageFamilyName); + Assert.Equal("{Foo}", manifest.ProductCode); + + if (manifestVersion >= TestManifestVersion.V110) + { + Assert.Equal("2021-01-01", manifest.ReleaseDate); + Assert.True(manifest.InstallerAbortsTerminal); + Assert.True(manifest.InstallLocationRequired); + Assert.True(manifest.RequireExplicitUpgrade); + Assert.Equal("elevatesSelf", manifest.ElevationRequirement); + Assert.Single(manifest.UnsupportedOSArchitectures); + Assert.Equal("arm", manifest.UnsupportedOSArchitectures[0]); + Assert.Single(manifest.AppsAndFeaturesEntries); + Assert.Equal("DisplayName", manifest.AppsAndFeaturesEntries[0].DisplayName); + Assert.Equal("DisplayVersion", manifest.AppsAndFeaturesEntries[0].DisplayVersion); + Assert.Equal("Publisher", manifest.AppsAndFeaturesEntries[0].Publisher); + Assert.Equal("ProductCode", manifest.AppsAndFeaturesEntries[0].ProductCode); + Assert.Equal("UpgradeCode", manifest.AppsAndFeaturesEntries[0].UpgradeCode); + Assert.Equal("exe", manifest.AppsAndFeaturesEntries[0].InstallerType); + Assert.Single(manifest.Markets.AllowedMarkets); + Assert.Equal("US", manifest.Markets.AllowedMarkets[0]); + Assert.Single(manifest.ExpectedReturnCodes); + Assert.Equal(10, manifest.ExpectedReturnCodes[0].InstallerReturnCode); + Assert.Equal("packageInUse", manifest.ExpectedReturnCodes[0].ReturnResponse); + } + + Assert.Equal(2, manifest.Installers.Count); + ManifestInstaller installer1 = manifest.Installers[0]; + Assert.Equal("x86", installer1.Arch); + Assert.Equal("en-GB", installer1.InstallerLocale); + Assert.Single(installer1.Platform); + Assert.Equal("Windows.Desktop", installer1.Platform[0]); + Assert.Equal("10.0.1.0", installer1.MinimumOSVersion); + Assert.Equal("msix", installer1.InstallerType); + Assert.Equal("https://www.microsoft.com/msixsdk/msixsdkx86.msix", installer1.Url); + Assert.Equal("69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82", installer1.Sha256); + Assert.Equal("69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82", installer1.SignatureSha256); + Assert.Equal("user", installer1.Scope); + Assert.Single(installer1.InstallModes); + Assert.Equal("interactive", installer1.InstallModes[0]); + + var installer1Switches = installer1.Switches; + Assert.Equal("/c", installer1Switches.Custom); + Assert.Equal("/sp", installer1Switches.SilentWithProgress); + Assert.Equal("/s", installer1Switches.Silent); + Assert.Equal("/i", installer1Switches.Interactive); + Assert.Equal("/l=<LOGPATH>", installer1Switches.Log); + Assert.Equal("/d=<INSTALLPATH>", installer1Switches.InstallLocation); + Assert.Equal("/u", installer1Switches.Upgrade); + + Assert.Equal("install", installer1.UpgradeBehavior); + Assert.Equal(2, installer1.Commands.Count); + Assert.Equal("makemsixPreview", installer1.Commands[0]); + Assert.Equal("makeappxPreview", installer1.Commands[1]); + Assert.Equal(2, installer1.Protocols.Count); + Assert.Equal("protocol1preview", installer1.Protocols[0]); + Assert.Equal("protocol2preview", installer1.Protocols[1]); + Assert.Equal(4, installer1.FileExtensions.Count); + Assert.Equal("appxbundle", installer1.FileExtensions[0]); + Assert.Equal("msixbundle", installer1.FileExtensions[1]); + Assert.Equal("appx", installer1.FileExtensions[2]); + Assert.Equal("msix", installer1.FileExtensions[3]); + + Assert.Single(installer1.Dependencies.WindowsFeatures); + Assert.Equal("PreviewIIS", installer1.Dependencies.WindowsFeatures[0]); + Assert.Single(installer1.Dependencies.WindowsLibraries); + Assert.Equal("Preview VC Runtime", installer1.Dependencies.WindowsLibraries[0]); + Assert.Single(installer1.Dependencies.PackageDependencies); + Assert.Equal("Microsoft.MsixSdkDepPreview", installer1.Dependencies.PackageDependencies[0].PackageIdentifier); + Assert.Single(installer1.Dependencies.ExternalDependencies); + Assert.Equal("Preview Outside dependencies", installer1.Dependencies.ExternalDependencies[0]); + + Assert.Single(installer1.Capabilities); + Assert.Equal("internetClientPreview", installer1.Capabilities[0]); + Assert.Single(installer1.RestrictedCapabilities); + Assert.Equal("runFullTrustPreview", installer1.RestrictedCapabilities[0]); + Assert.Equal("Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe", installer1.PackageFamilyName); + + if (manifestVersion >= TestManifestVersion.V110) + { + Assert.Equal("2021-02-02", installer1.ReleaseDate); + Assert.True(!installer1.InstallerAbortsTerminal); + Assert.True(!installer1.InstallLocationRequired); + Assert.True(!installer1.RequireExplicitUpgrade); + Assert.Equal("elevationRequired", installer1.ElevationRequirement); + Assert.Single(installer1.UnsupportedOSArchitectures); + Assert.Equal("arm64", installer1.UnsupportedOSArchitectures[0]); + Assert.Single(installer1.Markets.ExcludedMarkets); + Assert.Equal("US", installer1.Markets.ExcludedMarkets[0]); + Assert.Single(installer1.ExpectedReturnCodes); + Assert.Equal(2, installer1.ExpectedReturnCodes[0].InstallerReturnCode); + Assert.Equal("contactSupport", installer1.ExpectedReturnCodes[0].ReturnResponse); + } + + ManifestInstaller installer2 = manifest.Installers[1]; + Assert.Equal("x64", installer2.Arch); + Assert.Equal("exe", installer2.InstallerType); + Assert.Equal("https://www.microsoft.com/msixsdk/msixsdkx64.exe", installer2.Url); + Assert.Equal("69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82", installer2.Sha256); + Assert.Equal("{Bar}", installer2.ProductCode); + + // Localization + Assert.Single(manifest.Localization); + ManifestLocalization localization1 = manifest.Localization[0]; + Assert.Equal("en-GB", localization1.PackageLocale); + Assert.Equal("Microsoft UK", localization1.Publisher); + Assert.Equal("https://www.microsoft.com/UK", localization1.PublisherUrl); + Assert.Equal("https://www.microsoft.com/support/UK", localization1.PublisherSupportUrl); + Assert.Equal("https://www.microsoft.com/privacy/UK", localization1.PrivacyUrl); + Assert.Equal("Microsoft UK", localization1.Author); + Assert.Equal("MSIX SDK UK", localization1.PackageName); + Assert.Equal("https://www.microsoft.com/msixsdk/home/UK", localization1.PackageUrl); + Assert.Equal("MIT License UK", localization1.License); + Assert.Equal("https://www.microsoft.com/msixsdk/license/UK", localization1.LicenseUrl); + Assert.Equal("Copyright Microsoft Corporation UK", localization1.Copyright); + Assert.Equal("https://www.microsoft.com/msixsdk/copyright/UK", localization1.CopyrightUrl); + Assert.Equal("This is MSIX SDK UK", localization1.ShortDescription); + Assert.Equal("The MSIX SDK project is an effort to enable developers UK", localization1.Description); + Assert.Equal(2, localization1.Tags.Count); + Assert.Equal("appxsdkUK", localization1.Tags[0]); + Assert.Equal("msixsdkUK", localization1.Tags[1]); + + if (manifestVersion >= TestManifestVersion.V110) + { + Assert.Equal("Release notes", localization1.ReleaseNotes); + Assert.Equal("https://ReleaseNotes.net", localization1.ReleaseNotesUrl); + Assert.Single(localization1.Agreements); + Assert.Equal("Label", localization1.Agreements[0].AgreementLabel); + Assert.Equal("Text", localization1.Agreements[0].Agreement); + Assert.Equal("https://AgreementUrl.net", localization1.Agreements[0].AgreementUrl); + } + } + + /// <summary> + /// Helper class with manifest strings. + /// </summary> + internal class ManifestStrings + { + /// <summary> + /// Merged v1 manifest. + /// </summary> + public const string V100ManifestMerged = "V1ManifestMerged.yaml"; + + /// <summary> + /// Merged v1.1 manifest. + /// </summary> + public const string V110ManifestMerged = "V1_1ManifestMerged.yaml"; + + /// <summary> + /// Merged v1 manifest without localization. + /// </summary> + public const string V1ManifestNoLocalization = "V1ManifestNoLocalization.yaml"; + + /// <summary> + /// Merged v1 manifest missing required PackageLocale. + /// </summary> + public const string V1ManifestInfoMissingRequiredPackageLocale = "V1ManifestInfoMissingRequiredPackageLocale.yaml"; + } + } +} diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/AllEquality.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/AllEquality.yaml @@ -0,0 +1,27 @@ +Id: id.id +Version: 1.2.3 +Publisher: test +InstallerType: exe +Switches: + Custom: custom + Silent: /s + SilentWithProgress: /sp + Interactive: /i + Language: en-US + Log: /l=<LOGPATH> + InstallLocation: /d=<INSTALLPATH> +Installers: + - Arch: x86 + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + Language: en-US + InstallerType: msix + Scope: user + Switches: + Language: /en-US + Custom: /s + - Arch: x64 + Url: https://contosa.net/publiccontainer/contosainstaller64.exe + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C83 + Language: en-US + Scope: user+ \ No newline at end of file diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/AllEqualityWithDescription.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/AllEqualityWithDescription.yaml @@ -0,0 +1,28 @@ +Id: id.id +Version: 1.2.3 +Publisher: test +InstallerType: exe +Description: This is a description +Switches: + Custom: custom + Silent: /s + SilentWithProgress: /sp + Interactive: /i + Language: en-US + Log: /l=<LOGPATH> + InstallLocation: /d=<INSTALLPATH> +Installers: + - Arch: x86 + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + Language: en-US + InstallerType: msix + Scope: user + Switches: + Language: /en-US + Custom: /s + - Arch: x64 + Url: https://contosa.net/publiccontainer/contosainstaller64.exe + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C83 + Language: en-US + Scope: user+ \ No newline at end of file diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/DifferentId.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/DifferentId.yaml @@ -0,0 +1,27 @@ +Id: id.id2 +Version: 1.2.3 +Publisher: test +InstallerType: exe +Switches: + Custom: custom + Silent: /s + SilentWithProgress: /sp + Interactive: /i + Language: en-US + Log: /l=<LOGPATH> + InstallLocation: /d=<INSTALLPATH> +Installers: + - Arch: x86 + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + Language: en-US + InstallerType: msix + Scope: user + Switches: + Language: /en-US + Custom: /s + - Arch: x64 + Url: https://contosa.net/publiccontainer/contosainstaller64.exe + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C83 + Language: en-US + Scope: user+ \ No newline at end of file diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/OneInstaller.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/OneInstaller.yaml @@ -0,0 +1,18 @@ +Id: id.id +Version: 1.2.3 +Publisher: test +InstallerType: exe +Switches: + Custom: custom + Silent: /s + SilentWithProgress: /sp + Interactive: /i + Language: en-US + Log: /l=<LOGPATH> + InstallLocation: /d=<INSTALLPATH> +Installers: + - Arch: x64 + Url: https://contosa.net/publiccontainer/contosainstaller64.exe + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C83 + Language: en-US + Scope: user+ \ No newline at end of file diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/SomeEquality.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/SomeEquality.yaml @@ -0,0 +1,12 @@ +Id: id.id +Version: 1.2.3 +Switches: + Custom: custom + Silent: /s +Installers: + - Arch: x86 + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + - Arch: x64 + Url: https://contosa.net/publiccontainer/contosainstaller64.exe + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C83+ \ No newline at end of file diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/SomeEqualityWithLocalization.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/SomeEqualityWithLocalization.yaml @@ -0,0 +1,17 @@ +Id: id.id +Version: 1.2.3 +Switches: + Custom: custom + Silent: /s +Installers: + - Arch: x86 + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + - Arch: x64 + Url: https://contosa.net/publiccontainer/contosainstaller64.exe + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C83 +Localization: + - Language: es-MX + Description: Text to display for es-MX + Homepage: https://github.com/microsoft/msix-packaging/es-MX + LicenseUrl: https://github.com/microsoft/msix-packaging/blob/master/LICENSE-es-MX+ \ No newline at end of file diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/SomeEqualityWithoutInstallers.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/SomeEqualityWithoutInstallers.yaml @@ -0,0 +1,5 @@ +Id: id.id +Version: 1.2.3 +Switches: + Custom: custom + Silent: /s+ \ No newline at end of file diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/SomeEqualityWithoutSwitches.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/SomeEqualityWithoutSwitches.yaml @@ -0,0 +1,9 @@ +Id: id.id +Version: 1.2.3 +Installers: + - Arch: x86 + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + - Arch: x64 + Url: https://contosa.net/publiccontainer/contosainstaller64.exe + Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C83 diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/Test_yaml_with_bom.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/Test_yaml_with_bom.yaml @@ -0,0 +1,14 @@ +PackageIdentifier: IntegrationTests.ManifestUpdate.OneInstallerCreate +PackageVersion: 1.0 +PackageName: ManifestUpdate Test +Publisher: Contoso +ShortDescription: Manifest update test for Create manifest create. +License: Text +Installers: +- Architecture: x64 + InstallerUrl: https://stpkgmanvalwestustest.blob.core.windows.net/test-installers/VSCodeUserSetup-x64-1.46.1.exe + InstallerType: inno + InstallerSha256: e29f73f5b6bad9ea5a484d9a934141a03d3fa39c55efd6e65e6e02dea6be9aa5 +PackageLocale: en-US +ManifestType: singleton +ManifestVersion: 1.0.0 diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/Test_yaml_without_bom.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/Test_yaml_without_bom.yaml @@ -0,0 +1,14 @@ +PackageIdentifier: IntegrationTests.ManifestUpdate.OneInstallerCreate +PackageVersion: 1.0 +PackageName: ManifestUpdate Test +Publisher: Contoso +ShortDescription: Manifest update test for Create manifest create. +License: Text +Installers: +- Architecture: x64 + InstallerUrl: https://stpkgmanvalwestustest.blob.core.windows.net/test-installers/VSCodeUserSetup-x64-1.46.1.exe + InstallerType: inno + InstallerSha256: e29f73f5b6bad9ea5a484d9a934141a03d3fa39c55efd6e65e6e02dea6be9aa5 +PackageLocale: en-US +ManifestType: singleton +ManifestVersion: 1.0.0 diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1ManifestInfoMissingRequiredPackageLocale.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1ManifestInfoMissingRequiredPackageLocale.yaml @@ -0,0 +1,20 @@ +PackageIdentifier: microsoft.msixsdk +PackageVersion: 1.7.32 +Publisher: Microsoft UK +PublisherUrl: https://www.microsoft.com/UK +PublisherSupportUrl: https://www.microsoft.com/support/UK +PrivacyUrl: https://www.microsoft.com/privacy/UK +Author: Microsoft UK +PackageName: MSIX SDK UK +PackageUrl: https://www.microsoft.com/msixsdk/home/UK +License: MIT License UK +LicenseUrl: https://www.microsoft.com/msixsdk/license/UK +Copyright: Copyright Microsoft Corporation UK +CopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK +ShortDescription: This is MSIX SDK UK +Description: The MSIX SDK project is an effort to enable developers UK +Tags: + - "appxsdkUK" + - "msixsdkUK" +ManifestType: locale +ManifestVersion: 1.0.0 diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1ManifestMerged.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1ManifestMerged.yaml @@ -0,0 +1,142 @@ +Author: Microsoft +Capabilities: +- internetClient +Commands: +- makemsix +- makeappx +Copyright: Copyright Microsoft Corporation +CopyrightUrl: https://www.microsoft.com/msixsdk/copyright +Dependencies: + ExternalDependencies: + - Outside dependencies + PackageDependencies: + - MinimumVersion: 1.0.0 + PackageIdentifier: Microsoft.MsixSdkDep + WindowsFeatures: + - IIS + WindowsLibraries: + - VC Runtime +Description: The MSIX SDK project is an effort to enable developers +FileExtensions: +- appx +- msix +- appxbundle +- msixbundle +InstallModes: +- interactive +- silent +- silentWithProgress +InstallerLocale: en-US +InstallerSuccessCodes: +- 1 +- 0x80070005 +InstallerSwitches: + Custom: /custom + InstallLocation: /dir=<INSTALLPATH> + Interactive: /interactive + Log: /log=<LOGPATH> + Silent: /silence + SilentWithProgress: /silentwithprogress + Upgrade: /upgrade +InstallerType: zip +Installers: +- Architecture: x86 + Capabilities: + - internetClientPreview + Commands: + - makemsixPreview + - makeappxPreview + Dependencies: + ExternalDependencies: + - Preview Outside dependencies + PackageDependencies: + - PackageIdentifier: Microsoft.MsixSdkDepPreview + WindowsFeatures: + - PreviewIIS + WindowsLibraries: + - Preview VC Runtime + FileExtensions: + - appxbundle + - msixbundle + - appx + - msix + InstallModes: + - interactive + InstallerLocale: en-GB + InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + InstallerSwitches: + Custom: /c + InstallLocation: /d=<INSTALLPATH> + Interactive: /i + Log: /l=<LOGPATH> + Silent: /s + SilentWithProgress: /sp + Upgrade: /u + InstallerType: msix + InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix + MinimumOSVersion: 10.0.1.0 + PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe + Platform: + - Windows.Desktop + Protocols: + - protocol1preview + - protocol2preview + RestrictedCapabilities: + - runFullTrustPreview + Scope: user + SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + UpgradeBehavior: install +- Architecture: x64 + InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + InstallerType: exe + InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe + ProductCode: '{Bar}' +License: MIT License +LicenseUrl: https://www.microsoft.com/msixsdk/license +Localization: +- Author: Microsoft UK + Copyright: Copyright Microsoft Corporation UK + CopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK + Description: The MSIX SDK project is an effort to enable developers UK + License: MIT License UK + LicenseUrl: https://www.microsoft.com/msixsdk/license/UK + PackageLocale: en-GB + PackageName: MSIX SDK UK + PackageUrl: https://www.microsoft.com/msixsdk/home/UK + PrivacyUrl: https://www.microsoft.com/privacy/UK + Publisher: Microsoft UK + PublisherSupportUrl: https://www.microsoft.com/support/UK + PublisherUrl: https://www.microsoft.com/UK + ShortDescription: This is MSIX SDK UK + Tags: + - appxsdkUK + - msixsdkUK +ManifestType: merged +ManifestVersion: 1.0.0 +MinimumOSVersion: 10.0.0.0 +Moniker: msixsdk +PackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe +PackageIdentifier: microsoft.msixsdk +PackageLocale: en-US +PackageName: MSIX SDK +PackageUrl: https://www.microsoft.com/msixsdk/home +PackageVersion: 1.7.32 +Platform: +- Windows.Desktop +- Windows.Universal +PrivacyUrl: https://www.microsoft.com/privacy +ProductCode: '{Foo}' +Protocols: +- protocol1 +- protocol2 +Publisher: Microsoft +PublisherSupportUrl: https://www.microsoft.com/support +PublisherUrl: https://www.microsoft.com +RestrictedCapabilities: +- runFullTrust +Scope: machine +ShortDescription: This is MSIX SDK +Tags: +- appxsdk +- msixsdk +UpgradeBehavior: uninstallPrevious diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1ManifestNoLocalization.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1ManifestNoLocalization.yaml @@ -0,0 +1,117 @@ +Author: Microsoft +Capabilities: +- internetClient +Commands: +- makemsix +- makeappx +Copyright: Copyright Microsoft Corporation +CopyrightUrl: https://github.com/Microsoft/msix-packaging/copyright +Dependencies: + ExternalDependencies: + - Outside dependencies + PackageDependencies: + - MinimumVersion: 1.0.0 + PackageIdentifier: Microsoft.MsixSdkDep + WindowsFeatures: + - IIS + WindowsLibraries: + - VC Runtime +Description: The MSIX SDK project is an effort to enable developers +FileExtensions: +- appx +- msix +- appxbundle +- msixbundle +InstallModes: +- user +- machine +InstallerLocale: en-US +InstallerSuccessCodes: +- 1 +- 0x80070005 +InstallerSwitches: + Custom: /custom + InstallLocation: /dir=<INSTALLPATH> + Interactive: /interactive + Log: /log=<LOGPATH> + Silent: /silence + SilentWithProgress: /silentwithprogress + Upgrade: /upgrade +InstallerType: zip +Installers: +- Architecture: x64 + Commands: + - makemsixPreview + - makeappxPreview + Dependencies: + ExternalDependencies: + - Preview Outside dependencies + PackageDependencies: + - PackageIdentifier: Microsoft.MsixSdkDepPreview + WindowsFeatures: + - PreviewIIS + WindowsLibraries: + - Preview VC Runtime + FileExtensions: + - appxbundle + - msixbundle + - appx + - msix + InstallModes: + - user + InstallerLocale: en-GB + InstallerSha256: a4d23b49269a7cb1e09fbfb1d532c7b1eacb9acba5e2c6172b6206e885296052 + InstallerSwitches: + Custom: /c + InstallLocation: /d=<INSTALLPATH> + Interactive: /i + Log: /l=<LOGPATH> + Silent: /s + SilentWithProgress: /sp + Upgrade: /u + InstallerType: msi + InstallerUrl: https://github.com/microsoft/msix-packaging/releases/download/MSIX-Core-1.1-release/msixmgrSetup-1.1.0.0-x64.msi + MinimumOSVersion: 10.0.1.0 + Platform: + - Windows.Desktop + Protocols: + - protocol1preview + - protocol2preview + Scope: user + UpgradeBehavior: install +- Architecture: x86 + InstallerLocale: en-GB + InstallerSha256: a4d23b49269a7cb1e09fbfb1d532c7b1eacb9acba5e2c6172b6206e885296052 + InstallerType: msi + InstallerUrl: https://github.com/microsoft/msix-packaging/releases/download/MSIX-Core-1.1-release/msixmgrSetup-1.1.0.0-x86.msi +License: MIT License +LicenseUrl: https://github.com/Microsoft/msix-packaging/license +ManifestType: merged +ManifestVersion: 1.0.0 +MinimumOSVersion: 10.0.0.0 +Moniker: msixsdk +PackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe +PackageIdentifier: microsoft.msixsdk +PackageLocale: en-US +PackageName: MSIX SDK +PackageUrl: https://github.com/Microsoft/msix-packaging +PackageVersion: 1.7.32 +Platform: +- Windows.Desktop +- Windows.Universal +PrivacyUrl: https://www.microsoft.com/privacy +ProductCode: '{Foo}' +Protocols: +- protocol1 +- protocol2 +Publisher: Microsoft +PublisherSupportUrl: https://www.microsoft.com/support +PublisherUrl: https://www.microsoft.com +RestrictedCapabilities: +- runFullTrust +Scope: machine +ShortDescription: This is MSIX SDK +Tags: +- appxsdk +- msixsdk +UpgradeBehavior: uninstallPrevious diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_1ManifestMerged.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_1ManifestMerged.yaml @@ -0,0 +1,187 @@ +Agreements: +- Agreement: DefaultText + AgreementLabel: DefaultLabel + AgreementUrl: https://DefaultAgreementUrl.net +AppsAndFeaturesEntries: +- DisplayName: DisplayName + DisplayVersion: DisplayVersion + InstallerType: exe + ProductCode: ProductCode + Publisher: Publisher + UpgradeCode: UpgradeCode +Author: Microsoft +Capabilities: +- internetClient +Commands: +- makemsix +- makeappx +Copyright: Copyright Microsoft Corporation +CopyrightUrl: https://www.microsoft.com/msixsdk/copyright +Dependencies: + ExternalDependencies: + - Outside dependencies + PackageDependencies: + - MinimumVersion: 1.0.0 + PackageIdentifier: Microsoft.MsixSdkDep + WindowsFeatures: + - IIS + WindowsLibraries: + - VC Runtime +Description: The MSIX SDK project is an effort to enable developers +ElevationRequirement: elevatesSelf +ExpectedReturnCodes: +- InstallerReturnCode: 10 + ReturnResponse: packageInUse +FileExtensions: +- appx +- msix +- appxbundle +- msixbundle +InstallLocationRequired: true +InstallModes: +- interactive +- silent +- silentWithProgress +InstallerAbortsTerminal: true +InstallerLocale: en-US +InstallerSuccessCodes: +- 1 +- 0x80070005 +InstallerSwitches: + Custom: /custom + InstallLocation: /dir=<INSTALLPATH> + Interactive: /interactive + Log: /log=<LOGPATH> + Silent: /silence + SilentWithProgress: /silentwithprogress + Upgrade: /upgrade +InstallerType: zip +Installers: +- Architecture: x86 + Capabilities: + - internetClientPreview + Commands: + - makemsixPreview + - makeappxPreview + Dependencies: + ExternalDependencies: + - Preview Outside dependencies + PackageDependencies: + - PackageIdentifier: Microsoft.MsixSdkDepPreview + WindowsFeatures: + - PreviewIIS + WindowsLibraries: + - Preview VC Runtime + ElevationRequirement: elevationRequired + ExpectedReturnCodes: + - InstallerReturnCode: 2 + ReturnResponse: contactSupport + FileExtensions: + - appxbundle + - msixbundle + - appx + - msix + InstallLocationRequired: false + InstallModes: + - interactive + InstallerAbortsTerminal: false + InstallerLocale: en-GB + InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + InstallerSwitches: + Custom: /c + InstallLocation: /d=<INSTALLPATH> + Interactive: /i + Log: /l=<LOGPATH> + Silent: /s + SilentWithProgress: /sp + Upgrade: /u + InstallerType: msix + InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix + Markets: + ExcludedMarkets: + - US + MinimumOSVersion: 10.0.1.0 + PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe + Platform: + - Windows.Desktop + Protocols: + - protocol1preview + - protocol2preview + ReleaseDate: 2021-02-02 + RequireExplicitUpgrade: false + RestrictedCapabilities: + - runFullTrustPreview + Scope: user + SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + UnsupportedOSArchitectures: + - arm64 + UpgradeBehavior: install +- Architecture: x64 + InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + InstallerType: exe + InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe + ProductCode: '{Bar}' +License: MIT License +LicenseUrl: https://www.microsoft.com/msixsdk/license +Localization: +- Agreements: + - Agreement: Text + AgreementLabel: Label + AgreementUrl: https://AgreementUrl.net + Author: Microsoft UK + Copyright: Copyright Microsoft Corporation UK + CopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK + Description: The MSIX SDK project is an effort to enable developers UK + License: MIT License UK + LicenseUrl: https://www.microsoft.com/msixsdk/license/UK + PackageLocale: en-GB + PackageName: MSIX SDK UK + PackageUrl: https://www.microsoft.com/msixsdk/home/UK + PrivacyUrl: https://www.microsoft.com/privacy/UK + Publisher: Microsoft UK + PublisherSupportUrl: https://www.microsoft.com/support/UK + PublisherUrl: https://www.microsoft.com/UK + ReleaseNotes: Release notes + ReleaseNotesUrl: https://ReleaseNotes.net + ShortDescription: This is MSIX SDK UK + Tags: + - appxsdkUK + - msixsdkUK +ManifestType: merged +ManifestVersion: 1.1.0 +Markets: + AllowedMarkets: + - US +MinimumOSVersion: 10.0.0.0 +Moniker: msixsdk +PackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe +PackageIdentifier: microsoft.msixsdk +PackageLocale: en-US +PackageName: MSIX SDK +PackageUrl: https://www.microsoft.com/msixsdk/home +PackageVersion: 1.7.32 +Platform: +- Windows.Desktop +- Windows.Universal +PrivacyUrl: https://www.microsoft.com/privacy +ProductCode: '{Foo}' +Protocols: +- protocol1 +- protocol2 +Publisher: Microsoft +PublisherSupportUrl: https://www.microsoft.com/support +PublisherUrl: https://www.microsoft.com +ReleaseDate: 2021-01-01 +ReleaseNotes: Default release notes +ReleaseNotesUrl: https://DefaultReleaseNotes.net +RequireExplicitUpgrade: true +RestrictedCapabilities: +- runFullTrust +Scope: machine +ShortDescription: This is MSIX SDK +Tags: +- appxsdk +- msixsdk +UnsupportedOSArchitectures: +- arm +UpgradeBehavior: uninstallPrevious diff --git a/src/WinGetUtilInterop.UnitTests/WinGetUtilInterop.UnitTests.csproj b/src/WinGetUtilInterop.UnitTests/WinGetUtilInterop.UnitTests.csproj @@ -0,0 +1,70 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netcoreapp3.1</TargetFramework> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.ApplicationInsights" Version="2.16.0" /> + <PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" /> + <PackageReference Include="Microsoft.Msix.Utils" Version="1.0.200918001" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> + <PackageReference Include="Moq" Version="4.15.2" /> + <PackageReference Include="xunit" Version="2.4.0" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> + <PackageReference Include="coverlet.collector" Version="1.2.0" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\WinGetUtilInterop\WinGetUtilInterop.csproj" /> + </ItemGroup> + + <ItemGroup> + <None Update="TestCollateral\AllEquality.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\AllEqualityWithDescription.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\DifferentId.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\OneInstaller.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\SomeEquality.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\SomeEqualityWithLocalization.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\SomeEqualityWithoutInstallers.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\SomeEqualityWithoutSwitches.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\V1ManifestInfoMissingRequiredPackageLocale.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\V1ManifestNoLocalization.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\V1ManifestMerged.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\V1_1ManifestMerged.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\Test_yaml_with_bom.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="TestCollateral\Test_yaml_without_bom.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Update="xunit.runner.json"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + </ItemGroup> + +</Project> diff --git a/src/WinGetUtilInterop/Build/Microsoft.WindowsPackageManager.Utils.targets b/src/WinGetUtilInterop/Build/Microsoft.WindowsPackageManager.Utils.targets @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<ItemGroup> + <WinGetDll Include="$(MSBuildThisFileDirectory)\..\runtimes\**\**\*.dll" /> +</ItemGroup> +<Target Name="CopyWingetUtilDlls"> + <Copy SourceFiles="@(WinGetDll)" DestinationFiles="@(WinGetDll->'$(PublishDir)\bin\runtimes\%(RecursiveDir)%(Filename)%(Extension)')" /> +</Target> +</Project> diff --git a/src/WinGetUtilInterop/Helpers/WinGetUtilWrapperManifest.cs b/src/WinGetUtilInterop/Helpers/WinGetUtilWrapperManifest.cs @@ -0,0 +1,77 @@ +// ----------------------------------------------------------------------- +// <copyright file="WinGetUtilWrapperManifest.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Helpers +{ + using System; + using System.Runtime.InteropServices; + + /// <summary> + /// Wrapper class around WinGetUtil manifest native implementation. + /// For dll entry points are defined here: + /// https://github.com/microsoft/winget-cli/blob/master/src/WinGetUtil/WinGetUtil.h. + /// </summary> + public sealed class WinGetUtilWrapperManifest + { + /// <summary> + /// The error from the installer. + /// Must be in sync with WinGetValidateManifestOption at: + /// https://github.com/microsoft/winget-cli/blob/master/src/WinGetUtil/WinGetUtil.h. + /// </summary> + public enum ValidateManifestOption + { + /// <summary> + /// Default validation behavior. + /// </summary> + Default, + + /// <summary> + /// Schema validation only. + /// </summary> + SchemaValidationOnly, + } + + /// <summary> + /// Validates the manifest is compliant. + /// </summary> + /// <param name="manifestPath">Manifest path.</param> + /// <param name="mergedManifestPath">Merged manifest output path.</param> + /// <param name="option">Desired validate manifest option.</param> + /// <returns>Message from manifest validation.</returns> + public static (bool isValid, string message) ValidateManifest( + string manifestPath, + string mergedManifestPath = null, + ValidateManifestOption option = ValidateManifestOption.Default) + { + WinGetValidateManifestV2( + manifestPath, + out bool succeeded, + out string failureOrWarningMessage, + mergedManifestPath, + option); + + return (succeeded, failureOrWarningMessage); + } + + /// <summary> + /// Validates a given manifest. Returns a bool for validation result and + /// a string representing validation errors if validation failed. + /// </summary> + /// <param name="manifestPath">Path to manifest file.</param> + /// <param name="succeeded">Out bool is validation succeeded.</param> + /// <param name="failureMessage">Out string failure message, if any.</param> + /// <param name="mergedManifestPath">Path to merged manifest file. Empty means no merged manifest needed.</param> + /// <param name="option">Validate manifest option.</param> + /// <returns>HRESULT.</returns> + [DllImport("WinGetUtil.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)] + private static extern IntPtr WinGetValidateManifestV2( + string manifestPath, + [MarshalAs(UnmanagedType.U1)] out bool succeeded, + [MarshalAs(UnmanagedType.BStr)] out string failureMessage, + string mergedManifestPath, + ValidateManifestOption option); + } +} diff --git a/src/WinGetUtilInterop/Manifest/Preview/InstallerSwitches.cs b/src/WinGetUtilInterop/Manifest/Preview/InstallerSwitches.cs @@ -0,0 +1,134 @@ +// ----------------------------------------------------------------------- +// <copyright file="InstallerSwitches.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.Preview +{ + using System; + using System.Runtime.CompilerServices; + + /// <summary> + /// Class that contains different types of installer switches like Default, Silent and Verbose. + /// </summary> + public class InstallerSwitches : IEquatable<InstallerSwitches> + { + /// <summary> + /// Gets or sets the Custom installer switch. + /// </summary> + public string Custom { get; set; } + + /// <summary> + /// Gets or sets the Silent installer switch. + /// </summary> + public string Silent { get; set; } + + /// <summary> + /// Gets or sets the SilentWithProgress installer switch. + /// </summary> + public string SilentWithProgress { get; set; } + + /// <summary> + /// Gets or sets the Interactive installer switch. + /// </summary> + public string Interactive { get; set; } + + /// <summary> + /// Gets or sets the Language installer switch. + /// </summary> + public string Language { get; set; } + + /// <summary> + /// Gets or sets the Log installer switch. + /// </summary> + public string Log { get; set; } + + /// <summary> + /// Gets or sets the install location switch. + /// </summary> + public string InstallLocation { get; set; } + + /// <summary> + /// Override op_Equality. + /// </summary> + /// <param name="lhs">left hand side.</param> + /// <param name="rhs">right hand side.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public static bool operator ==(InstallerSwitches lhs, InstallerSwitches rhs) + { + return Equals(lhs, rhs); + } + + /// <summary> + /// Override op_Inequality. + /// </summary> + /// <param name="lhs">left hand side.</param> + /// <param name="rhs">right hand side.</param> + /// <returns>boolean indicating if the objects are not equals.</returns> + public static bool operator !=(InstallerSwitches lhs, InstallerSwitches rhs) + { + return !Equals(lhs, rhs); + } + + /// <summary> + /// Override object.Equals. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public override bool Equals(object other) + { + return (other is InstallerSwitches) && this.Equals(other as InstallerSwitches); + } + + /// <summary> + /// Implemented IEquitable. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public bool Equals(InstallerSwitches other) + { + // If parameter is null, return false. + if (ReferenceEquals(other, null)) + { + return false; + } + + // Optimization for a common success case. + if (ReferenceEquals(this, other)) + { + return true; + } + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + { + return false; + } + + return (this.Custom == other.Custom) && + (this.Silent == other.Silent) && + (this.SilentWithProgress == other.SilentWithProgress) && + (this.Interactive == other.Interactive) && + (this.Language == other.Language) && + (this.Log == other.Log) && + (this.InstallLocation == other.InstallLocation); + } + + /// <summary> + /// Override object.GetHashCode. Implement if needed. + /// to create the hash. + /// </summary> + /// <returns>resulting hash.</returns> + public override int GetHashCode() + { + return (this.Custom, + this.Silent, + this.SilentWithProgress, + this.Interactive, + this.Language, + this.Log, + this.InstallLocation).GetHashCode(); + } + } +} diff --git a/src/WinGetUtilInterop/Manifest/Preview/Manifest.cs b/src/WinGetUtilInterop/Manifest/Preview/Manifest.cs @@ -0,0 +1,281 @@ +// ----------------------------------------------------------------------- +// <copyright file="Manifest.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.Preview +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using YamlDotNet.Serialization; + using YamlDotNet.Serialization.NamingConventions; + + /// <summary> + /// Class that defines the structure of the manifest. Uses YamlDotNet + /// to deserialize a string or a stream and produce a manifest object. + /// </summary> + public class Manifest + { + /// <summary> + /// Gets or sets the Id of the manifest. + /// </summary> + public string Id { get; set; } + + /// <summary> + /// Gets or sets the name of the package. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets or sets the version of the package. + /// </summary> + public string Version { get; set; } + + /// <summary> + /// Gets or sets the publisher. + /// </summary> + public string Publisher { get; set; } + + /// <summary> + /// Gets or sets the AppMoniker. + /// </summary> + public string AppMoniker { get; set; } + + /// <summary> + /// Gets or sets the Channel. + /// </summary> + public string Channel { get; set; } + + /// <summary> + /// Gets or sets the Author of package. + /// </summary> + public string Author { get; set; } + + /// <summary> + /// Gets or sets the License. + /// </summary> + public string License { get; set; } + + /// <summary> + /// Gets or sets the MinOSVersion. + /// </summary> + public string MinOSVersion { get; set; } + + /// <summary> + /// Gets or sets the Tags. Comma separated values. + /// </summary> + public string Tags { get; set; } + + /// <summary> + /// Gets or sets the Commands. Comma separated values. + /// </summary> + public string Commands { get; set; } + + /// <summary> + /// Gets or sets the Protocols. Comma separated values. + /// </summary> + public string Protocols { get; set; } + + /// <summary> + /// Gets or sets the FileExtensions. Comma separated values. + /// </summary> + public string FileExtensions { get; set; } + + /// <summary> + /// Gets or sets the InstallerType of the package. Must be one + /// of the values of ValidInstallerTypes. IManifestInstallerDefaults. + /// An InstallerType in the root of the manifest is required if + /// InstallerType is not defined in an ManifestInstaller entry. + /// </summary> + public string InstallerType { get; set; } + + /// <summary> + /// Gets or sets Description. IManifestLocalization. + /// </summary> + public string Description { get; set; } + + /// <summary> + /// Gets or sets Homepage. IManifestLocalization. + /// </summary> + public string Homepage { get; set; } + + /// <summary> + /// Gets or sets LicenseUrl. IManifestLocalization. + /// </summary> + public string LicenseUrl { get; set; } + + /// <summary> + /// Gets or sets InstallerSwitches. IManifestInstallerDefaults. + /// </summary> + public InstallerSwitches Switches { get; set; } + + /// <summary> + /// Gets or sets collection of ManifestInstaller. At least one is required. + /// </summary> + public List<ManifestInstaller> Installers { get; set; } + + /// <summary> + /// Gets or sets collection of ManifestLocalization. + /// </summary> + public List<ManifestLocalization> Localization { get; set; } + + /// <summary> + /// Gets or sets the manifest version. + /// </summary> + public string ManifestVersion { get; set; } + + /// <summary> + /// Deserialize a stream into a Manifest object. + /// </summary> + /// <param name="stream">Manifest stream.</param> + /// <returns>Manifest object populated and validated.</returns> + public static Manifest CreateManifestFromStream(Stream stream) + { + using (StreamReader streamReader = new StreamReader(stream)) + { + return Manifest.CreateManifestFromStreamReader(streamReader); + } + } + + /// <summary> + /// Deserialize a stream reader into a Manifest object. + /// </summary> + /// <param name="streamReader">stream reader.</param> + /// <returns>Manifest object populated and validated.</returns> + public static Manifest CreateManifestFromStreamReader(StreamReader streamReader) + { + streamReader.BaseStream.Seek(0, SeekOrigin.Begin); + var deserializer = CreateDeserializer(); + return deserializer.Deserialize<Manifest>(streamReader); + } + + /// <summary> + /// Deserialize a stream reader into a Manifest object. + /// </summary> + /// <param name="filePath">file path.</param> + /// <returns>Manifest object populated and validated.</returns> + public static Manifest CreateManifestFromPath(string filePath) + { + using (StreamReader streamReader = new StreamReader(filePath)) + { + return Manifest.CreateManifestFromStreamReader(streamReader); + } + } + + /// <summary> + /// Deserialize a string into a Manifest object. + /// </summary> + /// <param name="value">Manifest in string value.</param> + /// <returns>Manifest object populated and validated.</returns> + public static Manifest CreateManifestFromString(string value) + { + var deserializer = CreateDeserializer(); + return deserializer.Deserialize<Manifest>(value); + } + + /// <summary> + /// Returns a List of strings containing the URIs contained within this manifest. + /// </summary> + /// <returns>List of strings.</returns> + public List<string> GetURIs() + { + List<string> uris = new List<string>(); + if (!string.IsNullOrEmpty(this.Homepage)) + { + uris.Add(this.Homepage); + } + + if (!string.IsNullOrEmpty(this.LicenseUrl)) + { + uris.Add(this.LicenseUrl); + } + + foreach (ManifestInstaller installer in this.Installers) + { + if (!string.IsNullOrEmpty(installer.Url)) + { + uris.Add(installer.Url); + } + } + + if (this.Localization != null) + { + foreach (ManifestLocalization localization in this.Localization) + { + if (!string.IsNullOrEmpty(localization.LicenseUrl)) + { + uris.Add(localization.LicenseUrl); + } + + if (!string.IsNullOrEmpty(localization.Homepage)) + { + uris.Add(localization.Homepage); + } + } + } + + return uris; + } + + /// <summary> + /// Checks if two manifests are equivalent. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public bool IsManifestEquivalent(Manifest other) + { + // If parameter is null, return false. + if (ReferenceEquals(other, null)) + { + return false; + } + + // Optimization for a common success case. + if (ReferenceEquals(this, other)) + { + return true; + } + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + { + return false; + } + + // Equality of Manifest consist on only these properties. + return (this.Id == other.Id) && + (this.Version == other.Version) && + (this.Publisher == other.Publisher) && + (this.InstallerType == other.InstallerType) && + (this.Switches == other.Switches) && + this.CompareInstallers(other.Installers); + } + + /// <summary> + /// Helper to deserialize the manifest. + /// </summary> + /// <returns>IDeserializer object.</returns> + private static IDeserializer CreateDeserializer() + { + var deserializer = new DeserializerBuilder(). + WithNamingConvention(PascalCaseNamingConvention.Instance). + IgnoreUnmatchedProperties(); + return deserializer.Build(); + } + + private bool CompareInstallers(List<ManifestInstaller> installers) + { + ISet<ManifestInstaller> first = + new HashSet<ManifestInstaller>( + this.Installers != null ? + this.Installers : + new List<ManifestInstaller>()); + + return first.SetEquals(installers != null + ? installers : new List<ManifestInstaller>()); + } + } +} diff --git a/src/WinGetUtilInterop/Manifest/Preview/ManifestInstaller.cs b/src/WinGetUtilInterop/Manifest/Preview/ManifestInstaller.cs @@ -0,0 +1,121 @@ +// ----------------------------------------------------------------------- +// <copyright file="ManifestInstaller.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.Preview +{ + using System; + + /// <summary> + /// Class that contains the elements that represent what an installer element can contain in the manifest file. + /// </summary> + public class ManifestInstaller + { + /// <summary> + /// Gets or sets the architecture of the installer. Values: x86, x64, arm, arm64, all. + /// </summary> + public string Arch { get; set; } + + /// <summary> + /// Gets or sets the URL of the installer. + /// </summary> + public string Url { get; set; } + + /// <summary> + /// Gets or sets the SHA256 hash of the installer. Required element. + /// </summary> + public string Sha256 { get; set; } + + /// <summary> + /// Gets or sets the signature SHA256 for an appx/msix. Only used by appx/msix type. + /// </summary> + public string SignatureSha256 { get; set; } + + /// <summary> + /// Gets or sets the localization of the installer. Empty indicates default. + /// </summary> + public string Language { get; set; } + + /// <summary> + /// Gets or sets the scope. Name to be decided. + /// </summary> + public string Scope { get; set; } + + /// <summary> + /// Gets or sets the Store ProductId. Only used when InstallerType is MSStore. + /// </summary> + public string ProductId { get; set; } + + /// <summary> + /// Gets or sets the installer type. If present, has more precedence than root. + /// </summary> + public string InstallerType { get; set; } + + /// <summary> + /// Gets or sets the installer switches. If present, has more precedence than root. + /// </summary> + public InstallerSwitches Switches { get; set; } + + /// <summary> + /// Override object.Equals. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public override bool Equals(object other) + { + return (other is ManifestInstaller) && this.Equals(other as ManifestInstaller); + } + + /// <summary> + /// Implemented IEquitable. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public bool Equals(ManifestInstaller other) + { + // If parameter is null, return false. + if (ReferenceEquals(other, null)) + { + return false; + } + + // Optimization for a common success case. + if (ReferenceEquals(this, other)) + { + return true; + } + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + { + return false; + } + + return (this.Arch == other.Arch) && + (this.Url == other.Url) && + (this.Sha256 == other.Sha256) && + (this.SignatureSha256 == other.SignatureSha256) && + (this.Language == other.Language) && + (this.Scope == other.Scope) && + (this.InstallerType == other.InstallerType) && + (this.Switches == other.Switches); + } + + /// <summary> + /// Override object.GetHashCode. + /// </summary> + /// <returns>resulting hash.</returns> + public override int GetHashCode() + { + return (this.Arch, + this.Url, + this.SignatureSha256, + this.Language, + this.Scope, + this.InstallerType, + this.Switches).GetHashCode(); + } + } +} diff --git a/src/WinGetUtilInterop/Manifest/Preview/ManifestLocalization.cs b/src/WinGetUtilInterop/Manifest/Preview/ManifestLocalization.cs @@ -0,0 +1,34 @@ +// ----------------------------------------------------------------------- +// <copyright file="ManifestLocalization.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.Preview +{ + /// <summary> + /// Class that contains the elements that represent what a manifest localization element can contain in the manifest file. + /// </summary> + public class ManifestLocalization + { + /// <summary> + /// Gets or sets the localization type of manifest. Required element. + /// </summary> + public string Language { get; set; } + + /// <summary> + /// Gets or sets the description of the manifest. + /// </summary> + public string Description { get; set; } + + /// <summary> + /// Gets or sets the homepage related to the package. + /// </summary> + public string Homepage { get; set; } + + /// <summary> + /// Gets or sets the license URL. + /// </summary> + public string LicenseUrl { get; set; } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/InstallerArpEntry.cs b/src/WinGetUtilInterop/Manifest/V1/InstallerArpEntry.cs @@ -0,0 +1,44 @@ +// ----------------------------------------------------------------------- +// <copyright file="InstallerArpEntry.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + /// <summary> + /// Class that contains installer arp entry. + /// </summary> + public class InstallerArpEntry + { + /// <summary> + /// Gets or sets the display name. + /// </summary> + public string DisplayName { get; set; } + + /// <summary> + /// Gets or sets the publisher. + /// </summary> + public string Publisher { get; set; } + + /// <summary> + /// Gets or sets the display version. + /// </summary> + public string DisplayVersion { get; set; } + + /// <summary> + /// Gets or sets the ProductCode. + /// </summary> + public string ProductCode { get; set; } + + /// <summary> + /// Gets or sets the UpgradeCode. + /// </summary> + public string UpgradeCode { get; set; } + + /// <summary> + /// Gets or sets the installer type. + /// </summary> + public string InstallerType { get; set; } + } +}+ \ No newline at end of file diff --git a/src/WinGetUtilInterop/Manifest/V1/InstallerDependency.cs b/src/WinGetUtilInterop/Manifest/V1/InstallerDependency.cs @@ -0,0 +1,37 @@ +// ----------------------------------------------------------------------- +// <copyright file="InstallerDependency.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + using System; + using System.Collections.Generic; + + /// <summary> + /// Class that contains different dependencies of installer. + /// </summary> + public class InstallerDependency + { + /// <summary> + /// Gets or sets the windows features installer depends on. + /// </summary> + public List<string> WindowsFeatures { get; set; } + + /// <summary> + /// Gets or sets the windows libraries installer depends on. + /// </summary> + public List<string> WindowsLibraries { get; set; } + + /// <summary> + /// Gets or sets the package dependencies under same source. + /// </summary> + public List<InstallerPackageDependency> PackageDependencies { get; set; } + + /// <summary> + /// Gets or sets the external dependencies installer depends on. + /// </summary> + public List<string> ExternalDependencies { get; set; } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/InstallerExpectedReturnCode.cs b/src/WinGetUtilInterop/Manifest/V1/InstallerExpectedReturnCode.cs @@ -0,0 +1,24 @@ +// ----------------------------------------------------------------------- +// <copyright file="InstallerExpectedReturnCode.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + /// <summary> + /// Class that contains installer expected return code. + /// </summary> + public class InstallerExpectedReturnCode + { + /// <summary> + /// Gets or sets the installer return code. + /// </summary> + public long InstallerReturnCode { get; set; } + + /// <summary> + /// Gets or sets the corresponding response category. + /// </summary> + public string ReturnResponse { get; set; } + } +}+ \ No newline at end of file diff --git a/src/WinGetUtilInterop/Manifest/V1/InstallerMarkets.cs b/src/WinGetUtilInterop/Manifest/V1/InstallerMarkets.cs @@ -0,0 +1,26 @@ +// ----------------------------------------------------------------------- +// <copyright file="InstallerMarkets.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + using System.Collections.Generic; + + /// <summary> + /// Class that contains installer markets. + /// </summary> + public class InstallerMarkets + { + /// <summary> + /// Gets or sets the list of allowed markets. + /// </summary> + public List<string> AllowedMarkets { get; set; } + + /// <summary> + /// Gets or sets the list of excluded markets. + /// </summary> + public List<string> ExcludedMarkets { get; set; } + } +}+ \ No newline at end of file diff --git a/src/WinGetUtilInterop/Manifest/V1/InstallerPackageDependency.cs b/src/WinGetUtilInterop/Manifest/V1/InstallerPackageDependency.cs @@ -0,0 +1,26 @@ +// ----------------------------------------------------------------------- +// <copyright file="InstallerPackageDependency.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + using System; + + /// <summary> + /// Class that contains package dependency from same source. + /// </summary> + public class InstallerPackageDependency + { + /// <summary> + /// Gets or sets the dependency package identifier. + /// </summary> + public string PackageIdentifier { get; set; } + + /// <summary> + /// Gets or sets the minimum version of the dependency package. + /// </summary> + public string MinimumVersion { get; set; } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/InstallerSwitches.cs b/src/WinGetUtilInterop/Manifest/V1/InstallerSwitches.cs @@ -0,0 +1,133 @@ +// ----------------------------------------------------------------------- +// <copyright file="InstallerSwitches.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + using System; + + /// <summary> + /// Class that contains different types of installer switches like Custom, Silent and Interactive. + /// </summary> + public class InstallerSwitches : IEquatable<InstallerSwitches> + { + /// <summary> + /// Gets or sets the Custom installer switch. + /// </summary> + public string Custom { get; set; } + + /// <summary> + /// Gets or sets the Silent installer switch. + /// </summary> + public string Silent { get; set; } + + /// <summary> + /// Gets or sets the SilentWithProgress installer switch. + /// </summary> + public string SilentWithProgress { get; set; } + + /// <summary> + /// Gets or sets the Interactive installer switch. + /// </summary> + public string Interactive { get; set; } + + /// <summary> + /// Gets or sets the Upgrade installer switch. + /// </summary> + public string Upgrade { get; set; } + + /// <summary> + /// Gets or sets the Log installer switch. + /// </summary> + public string Log { get; set; } + + /// <summary> + /// Gets or sets the install location switch. + /// </summary> + public string InstallLocation { get; set; } + + /// <summary> + /// Override op_Equality. + /// </summary> + /// <param name="lhs">left hand side.</param> + /// <param name="rhs">right hand side.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public static bool operator ==(InstallerSwitches lhs, InstallerSwitches rhs) + { + return Equals(lhs, rhs); + } + + /// <summary> + /// Override op_Inequality. + /// </summary> + /// <param name="lhs">left hand side.</param> + /// <param name="rhs">right hand side.</param> + /// <returns>boolean indicating if the objects are not equals.</returns> + public static bool operator !=(InstallerSwitches lhs, InstallerSwitches rhs) + { + return !Equals(lhs, rhs); + } + + /// <summary> + /// Override object.Equals. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public override bool Equals(object other) + { + return (other is InstallerSwitches) && this.Equals(other as InstallerSwitches); + } + + /// <summary> + /// Implemented IEquitable. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public bool Equals(InstallerSwitches other) + { + // If parameter is null, return false. + if (ReferenceEquals(other, null)) + { + return false; + } + + // Optimization for a common success case. + if (ReferenceEquals(this, other)) + { + return true; + } + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + { + return false; + } + + return (this.Custom == other.Custom) && + (this.Silent == other.Silent) && + (this.SilentWithProgress == other.SilentWithProgress) && + (this.Interactive == other.Interactive) && + (this.Upgrade == other.Upgrade) && + (this.Log == other.Log) && + (this.InstallLocation == other.InstallLocation); + } + + /// <summary> + /// Override object.GetHashCode. Implement if needed. + /// to create the hash. + /// </summary> + /// <returns>resulting hash.</returns> + public override int GetHashCode() + { + return (this.Custom, + this.Silent, + this.SilentWithProgress, + this.Interactive, + this.Upgrade, + this.Log, + this.InstallLocation).GetHashCode(); + } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs @@ -0,0 +1,466 @@ +// ----------------------------------------------------------------------- +// <copyright file="Manifest.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using YamlDotNet.Serialization; + using YamlDotNet.Serialization.NamingConventions; + + /// <summary> + /// Class that defines the structure of the manifest. Uses YamlDotNet + /// to deserialize a string or a stream and produce a manifest object. + /// </summary> + public class Manifest + { + /// <summary> + /// Gets or sets the Id of the package. + /// </summary> + [YamlMember(Alias ="PackageIdentifier")] + public string Id { get; set; } + + /// <summary> + /// Gets or sets the version of the package. + /// </summary> + [YamlMember(Alias = "PackageVersion")] + public string Version { get; set; } + + /// <summary> + /// Gets or sets the manifest type. + /// </summary> + public string ManifestType { get; set; } + + /// <summary> + /// Gets or sets the manifest version. + /// </summary> + public string ManifestVersion { get; set; } + + /// <summary> + /// Gets or sets the Channel. + /// </summary> + public string Channel { get; set; } + + // Localization fields + + /// <summary> + /// Gets or sets the AppMoniker. + /// </summary> + public string Moniker { get; set; } + + /// <summary> + /// Gets or sets the default locale. + /// </summary> + public string PackageLocale { get; set; } + + /// <summary> + /// Gets or sets the publisher in default locale. + /// </summary> + public string Publisher { get; set; } + + /// <summary> + /// Gets or sets the publisher url in default locale. + /// </summary> + public string PublisherUrl { get; set; } + + /// <summary> + /// Gets or sets the publisher support url in default locale. + /// </summary> + public string PublisherSupportUrl { get; set; } + + /// <summary> + /// Gets or sets the default privacy url. + /// </summary> + public string PrivacyUrl { get; set; } + + /// <summary> + /// Gets or sets the author in default locale. + /// </summary> + public string Author { get; set; } + + /// <summary> + /// Gets or sets the package name in default locale. + /// </summary> + public string PackageName { get; set; } + + /// <summary> + /// Gets or sets the package homepage url in default locale. + /// </summary> + public string PackageUrl { get; set; } + + /// <summary> + /// Gets or sets the license in default locale. + /// </summary> + public string License { get; set; } + + /// <summary> + /// Gets or sets the license url in default locale. + /// </summary> + public string LicenseUrl { get; set; } + + /// <summary> + /// Gets or sets the copyright in default locale. + /// </summary> + public string Copyright { get; set; } + + /// <summary> + /// Gets or sets the copyright url in default locale. + /// </summary> + public string CopyrightUrl { get; set; } + + /// <summary> + /// Gets or sets the the package short description in default locale. + /// </summary> + public string ShortDescription { get; set; } + + /// <summary> + /// Gets or sets the package description in default locale. + /// </summary> + public string Description { get; set; } + + /// <summary> + /// Gets or sets the Tags in default locale. + /// </summary> + public List<string> Tags { get; set; } + + /// <summary> + /// Gets or sets the package agreements in default locale. + /// </summary> + public List<PackageAgreement> Agreements { get; set; } + + /// <summary> + /// Gets or sets the release notes in default locale. + /// </summary> + public string ReleaseNotes { get; set; } + + /// <summary> + /// Gets or sets the release notes url in default locale. + /// </summary> + public string ReleaseNotesUrl { get; set; } + + // Installer fields + + /// <summary> + /// Gets or sets the default installer locale. + /// </summary> + public string InstallerLocale { get; set; } + + /// <summary> + /// Gets or sets the default list of supported platforms. + /// </summary> + public List<string> Platform { get; set; } + + /// <summary> + /// Gets or sets the default minimum OS version. + /// </summary> + public string MinimumOSVersion { get; set; } + + /// <summary> + /// Gets or sets the default installer type. + /// </summary> + public string InstallerType { get; set; } + + /// <summary> + /// Gets or sets the default installer scope. + /// </summary> + public string Scope { get; set; } + + /// <summary> + /// Gets or sets the default list of install modes. + /// </summary> + public List<string> InstallModes { get; set; } + + /// <summary> + /// Gets or sets the default list of additional installer success codes. + /// </summary> + public List<long> InstallerSuccessCodes { get; set; } + + /// <summary> + /// Gets or sets the default upgrade behavior. + /// </summary> + public string UpgradeBehavior { get; set; } + + /// <summary> + /// Gets or sets the default list of commands. + /// </summary> + public List<string> Commands { get; set; } + + /// <summary> + /// Gets or sets the default list of supported protocols. + /// </summary> + public List<string> Protocols { get; set; } + + /// <summary> + /// Gets or sets the default list of supported file extensions. + /// </summary> + public List<string> FileExtensions { get; set; } + + /// <summary> + /// Gets or sets the default package family name for msix packaged installers. + /// </summary> + public string PackageFamilyName { get; set; } + + /// <summary> + /// Gets or sets default product code for ARP (Add/Remove Programs) installers. + /// </summary> + public string ProductCode { get; set; } + + /// <summary> + /// Gets or sets the default list of capabilities. For msix only. + /// </summary> + public List<string> Capabilities { get; set; } + + /// <summary> + /// Gets or sets the default list of restricted capabilities. For msix only. + /// </summary> + public List<string> RestrictedCapabilities { get; set; } + + /// <summary> + /// Gets or sets the default installer dependency. + /// </summary> + public InstallerDependency Dependencies { get; set; } + + /// <summary> + /// Gets or sets the default installer switches. + /// </summary> + [YamlMember(Alias = "InstallerSwitches")] + public InstallerSwitches Switches { get; set; } + + /// <summary> + /// Gets or sets the default installer markets info. + /// </summary> + public InstallerMarkets Markets { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the default installer behavior aborts terminal. + /// </summary> + public bool InstallerAbortsTerminal { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the default installer behavior requires explicit install location. + /// </summary> + public bool InstallLocationRequired { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the default installer behavior requires explicit upgrade. + /// </summary> + public bool RequireExplicitUpgrade { get; set; } + + /// <summary> + /// Gets or sets the default installer release date. + /// </summary> + public string ReleaseDate { get; set; } + + /// <summary> + /// Gets or sets the default list of unsupported OS architectures. + /// </summary> + public List<string> UnsupportedOSArchitectures { get; set; } + + /// <summary> + /// Gets or sets the default list of apps and features entries. + /// </summary> + public List<InstallerArpEntry> AppsAndFeaturesEntries { get; set; } + + /// <summary> + /// Gets or sets the default installer elevation requirement. + /// </summary> + public string ElevationRequirement { get; set; } + + /// <summary> + /// Gets or sets the default list of installer expected return codes. + /// </summary> + public List<InstallerExpectedReturnCode> ExpectedReturnCodes { get; set; } + + /// <summary> + /// Gets or sets collection of ManifestInstaller. At least one is required. + /// </summary> + public List<ManifestInstaller> Installers { get; set; } + + /// <summary> + /// Gets or sets collection of additional ManifestLocalization. + /// </summary> + public List<ManifestLocalization> Localization { get; set; } + + /// <summary> + /// Deserialize a stream reader into a Manifest object. + /// </summary> + /// <param name="filePath">file path.</param> + /// <returns>Manifest object populated and validated.</returns> + public static Manifest CreateManifestFromPath(string filePath) + { + using (StreamReader streamReader = new StreamReader(filePath)) + { + return Manifest.CreateManifestFromStreamReader(streamReader); + } + } + + /// <summary> + /// Deserialize a stream into a Manifest object. + /// </summary> + /// <param name="stream">Manifest stream.</param> + /// <returns>Manifest object populated and validated.</returns> + public static Manifest CreateManifestFromStream(Stream stream) + { + using (StreamReader streamReader = new StreamReader(stream)) + { + return Manifest.CreateManifestFromStreamReader(streamReader); + } + } + + /// <summary> + /// Deserialize a stream reader into a Manifest object. + /// </summary> + /// <param name="streamReader">stream reader.</param> + /// <returns>Manifest object populated and validated.</returns> + public static Manifest CreateManifestFromStreamReader(StreamReader streamReader) + { + streamReader.BaseStream.Seek(0, SeekOrigin.Begin); + var deserializer = CreateDeserializer(); + return deserializer.Deserialize<Manifest>(streamReader); + } + + /// <summary> + /// Deserialize a string into a Manifest object. + /// </summary> + /// <param name="value">Manifest in string value.</param> + /// <returns>Manifest object populated and validated.</returns> + public static Manifest CreateManifestFromString(string value) + { + var deserializer = CreateDeserializer(); + return deserializer.Deserialize<Manifest>(value); + } + + /// <summary> + /// Returns a List of strings containing the URIs contained within this manifest. + /// </summary> + /// <returns>List of strings.</returns> + public List<string> GetURIs() + { + List<string> uris = new List<string>(); + if (!string.IsNullOrEmpty(this.PublisherUrl)) + { + uris.Add(this.PublisherUrl); + } + + if (!string.IsNullOrEmpty(this.PublisherSupportUrl)) + { + uris.Add(this.PublisherSupportUrl); + } + + if (!string.IsNullOrEmpty(this.PrivacyUrl)) + { + uris.Add(this.PrivacyUrl); + } + + if (!string.IsNullOrEmpty(this.PackageUrl)) + { + uris.Add(this.PackageUrl); + } + + if (!string.IsNullOrEmpty(this.LicenseUrl)) + { + uris.Add(this.LicenseUrl); + } + + if (!string.IsNullOrEmpty(this.CopyrightUrl)) + { + uris.Add(this.CopyrightUrl); + } + + if (!string.IsNullOrEmpty(this.ReleaseNotesUrl)) + { + uris.Add(this.ReleaseNotesUrl); + } + + if (this.Agreements != null) + { + foreach (var agreement in this.Agreements) + { + if (!string.IsNullOrEmpty(agreement.AgreementUrl)) + { + uris.Add(agreement.AgreementUrl); + } + } + } + + foreach (ManifestInstaller installer in this.Installers) + { + uris.AddRange(installer.GetURIs()); + } + + if (this.Localization != null) + { + foreach (ManifestLocalization localization in this.Localization) + { + uris.AddRange(localization.GetURIs()); + } + } + + return uris; + } + + /// <summary> + /// Checks if two manifests are equivalent. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public bool IsManifestEquivalent(Manifest other) + { + // If parameter is null, return false. + if (ReferenceEquals(other, null)) + { + return false; + } + + // Optimization for a common success case. + if (ReferenceEquals(this, other)) + { + return true; + } + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + { + return false; + } + + // Equality of Manifest consist on only these properties. + return (this.Id == other.Id) && + (this.Version == other.Version) && + (this.InstallerLocale == other.InstallerLocale) && + (this.Scope == other.Scope) && + (this.InstallerType == other.InstallerType) && + (this.Switches == other.Switches) && + this.CompareInstallers(other.Installers); + } + + /// <summary> + /// Helper to deserialize the manifest. + /// </summary> + /// <returns>IDeserializer object.</returns> + private static IDeserializer CreateDeserializer() + { + var deserializer = new DeserializerBuilder(). + WithNamingConvention(PascalCaseNamingConvention.Instance). + IgnoreUnmatchedProperties(); + return deserializer.Build(); + } + + private bool CompareInstallers(List<ManifestInstaller> installers) + { + ISet<ManifestInstaller> first = + new HashSet<ManifestInstaller>( + this.Installers != null ? + this.Installers : + new List<ManifestInstaller>()); + + return first.SetEquals(installers != null + ? installers : new List<ManifestInstaller>()); + } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs b/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs @@ -0,0 +1,248 @@ +// ----------------------------------------------------------------------- +// <copyright file="ManifestInstaller.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + using System; + using System.Collections.Generic; + using YamlDotNet.Serialization; + + /// <summary> + /// Class that contains the elements that represent what an installer element can contain in the manifest file. + /// </summary> + public class ManifestInstaller + { + /// <summary> + /// Gets or sets the architecture of the installer. Values: x86, x64, arm, arm64, neutral. + /// </summary> + [YamlMember(Alias = "Architecture")] + public string Arch { get; set; } + + /// <summary> + /// Gets or sets the URL of the installer. + /// </summary> + [YamlMember(Alias = "InstallerUrl")] + public string Url { get; set; } + + /// <summary> + /// Gets or sets the SHA256 hash of the installer. Required element. + /// </summary> + [YamlMember(Alias = "InstallerSha256")] + public string Sha256 { get; set; } + + /// <summary> + /// Gets or sets the signature SHA256 for an appx/msix. Only used by appx/msix type. + /// </summary> + public string SignatureSha256 { get; set; } + + /// <summary> + /// Gets or sets the installer locale. + /// </summary> + public string InstallerLocale { get; set; } + + /// <summary> + /// Gets or sets the list of supported platforms. + /// </summary> + public List<string> Platform { get; set; } + + /// <summary> + /// Gets or sets the minimum OS version. + /// </summary> + public string MinimumOSVersion { get; set; } + + /// <summary> + /// Gets or sets the installer type. If present, has more precedence than root. + /// </summary> + public string InstallerType { get; set; } + + /// <summary> + /// Gets or sets the installer scope. + /// </summary> + public string Scope { get; set; } + + /// <summary> + /// Gets or sets the list of install modes. + /// </summary> + public List<string> InstallModes { get; set; } + + /// <summary> + /// Gets or sets the list of additional installer success codes. + /// </summary> + public List<long> InstallerSuccessCodes { get; set; } + + /// <summary> + /// Gets or sets the upgrade behavior. + /// </summary> + public string UpgradeBehavior { get; set; } + + /// <summary> + /// Gets or sets the list of commands. + /// </summary> + public List<string> Commands { get; set; } + + /// <summary> + /// Gets or sets the list of supported protocols. + /// </summary> + public List<string> Protocols { get; set; } + + /// <summary> + /// Gets or sets the list of supported file extensions. + /// </summary> + public List<string> FileExtensions { get; set; } + + /// <summary> + /// Gets or sets the package family name for msix packaged installers. + /// </summary> + public string PackageFamilyName { get; set; } + + /// <summary> + /// Gets or sets product code for ARP (Add/Remove Programs) installers. + /// </summary> + public string ProductCode { get; set; } + + /// <summary> + /// Gets or sets the list of capabilities. For msix only. + /// </summary> + public List<string> Capabilities { get; set; } + + /// <summary> + /// Gets or sets the list of restricted capabilities. For msix only. + /// </summary> + public List<string> RestrictedCapabilities { get; set; } + + /// <summary> + /// Gets or sets the installer dependency. + /// </summary> + public InstallerDependency Dependencies { get; set; } + + /// <summary> + /// Gets or sets the installer switches. If present, has more precedence than root. + /// </summary> + [YamlMember(Alias = "InstallerSwitches")] + public InstallerSwitches Switches { get; set; } + + /// <summary> + /// Gets or sets the installer markets info. + /// </summary> + public InstallerMarkets Markets { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the installer behavior aborts terminal. + /// </summary> + public bool InstallerAbortsTerminal { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the installer behavior requires explicit install location. + /// </summary> + public bool InstallLocationRequired { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the installer behavior requires explicit upgrade. + /// </summary> + public bool RequireExplicitUpgrade { get; set; } + + /// <summary> + /// Gets or sets the installer release date. + /// </summary> + public string ReleaseDate { get; set; } + + /// <summary> + /// Gets or sets the list of unsupported OS architectures. + /// </summary> + public List<string> UnsupportedOSArchitectures { get; set; } + + /// <summary> + /// Gets or sets the list of apps and features entries. + /// </summary> + public List<InstallerArpEntry> AppsAndFeaturesEntries { get; set; } + + /// <summary> + /// Gets or sets the installer elevation requirement. + /// </summary> + public string ElevationRequirement { get; set; } + + /// <summary> + /// Gets or sets the list of installer expected return codes. + /// </summary> + public List<InstallerExpectedReturnCode> ExpectedReturnCodes { get; set; } + + /// <summary> + /// Returns a List of strings containing the URIs contained within this installer. + /// </summary> + /// <returns>List of strings.</returns> + public List<string> GetURIs() + { + List<string> uris = new List<string>(); + if (!string.IsNullOrEmpty(this.Url)) + { + uris.Add(this.Url); + } + + return uris; + } + + /// <summary> + /// Override object.Equals. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public override bool Equals(object other) + { + return (other is ManifestInstaller) && this.Equals(other as ManifestInstaller); + } + + /// <summary> + /// Implemented IEquitable. + /// </summary> + /// <param name="other">other object.</param> + /// <returns>boolean indicating if the objects are equals.</returns> + public bool Equals(ManifestInstaller other) + { + // If parameter is null, return false. + if (ReferenceEquals(other, null)) + { + return false; + } + + // Optimization for a common success case. + if (ReferenceEquals(this, other)) + { + return true; + } + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + { + return false; + } + + return (this.Arch == other.Arch) && + (this.Url == other.Url) && + (this.Sha256 == other.Sha256) && + (this.SignatureSha256 == other.SignatureSha256) && + (this.InstallerLocale == other.InstallerLocale) && + (this.Scope == other.Scope) && + (this.InstallerType == other.InstallerType) && + (this.Switches == other.Switches); + } + + /// <summary> + /// Override object.GetHashCode. + /// </summary> + /// <returns>resulting hash.</returns> + public override int GetHashCode() + { + return (this.Arch, + this.Url, + this.Sha256, + this.SignatureSha256, + this.InstallerLocale, + this.Scope, + this.InstallerType, + this.Switches).GetHashCode(); + } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/ManifestLocalization.cs b/src/WinGetUtilInterop/Manifest/V1/ManifestLocalization.cs @@ -0,0 +1,162 @@ +// ----------------------------------------------------------------------- +// <copyright file="ManifestLocalization.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + using System.Collections.Generic; + + /// <summary> + /// Class that contains the elements that represent what a manifest localization element can contain in the manifest file. + /// </summary> + public class ManifestLocalization + { + /// <summary> + /// Gets or sets the locale. + /// </summary> + public string PackageLocale { get; set; } + + /// <summary> + /// Gets or sets the publisher. + /// </summary> + public string Publisher { get; set; } + + /// <summary> + /// Gets or sets the publisher url. + /// </summary> + public string PublisherUrl { get; set; } + + /// <summary> + /// Gets or sets the publisher support url. + /// </summary> + public string PublisherSupportUrl { get; set; } + + /// <summary> + /// Gets or sets the default privacy url. + /// </summary> + public string PrivacyUrl { get; set; } + + /// <summary> + /// Gets or sets the author. + /// </summary> + public string Author { get; set; } + + /// <summary> + /// Gets or sets the package name. + /// </summary> + public string PackageName { get; set; } + + /// <summary> + /// Gets or sets the package homepage url. + /// </summary> + public string PackageUrl { get; set; } + + /// <summary> + /// Gets or sets the license. + /// </summary> + public string License { get; set; } + + /// <summary> + /// Gets or sets the license url. + /// </summary> + public string LicenseUrl { get; set; } + + /// <summary> + /// Gets or sets the copyright. + /// </summary> + public string Copyright { get; set; } + + /// <summary> + /// Gets or sets the copyright url. + /// </summary> + public string CopyrightUrl { get; set; } + + /// <summary> + /// Gets or sets the the package short description. + /// </summary> + public string ShortDescription { get; set; } + + /// <summary> + /// Gets or sets the package description. + /// </summary> + public string Description { get; set; } + + /// <summary> + /// Gets or sets the Tags. + /// </summary> + public List<string> Tags { get; set; } + + /// <summary> + /// Gets or sets the package agreements. + /// </summary> + public List<PackageAgreement> Agreements { get; set; } + + /// <summary> + /// Gets or sets the release notes. + /// </summary> + public string ReleaseNotes { get; set; } + + /// <summary> + /// Gets or sets the release notes url. + /// </summary> + public string ReleaseNotesUrl { get; set; } + + /// <summary> + /// Returns a List of strings containing the URIs contained within this localization. + /// </summary> + /// <returns>List of strings.</returns> + public List<string> GetURIs() + { + List<string> uris = new List<string>(); + if (!string.IsNullOrEmpty(this.PublisherUrl)) + { + uris.Add(this.PublisherUrl); + } + + if (!string.IsNullOrEmpty(this.PublisherSupportUrl)) + { + uris.Add(this.PublisherSupportUrl); + } + + if (!string.IsNullOrEmpty(this.PrivacyUrl)) + { + uris.Add(this.PrivacyUrl); + } + + if (!string.IsNullOrEmpty(this.PackageUrl)) + { + uris.Add(this.PackageUrl); + } + + if (!string.IsNullOrEmpty(this.LicenseUrl)) + { + uris.Add(this.LicenseUrl); + } + + if (!string.IsNullOrEmpty(this.CopyrightUrl)) + { + uris.Add(this.CopyrightUrl); + } + + if (!string.IsNullOrEmpty(this.ReleaseNotesUrl)) + { + uris.Add(this.ReleaseNotesUrl); + } + + if (this.Agreements != null) + { + foreach (var agreement in this.Agreements) + { + if (!string.IsNullOrEmpty(agreement.AgreementUrl)) + { + uris.Add(agreement.AgreementUrl); + } + } + } + + return uris; + } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/MinManifestInfo.cs b/src/WinGetUtilInterop/Manifest/V1/MinManifestInfo.cs @@ -0,0 +1,158 @@ +// ----------------------------------------------------------------------- +// <copyright file="MinManifestInfo.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + using System; + using System.IO; + using YamlDotNet.Serialization; + using YamlDotNet.Serialization.NamingConventions; + + /// <summary> + /// Class that contains minimum manifest info for each single manifest in a multi file manifest. + /// Used in validation pipeline to check multi file manifest consistency. + /// </summary> + public class MinManifestInfo + { + private const string ManifestTypeSingleton = "singleton"; + private const string ManifestTypeLocale = "locale"; + private const string ManifestTypeDefaultLocale = "defaultLocale"; + + private const string ValidationErrorMissingField = "Manifest file missing required field: "; + private const string ValidationErrorFailedManifestCreation = "Failed to create Manifest object from manifest file."; + + /// <summary> + /// Gets or sets the Id of the package. + /// </summary> + [YamlMember(Alias = "PackageIdentifier")] + public string Id { get; set; } + + /// <summary> + /// Gets or sets the version of the package. + /// </summary> + [YamlMember(Alias = "PackageVersion")] + public string Version { get; set; } + + /// <summary> + /// Gets or sets the manifest type. + /// </summary> + public string ManifestType { get; set; } + + /// <summary> + /// Gets or sets the manifest version. + /// </summary> + public string ManifestVersion { get; set; } + + /// <summary> + /// Gets or sets the package locale. Used in locale manifest in a multi file manifest. + /// </summary> + public string PackageLocale { get; set; } + + /// <summary> + /// Deserialize a stream reader into a Manifest object. + /// </summary> + /// <param name="filePath">file path.</param> + /// <returns>Manifest object populated and validated.</returns> + public static MinManifestInfo CreateManifestInfoFromPath(string filePath) + { + using (StreamReader streamReader = new StreamReader(filePath)) + { + return MinManifestInfo.CreateManifestInfoFromStreamReader(streamReader); + } + } + + /// <summary> + /// Deserialize a stream into a Manifest object. + /// </summary> + /// <param name="stream">Manifest stream.</param> + /// <returns>Manifest object populated and validated.</returns> + public static MinManifestInfo CreateManifestInfoFromStream(Stream stream) + { + using (StreamReader streamReader = new StreamReader(stream)) + { + return MinManifestInfo.CreateManifestInfoFromStreamReader(streamReader); + } + } + + /// <summary> + /// Deserialize a stream reader into a Manifest object. + /// </summary> + /// <param name="streamReader">stream reader.</param> + /// <returns>Manifest object populated and validated.</returns> + public static MinManifestInfo CreateManifestInfoFromStreamReader(StreamReader streamReader) + { + streamReader.BaseStream.Seek(0, SeekOrigin.Begin); + var deserializer = CreateDeserializer(); + var result = deserializer.Deserialize<MinManifestInfo>(streamReader); + ValidateManifestInfo(result); + return result; + } + + /// <summary> + /// Deserialize a string into a Manifest object. + /// </summary> + /// <param name="value">Manifest in string value.</param> + /// <returns>Manifest object populated and validated.</returns> + public static MinManifestInfo CreateManifestInfoFromString(string value) + { + var deserializer = CreateDeserializer(); + var result = deserializer.Deserialize<MinManifestInfo>(value); + ValidateManifestInfo(result); + return result; + } + + /// <summary> + /// Helper to deserialize the manifest. + /// </summary> + /// <returns>IDeserializer object.</returns> + private static IDeserializer CreateDeserializer() + { + var deserializer = new DeserializerBuilder(). + WithNamingConvention(PascalCaseNamingConvention.Instance). + IgnoreUnmatchedProperties(); + return deserializer.Build(); + } + + /// <summary> + /// Validate manifest info integrity. + /// </summary> + private static void ValidateManifestInfo(MinManifestInfo manifestInfo) + { + if (manifestInfo == null) + { + throw new InvalidDataException(ValidationErrorFailedManifestCreation); + } + + if (string.IsNullOrEmpty(manifestInfo.Id)) + { + throw new InvalidDataException(ValidationErrorMissingField + "PackageIdentifier"); + } + + if (string.IsNullOrEmpty(manifestInfo.Version)) + { + throw new InvalidDataException(ValidationErrorMissingField + "PackageVersion"); + } + + if (string.IsNullOrEmpty(manifestInfo.ManifestType)) + { + throw new InvalidDataException(ValidationErrorMissingField + "ManifestType"); + } + + if (string.IsNullOrEmpty(manifestInfo.ManifestVersion)) + { + throw new InvalidDataException(ValidationErrorMissingField + "ManifestVersion"); + } + + if (string.IsNullOrEmpty(manifestInfo.PackageLocale) && + (manifestInfo.ManifestType == ManifestTypeDefaultLocale || + manifestInfo.ManifestType == ManifestTypeLocale || + manifestInfo.ManifestType == ManifestTypeSingleton)) + { + throw new InvalidDataException(ValidationErrorMissingField + "PackageLocale"); + } + } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/PackageAgreement.cs b/src/WinGetUtilInterop/Manifest/V1/PackageAgreement.cs @@ -0,0 +1,29 @@ +// ----------------------------------------------------------------------- +// <copyright file="PackageAgreement.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +// ----------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + /// <summary> + /// Class that contains package agreement. + /// </summary> + public class PackageAgreement + { + /// <summary> + /// Gets or sets the agreement label. + /// </summary> + public string AgreementLabel { get; set; } + + /// <summary> + /// Gets or sets the agreement text. + /// </summary> + public string Agreement { get; set; } + + /// <summary> + /// Gets or sets the agreement url. + /// </summary> + public string AgreementUrl { get; set; } + } +}+ \ No newline at end of file diff --git a/src/WinGetUtilInterop/WinGetUtilInterop.csproj b/src/WinGetUtilInterop/WinGetUtilInterop.csproj @@ -0,0 +1,15 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netstandard2.0</TargetFramework> + </PropertyGroup> + + <ItemGroup> + <Folder Include="Helpers\" /> + <Folder Include="Manifest\" /> + </ItemGroup> + + <ItemGroup> + <PackageReference Include="YamlDotNet" Version="8.1.2" /> + </ItemGroup> +</Project>