diff --git a/.gitignore b/.gitignore
index 479e37e613..5b15105408 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,9 @@
*.userosscache
*.sln.docstates
+# Backup files
+*.[Bb][Aa][Kk]
+
# full nuget directory
[Bb]uild/FullNuget
diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln
index d36b1388a6..49d0218225 100644
--- a/WindowsAppRuntime.sln
+++ b/WindowsAppRuntime.sln
@@ -548,6 +548,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OAuth", "dev\OAuth\OAuth.vcxitems", "{3E7FD510-8B66-40E7-A80B-780CB8972F83}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Security.Authentication.OAuth.Projection", "dev\Projections\CS\Microsoft.Security.Authentication.OAuth\Microsoft.Security.Authentication.OAuth.Projection.csproj", "{1D24CC70-85B1-4864-B847-3328F40AF01E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1}
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interop", "Interop", "{3B706C5C-55E0-4B76-BF59-89E20FE46795}"
EndProject
@@ -564,6 +567,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CameraCaptureUITests", "tes
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Windows.Media.Capture.Projection", "dev\Projections\CS\Microsoft.Windows.Media.Capture.Projection\Microsoft.Windows.Media.Capture.Projection.csproj", "{97AB4F8D-DF7E-4BA8-9B06-E7B79AF616D6}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1}
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BackgroundTaskBuilder", "BackgroundTaskBuilder", "{F425452A-3597-4A7A-BA0A-0C3C76A9F5CD}"
EndProject
@@ -680,6 +686,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BadgeNotificationTest", "test\BadgeNotificationTest\BadgeNotificationTest.vcxproj", "{7C8BEED1-7B27-41C5-A22F-9D6B4468F52A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Storage.Pickers.Projection", "dev\Projections\CS\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.csproj", "{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Interop\StoragePickers\StoragePickers.vcxitems", "{A39E7B2F-5F67-47DD-8443-531D095CA7F3}"
EndProject
@@ -739,6 +748,24 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Decimal", "dev\Decimal\Deci
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ABForwardTests", "test\ABForward\ABForward.vcxproj", "{C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{8479133D-5FF8-486B-B978-3A14D66725F7}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package", "dev\Package\Package.vcxitems", "{3D652B4A-AC29-4BA2-A2CA-2ACC08EAD1E9}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{9DE31467-8D10-4558-8719-32559E01B32A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "API", "API", "{BF763B12-77A9-471D-825B-4AC05E70A804}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageTests", "test\Package\API\PackageTests.vcxproj", "{F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563} = {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}
+ {3347E246-6BF5-469F-9C91-7D6E33B66786} = {3347E246-6BF5-469F-9C91-7D6E33B66786}
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0} = {469EE821-0FB5-4B9A-82D9-91292B0593D0}
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025} = {472B8D93-9200-48B7-BFB6-9D9B85AA4025}
+ {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1}
+ {F41B5211-4E18-4625-96A3-0130001B57C8} = {F41B5211-4E18-4625-96A3-0130001B57C8}
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Windows.ApplicationModel.Resources", "dev\MRTCore\mrt\Microsoft.Windows.ApplicationModel.Resources\src\Microsoft.Windows.ApplicationModel.Resources.vcxproj", "{9B3B03BC-1BC0-43EA-B3FF-D5214F3CF5CF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mrmmin", "dev\MRTCore\mrt\mrm\mrmmin\mrmmin.vcxproj", "{AB199369-87E7-44B4-AE83-7CF5C068EFEB}"
@@ -755,6 +782,28 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Deployment.WindowsAppRuntim
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Deployment.WindowsAppRuntime.Test.SingletonLowerVersion", "test\Deployment\data\WindowsAppRuntime.Test.SingletonLowerVersion\WindowsAppRuntime.Test.SingletonLowerVersion.vcxproj", "{7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{2BF5AE78-D16A-402B-84C1-2164B887D858}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MachineExternal", "MachineExternal", "{862A4050-B803-493D-89C2-09390141C774}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mutable", "Mutable", "{39ADE0B0-74E8-478A-9AE1-EFB568985AA5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UserExternal", "UserExternal", "{70317696-8BDE-4D1E-99DE-5CD722EB86B1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.Mutable.msix", "test\Package\data\Mutable\Package.Test.Mutable.msix.vcxproj", "{469EE821-0FB5-4B9A-82D9-91292B0593D0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.MachineExternal.msix", "test\Package\data\MachineExternal\Package.Test.MachineExternal.msix.vcxproj", "{3347E246-6BF5-469F-9C91-7D6E33B66786}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.UserExternal.msix", "test\Package\data\UserExternal\Package.Test.UserExternal.msix.vcxproj", "{28CEF2AF-174B-4EE9-B71E-D596C5E1E563}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Framework", "Framework", "{2F020A4F-E3ED-445F-9D17-4149F198006A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.Framework.msix", "test\Package\data\Framework\Package.Test.Framework.msix.vcxproj", "{F41B5211-4E18-4625-96A3-0130001B57C8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{537704A1-B275-436E-A9AC-11A8A9398F27}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.Main.msix", "test\Package\data\Main\Package.Test.Main.msix.vcxproj", "{472B8D93-9200-48B7-BFB6-9D9B85AA4025}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -2553,6 +2602,22 @@ Global
{C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99}.Release|x64.Build.0 = Release|x64
{C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99}.Release|x86.ActiveCfg = Release|Win32
{C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99}.Release|x86.Build.0 = Release|Win32
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|Any CPU.Build.0 = Debug|x64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|ARM64.Build.0 = Debug|ARM64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|x64.ActiveCfg = Debug|x64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|x64.Build.0 = Debug|x64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|x86.ActiveCfg = Debug|Win32
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|x86.Build.0 = Debug|Win32
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|Any CPU.ActiveCfg = Release|x64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|Any CPU.Build.0 = Release|x64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|ARM64.ActiveCfg = Release|ARM64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|ARM64.Build.0 = Release|ARM64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|x64.ActiveCfg = Release|x64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|x64.Build.0 = Release|x64
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|x86.ActiveCfg = Release|Win32
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|x86.Build.0 = Release|Win32
{9B3B03BC-1BC0-43EA-B3FF-D5214F3CF5CF}.Debug|Any CPU.ActiveCfg = Debug|x64
{9B3B03BC-1BC0-43EA-B3FF-D5214F3CF5CF}.Debug|Any CPU.Build.0 = Debug|x64
{9B3B03BC-1BC0-43EA-B3FF-D5214F3CF5CF}.Debug|ARM64.ActiveCfg = Debug|ARM64
@@ -2665,6 +2730,86 @@ Global
{7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D}.Release|x64.Build.0 = Release|x64
{7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D}.Release|x86.ActiveCfg = Release|Win32
{7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D}.Release|x86.Build.0 = Release|Win32
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|Any CPU.Build.0 = Debug|x64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|ARM64.Build.0 = Debug|ARM64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|x64.ActiveCfg = Debug|x64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|x64.Build.0 = Debug|x64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|x86.ActiveCfg = Debug|Win32
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|x86.Build.0 = Debug|Win32
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|Any CPU.ActiveCfg = Release|x64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|Any CPU.Build.0 = Release|x64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|ARM64.ActiveCfg = Release|ARM64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|ARM64.Build.0 = Release|ARM64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x64.ActiveCfg = Release|x64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x64.Build.0 = Release|x64
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x86.ActiveCfg = Release|Win32
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x86.Build.0 = Release|Win32
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|Any CPU.Build.0 = Debug|x64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|ARM64.Build.0 = Debug|ARM64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|x64.ActiveCfg = Debug|x64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|x64.Build.0 = Debug|x64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|x86.ActiveCfg = Debug|Win32
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|x86.Build.0 = Debug|Win32
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|Any CPU.ActiveCfg = Release|x64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|Any CPU.Build.0 = Release|x64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|ARM64.ActiveCfg = Release|ARM64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|ARM64.Build.0 = Release|ARM64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|x64.ActiveCfg = Release|x64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|x64.Build.0 = Release|x64
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|x86.ActiveCfg = Release|Win32
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|x86.Build.0 = Release|Win32
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|Any CPU.Build.0 = Debug|x64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|ARM64.Build.0 = Debug|ARM64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|x64.ActiveCfg = Debug|x64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|x64.Build.0 = Debug|x64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|x86.ActiveCfg = Debug|Win32
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|x86.Build.0 = Debug|Win32
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|Any CPU.ActiveCfg = Release|x64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|Any CPU.Build.0 = Release|x64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|ARM64.ActiveCfg = Release|ARM64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|ARM64.Build.0 = Release|ARM64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x64.ActiveCfg = Release|x64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x64.Build.0 = Release|x64
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x86.ActiveCfg = Release|Win32
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x86.Build.0 = Release|Win32
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|Any CPU.Build.0 = Debug|x64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|ARM64.Build.0 = Debug|ARM64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|x64.ActiveCfg = Debug|x64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|x64.Build.0 = Debug|x64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|x86.ActiveCfg = Debug|Win32
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|x86.Build.0 = Debug|Win32
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|Any CPU.ActiveCfg = Release|x64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|Any CPU.Build.0 = Release|x64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|ARM64.ActiveCfg = Release|ARM64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|ARM64.Build.0 = Release|ARM64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|x64.ActiveCfg = Release|x64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|x64.Build.0 = Release|x64
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|x86.ActiveCfg = Release|Win32
+ {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|x86.Build.0 = Release|Win32
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|Any CPU.Build.0 = Debug|x64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|ARM64.Build.0 = Debug|ARM64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|x64.ActiveCfg = Debug|x64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|x64.Build.0 = Debug|x64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|x86.ActiveCfg = Debug|Win32
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|x86.Build.0 = Debug|Win32
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|Any CPU.ActiveCfg = Release|x64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|Any CPU.Build.0 = Release|x64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|ARM64.ActiveCfg = Release|ARM64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|ARM64.Build.0 = Release|ARM64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|x64.ActiveCfg = Release|x64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|x64.Build.0 = Release|x64
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|x86.ActiveCfg = Release|Win32
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2888,11 +3033,27 @@ Global
{E9C055BB-6AE4-497A-A354-D07841E68976} = {022E355A-AB24-48EE-9CC0-965BEFDF5E8C}
{DC453DE3-18FD-43E7-8103-20763C8B97C8} = {5012149E-F09F-4F18-A03C-FFE597203821}
{C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
+ {8479133D-5FF8-486B-B978-3A14D66725F7} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
+ {3D652B4A-AC29-4BA2-A2CA-2ACC08EAD1E9} = {8479133D-5FF8-486B-B978-3A14D66725F7}
+ {9DE31467-8D10-4558-8719-32559E01B32A} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
+ {BF763B12-77A9-471D-825B-4AC05E70A804} = {9DE31467-8D10-4558-8719-32559E01B32A}
+ {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7} = {BF763B12-77A9-471D-825B-4AC05E70A804}
{BF580B26-B869-3AF1-43EC-D0FD55A49E4D} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
{346E099B-45E4-FF40-E63D-8B34915223C1} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
{06AA7FD7-36BE-41AC-9008-56919D1612C6} = {3B706C5C-55E0-4B76-BF59-89E20FE46795}
{462CF10A-E6B5-4005-8E25-132D1DE589B7} = {2B653A15-2482-40E5-9509-C531E69D0749}
{7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D} = {2B653A15-2482-40E5-9509-C531E69D0749}
+ {2BF5AE78-D16A-402B-84C1-2164B887D858} = {9DE31467-8D10-4558-8719-32559E01B32A}
+ {862A4050-B803-493D-89C2-09390141C774} = {2BF5AE78-D16A-402B-84C1-2164B887D858}
+ {39ADE0B0-74E8-478A-9AE1-EFB568985AA5} = {2BF5AE78-D16A-402B-84C1-2164B887D858}
+ {70317696-8BDE-4D1E-99DE-5CD722EB86B1} = {2BF5AE78-D16A-402B-84C1-2164B887D858}
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0} = {39ADE0B0-74E8-478A-9AE1-EFB568985AA5}
+ {3347E246-6BF5-469F-9C91-7D6E33B66786} = {862A4050-B803-493D-89C2-09390141C774}
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563} = {70317696-8BDE-4D1E-99DE-5CD722EB86B1}
+ {2F020A4F-E3ED-445F-9D17-4149F198006A} = {2BF5AE78-D16A-402B-84C1-2164B887D858}
+ {F41B5211-4E18-4625-96A3-0130001B57C8} = {2F020A4F-E3ED-445F-9D17-4149F198006A}
+ {537704A1-B275-436E-A9AC-11A8A9398F27} = {2BF5AE78-D16A-402B-84C1-2164B887D858}
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025} = {537704A1-B275-436E-A9AC-11A8A9398F27}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77}
@@ -2904,6 +3065,7 @@ Global
dev\RuntimeCompatibilityOptions\RuntimeCompatibilityOptions.vcxitems*{1f7b9e9f-9987-490b-9e6e-093c7f63fec4}*SharedItemsImports = 9
dev\Notifications\BaseNotifications\BaseNotifications.vcxitems*{2bd7a1bb-d3d8-484f-9180-409d781dccf9}*SharedItemsImports = 9
dev\EnvironmentManager\API\Microsoft.Process.Environment.vcxitems*{2f3fad1b-d3df-4866-a3a3-c2c777d55638}*SharedItemsImports = 9
+ dev\Package\Package.vcxitems*{3d652b4a-ac29-4ba2-a2ca-2acc08ead1e9}*SharedItemsImports = 9
dev\OAuth\OAuth.vcxitems*{3e7fd510-8b66-40e7-a80b-780cb8972f83}*SharedItemsImports = 9
test\inc\inc.vcxitems*{412d023e-8635-4ad2-a0ea-e19e08d36915}*SharedItemsImports = 4
test\inc\inc.vcxitems*{4b30c685-8490-440f-9879-a75d45daa361}*SharedItemsImports = 4
@@ -2929,6 +3091,7 @@ Global
dev\DynamicDependency\API\DynamicDependency.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\Licensing\Licensing.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\PackageManager\API\PackageManager.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
+ dev\Package\Package.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\PowerNotifications\PowerNotifications.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\RuntimeCompatibilityOptions\RuntimeCompatibilityOptions.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\UndockedRegFreeWinRT\UndockedRegFreeWinRT.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
diff --git a/build/NuSpecs/AppxManifest.xml b/build/NuSpecs/AppxManifest.xml
index 256c8c66be..ca4a56f80e 100644
--- a/build/NuSpecs/AppxManifest.xml
+++ b/build/NuSpecs/AppxManifest.xml
@@ -46,6 +46,9 @@
+
+
+
diff --git a/dev/Common/AppModel.Package.h b/dev/Common/AppModel.Package.h
index 772091840a..b3a3304c88 100644
--- a/dev/Common/AppModel.Package.h
+++ b/dev/Common/AppModel.Package.h
@@ -6,7 +6,12 @@
#include
+#include
+#include
+
#include
+#include
+#include
namespace AppModel::Package
{
@@ -79,6 +84,211 @@ inline std::tuple
+ inline TString MakeFromPCWSTR(PCWSTR s)
+ {
+ if constexpr (std::is_same_v)
+ {
+ return s ? std::wstring{s} : std::wstring{};
+ }
+ else
+ {
+ // For WIL unique string wrappers, use WIL's maker.
+ // WIL string maker functions accept PCWSTR and return a unique_*_string wrapper. [1](https://github-wiki-see.page/m/microsoft/wil/wiki/String-helpers)
+ return wil::make_unique_string(s);
+ }
+ }
+
+ // GetPackagePathByFullName2 requires >=19H1
+ typedef LONG (WINAPI* GetPackagePathByFullName2Function)(
+ PCWSTR packageFullName,
+ PackagePathType packagePathType,
+ UINT32* pathLength,
+ PWSTR path);
+
+ inline wil::unique_hmodule g_dll_apiset_appmodel_runtime_1_3;
+ inline GetPackagePathByFullName2Function g_getPackagePathByFullName2{};
+ inline std::once_flag g_onceFlag{};
+
+ inline void initialize()
+ {
+ wil::unique_hmodule dll;
+ if (::ExportLoader::Load(L"api-ms-win-appmodel-runtime-l1-1-3.dll", wil::out_param(dll)))
+ {
+ return;
+ }
+ if (dll)
+ {
+ GetPackagePathByFullName2Function getPackagePathByFullName2{};
+ if (FAILED(::ExportLoader::GetFunctionIfExists(dll.get(), "GetPackagePathByFullName2", &getPackagePathByFullName2)))
+ {
+ return;
+ }
+ if (getPackagePathByFullName2)
+ {
+ g_dll_apiset_appmodel_runtime_1_3 = std::move(dll);
+ g_getPackagePathByFullName2 = std::move(getPackagePathByFullName2);
+ }
+ }
+ }
+
+ /// Get the path for a package, if GetPackagePathByFullName2() is available.
+ /// Return an empty path if the PackagePathType isn't supported on current platform (*pathLength=0, *path="").
+ /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2
+ inline HRESULT GetPackagePathByFullName2IfSupported(
+ _In_ PCWSTR packageFullName,
+ PackagePathType packagePathType,
+ std::uint32_t* pathLength,
+ _Out_writes_opt_(*pathLength) PWSTR path)
+ {
+ // Availability is a matter of timeline:
+ // * PackagePathType_Install is available since Win8
+ // * PackagePathType_Mutable is available since 19H1
+ // * PackagePathType_Effective is available since 19H1
+ // * PackagePathType_MachineExternalLocation is available since 20H1
+ // * PackagePathType_UserExternalLocation is available since 20H1
+ // * PackagePathType_EffectiveExternalLocation is available since 20H1
+ // GetPackagePathByFullName() is available since Win8
+ // GetPackagePathByFullName2() is available since 19H1 (though not all PackagePathType values were supported that early)
+ //
+ // Treat asks for locations not supported by the current system the same as not-found
+
+ if (::WindowsVersion::IsWindows10_20H1OrGreater() ||
+ (::WindowsVersion::IsWindows10_19H1OrGreater() &&
+ ((packagePathType == PackagePathType_Install) || (packagePathType == PackagePathType_Mutable) || (packagePathType == PackagePathType_Effective))))
+ {
+ std::call_once(g_onceFlag, initialize);
+ RETURN_HR_IF_NULL(E_NOTIMPL, g_getPackagePathByFullName2);
+
+ RETURN_IF_FAILED(g_getPackagePathByFullName2(packageFullName, packagePathType, pathLength, path));
+ }
+ else if ((packagePathType == PackagePathType_Install) || (packagePathType == PackagePathType_Effective))
+ {
+ // Only Install location is supported by the current system
+ // Effective is thus equivalent to Install
+ // Either way, rock it old school...
+ RETURN_IF_FAILED(::GetPackagePathByFullName(packageFullName, pathLength, path));
+ }
+ else
+ {
+ // The requested location isn't possible on the current system
+ if (path && (*pathLength > 0))
+ {
+ *path = L'\0';
+ }
+ *pathLength = 0;
+ }
+ return S_OK;
+ }
+}
+
+/// Get the path for a package.
+/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getcurrentpackagepath2
+template
+inline Tstring GetPath(_In_ PCWSTR packageFullName, PackagePathType packagePathType)
+{
+ // Paths can be long but typically short(ish). We can use a quick fixed buffer
+ // as an optimization and fallback to dynamic allocation if need be
+ WCHAR path[MAX_PATH]{};
+ uint32_t pathLength{ ARRAYSIZE(path) };
+ const auto hr{ details::GetPackagePathByFullName2IfSupported(packageFullName, packagePathType, &pathLength, path) };
+ if (SUCCEEDED(hr))
+ {
+ if (pathLength > 0)
+ {
+ return details::MakeFromPCWSTR(path);
+ }
+ else
+ {
+ return Tstring{};
+ }
+ }
+ else if ((hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) ||
+ (hr == HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_MUTABLE_DIRECTORY)) ||
+ (hr == E_NOTIMPL))
+ {
+ return Tstring{};
+ }
+ else if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
+ {
+ THROW_HR_MSG(hr, "PackageFullName=%ls PackagePathType=%d", packageFullName ? packageFullName : L"", static_cast(packagePathType));
+ }
+
+ // It's bigger than a breadbox. Allocate memory
+ std::unique_ptr pathBuffer{ std::make_unique(pathLength) };
+ THROW_IF_WIN32_ERROR_MSG(details::GetPackagePathByFullName2IfSupported(packageFullName, packagePathType, &pathLength, pathBuffer.get()),
+ "PackageFullName=%ls PackagePathType=%d", packageFullName ? packageFullName : L"", static_cast(packagePathType));
+ return details::MakeFromPCWSTR(pathBuffer.get());
+}
+
+/// Get the install path for a package.
+/// @return null or empty string if the package isn't visible.
+/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype
+template
+inline Tstring GetInstallPath(_In_ PCWSTR packageFullName)
+{
+ return GetPath(packageFullName, PackagePathType_Install);
+}
+
+/// Get the mutable path for a package.
+/// @return null or empty string if the package isn't visible to the caller or has no mutable path.
+/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype
+template
+inline Tstring GetMutablePath(_In_ PCWSTR packageFullName)
+{
+ return GetPath(packageFullName, PackagePathType_Mutable);
+}
+
+/// Get the machine external path for a package.
+/// @return null or empty string if the package isn't visible to the caller or has no machine external path.
+/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype
+template
+inline Tstring GetMachineExternalPath(_In_ PCWSTR packageFullName)
+{
+ return GetPath(packageFullName, PackagePathType_MachineExternal);
+}
+
+/// Get the user external path for a package.
+/// @return null or empty string if the package isn't visible to the caller or has no user external path.
+/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype
+template
+inline Tstring GetUserExternalPath(_In_ PCWSTR packageFullName)
+{
+ return GetPath(packageFullName, PackagePathType_UserExternal);
+}
+
+/// Get the effective external path for a package.
+/// @return null or empty string if the package isn't visible to the caller or has no effective external path.
+/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype
+template
+inline Tstring GetEffectiveExternalPath(_In_ PCWSTR packageFullName)
+{
+ return GetPath(packageFullName, PackagePathType_EffectiveExternal);
+}
+
+/// Get the effective path for a package.
+/// @return null or empty string if the package isn't visible to the caller.
+/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype
+template
+inline Tstring GetEffectivePath(_In_ PCWSTR packageFullName)
+{
+ return GetPath(packageFullName, PackagePathType_Effective);
+}
+
+inline std::filesystem::path GetAbsoluteFilename(
+ PCWSTR packageFullName,
+ PCWSTR filename,
+ PackagePathType packageType)
+{
+ const auto path{ ::AppModel::Package::GetPath(packageFullName, packageType) };
+ std::filesystem::path pathName{ path };
+ pathName /= filename;
+ return std::filesystem::absolute(pathName);
+}
}
#endif // __APPMODEL_PACKAGE_H
diff --git a/dev/Common/AppModel.PackageGraph.h b/dev/Common/AppModel.PackageGraph.h
index 43a502e42e..1770f04beb 100644
--- a/dev/Common/AppModel.PackageGraph.h
+++ b/dev/Common/AppModel.PackageGraph.h
@@ -10,18 +10,18 @@ namespace AppModel::PackageGraph
{
inline HRESULT GetCurrentPackageGraph(
const UINT32 flags,
- uint32_t& packageInfoCount,
+ std::uint32_t& packageInfoCount,
const PACKAGE_INFO*& packageInfo,
wil::unique_cotaskmem_ptr& buffer)
{
packageInfoCount = 0;
packageInfo = nullptr;
- uint32_t bufferLength{};
+ std::uint32_t bufferLength{};
LONG rc{ ::GetCurrentPackageInfo(flags, &bufferLength, nullptr, &packageInfoCount) };
if ((rc == APPMODEL_ERROR_NO_PACKAGE) || (packageInfoCount == 0))
{
- // No packages. We�re done
+ // No packages. We're done
return S_OK;
}
RETURN_HR_IF(HRESULT_FROM_WIN32(rc), rc != ERROR_INSUFFICIENT_BUFFER);
diff --git a/dev/Common/Common.vcxitems.filters b/dev/Common/Common.vcxitems.filters
index 987c2340a5..9aa9fb614d 100644
--- a/dev/Common/Common.vcxitems.filters
+++ b/dev/Common/Common.vcxitems.filters
@@ -59,4 +59,4 @@
Source Files
-
\ No newline at end of file
+
diff --git a/dev/Common/ExportLoader.h b/dev/Common/ExportLoader.h
index 3906d65170..7d9384d732 100644
--- a/dev/Common/ExportLoader.h
+++ b/dev/Common/ExportLoader.h
@@ -6,6 +6,19 @@
namespace ExportLoader
{
+inline HRESULT Load(PCWSTR moduleName, _Out_ HMODULE* module)
+{
+ auto hmodule{ ::LoadLibraryExW(moduleName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32) };
+ if (!hmodule)
+ {
+ const auto rc{ GetLastError() };
+ RETURN_HR_IF_MSG(HRESULT_FROM_WIN32(rc), rc != ERROR_MOD_NOT_FOUND, "%ls", moduleName);
+ RETURN_HR(E_NOTIMPL);
+ }
+ *module = hmodule;
+ return S_OK;
+}
+
inline HMODULE Load(PCWSTR moduleName)
{
auto hmodule{ ::LoadLibraryExW(moduleName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32) };
@@ -19,17 +32,41 @@ inline HMODULE Load(PCWSTR moduleName)
}
template
-inline T GetFunction(HMODULE module, PCSTR functionName)
+inline HRESULT GetFunctionIfExists(HMODULE module, PCSTR functionName, _Out_ T* function)
+{
+ auto fn{ reinterpret_cast(::GetProcAddress(module, functionName)) };
+ if (!fn)
+ {
+ const auto rc{ GetLastError() };
+ RETURN_HR_IF_MSG(HRESULT_FROM_WIN32(rc), rc != ERROR_PROC_NOT_FOUND, "%hs", functionName);
+ }
+ *function = fn;
+ return S_OK;
+}
+
+template
+inline T GetFunctionIfExists(HMODULE module, PCSTR functionName)
{
auto function{ reinterpret_cast(::GetProcAddress(module, functionName)) };
if (!function)
{
const auto rc{ GetLastError() };
- THROW_HR_IF_MSG(HRESULT_FROM_WIN32(rc), rc != ERROR_PROC_NOT_FOUND, "%hs", functionName);
- THROW_HR(E_NOTIMPL);
+ if (rc == ERROR_PROC_NOT_FOUND)
+ {
+ return nullptr;
+ }
+ THROW_WIN32_MSG(rc, "%hs", functionName);
}
return function;
}
+
+template
+inline T GetFunction(HMODULE module, PCSTR functionName)
+{
+ auto function{ GetFunctionIfExists(module, functionName) };
+ THROW_HR_IF_NULL_MSG(E_NOTIMPL, function, "%hs", functionName);
+ return function;
+}
}
#endif // defined(__EXPORTLOADER_H)
diff --git a/dev/Common/IsWindowsVersion.h b/dev/Common/IsWindowsVersion.h
index f7fe5ee17c..2b049a1b43 100644
--- a/dev/Common/IsWindowsVersion.h
+++ b/dev/Common/IsWindowsVersion.h
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation and Contributors.
+// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.
#ifndef __ISWINDOWSVERSION_H
@@ -6,6 +6,8 @@
#include
+#include
+
namespace WindowsVersion
{
inline bool IsExportPresent(
diff --git a/dev/Common/TerminalVelocityFeatures-PackageRuntime.h b/dev/Common/TerminalVelocityFeatures-PackageRuntime.h
new file mode 100644
index 0000000000..4fd99a2151
--- /dev/null
+++ b/dev/Common/TerminalVelocityFeatures-PackageRuntime.h
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT IT
+
+// INPUT FILE: dev\Common\TerminalVelocityFeatures-PackageRuntime.xml
+// OPTIONS: -Channel Experimental -Language C++ -Namespace Microsoft.Windows.ApplicationModel -Path dev\Common\TerminalVelocityFeatures-PackageRuntime.xml -Output dev\Common\TerminalVelocityFeatures-PackageRuntime.h
+
+#if defined(__midlrt)
+namespace features
+{
+ feature_name Feature_PackageRuntime = { DisabledByDefault, FALSE };
+}
+#endif // defined(__midlrt)
+
+// Feature constants
+#define WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_APPLICATIONMODEL_FEATURE_PACKAGERUNTIME_ENABLED 1
+
+#if defined(__cplusplus)
+
+namespace Microsoft::Windows::ApplicationModel
+{
+
+__pragma(detect_mismatch("ODR_violation_WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_APPLICATIONMODEL_FEATURE_PACKAGERUNTIME_ENABLED_mismatch", "AlwaysEnabled"))
+struct Feature_PackageRuntime
+{
+ static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_APPLICATIONMODEL_FEATURE_PACKAGERUNTIME_ENABLED == 1; }
+};
+
+} // namespace Microsoft.Windows.ApplicationModel
+
+#endif // defined(__cplusplus)
diff --git a/dev/Common/TerminalVelocityFeatures-PackageRuntime.xml b/dev/Common/TerminalVelocityFeatures-PackageRuntime.xml
new file mode 100644
index 0000000000..2d1fa1c612
--- /dev/null
+++ b/dev/Common/TerminalVelocityFeatures-PackageRuntime.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+ Feature_PackageRuntime
+ Package Runtime APIs
+ AlwaysEnabled
+
+ Preview
+ Stable
+
+
+
diff --git a/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h b/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h
index 9ca7bee67e..4ef14a71d6 100644
--- a/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h
+++ b/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h
@@ -37,16 +37,16 @@ extern "C" HRESULT WINAPI GetCurrentPackageInfo3(
// Modern variants of appmodel.h
namespace appmodel
{
-inline std::wstring GetPackagePath(PCWSTR packageFullName)
+inline std::wstring GetPackagePath(PCWSTR packageFullName, PackagePathType packagePathType)
{
// Paths can be long but typically short(ish). We can use a quick fixed buffer
// as an optimization and fallback to dynamic allocation if need be
- WCHAR path[MAX_PATH];
+ WCHAR path[MAX_PATH]{};
UINT32 pathLength{ ARRAYSIZE(path) };
- const auto rc{ ::GetPackagePathByFullName(packageFullName, &pathLength, path) };
+ const auto rc{ ::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, path) };
if (rc == ERROR_SUCCESS)
{
- return std::wstring(path);
+ return std::wstring{ path };
}
else if (rc != ERROR_INSUFFICIENT_BUFFER)
{
@@ -56,7 +56,12 @@ inline std::wstring GetPackagePath(PCWSTR packageFullName)
// It's bigger than a breadbox. Allocate memory
std::unique_ptr pathBuffer{ std::make_unique(pathLength) };
THROW_IF_NULL_ALLOC(pathBuffer);
- THROW_IF_WIN32_ERROR(::GetPackagePathByFullName(packageFullName, &pathLength, pathBuffer.get()));
+ THROW_IF_WIN32_ERROR(::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, pathBuffer.get()));
return std::wstring(pathBuffer.get());
}
+
+inline std::wstring GetPackagePath(PCWSTR packageFullName)
+{
+ return GetPackagePath(packageFullName, PackagePathType_Install);
+}
}
diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp
index d20a90d365..7f59104fe2 100644
--- a/dev/Interop/StoragePickers/PickerCommon.cpp
+++ b/dev/Interop/StoragePickers/PickerCommon.cpp
@@ -181,7 +181,7 @@ namespace PickerCommon {
return;
}
- for (size_t i = 0; i < value.size(); i++)
+ for (std::uint32_t i = 0; i < value.size(); i++)
{
if (value[i] == L'\0')
{
@@ -204,7 +204,7 @@ namespace PickerCommon {
PickerLocalization::GetStoragePickersLocalizationText(ImproperFileExtensionLocalizationKey));
}
- for (size_t i = 1; i < filter.size(); i++)
+ for (std::uint32_t i = 1; i < filter.size(); i++)
{
if (filter[i] == L'.' || filter[i] == L'*' || filter[i] == L'?')
{
diff --git a/dev/Package/M.W.A.Package.cpp b/dev/Package/M.W.A.Package.cpp
new file mode 100644
index 0000000000..bdcd73ac0e
--- /dev/null
+++ b/dev/Package/M.W.A.Package.cpp
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+#include "M.W.A.Package.h"
+#include "Microsoft.Windows.ApplicationModel.Package.g.cpp"
+
+#include "package_runtime.h"
+
+#include "PackageTelemetry.h"
+
+namespace winrt::Microsoft::Windows::ApplicationModel::implementation
+{
+ static_assert(static_cast(PackageFeature::PackagePath_Mutable) == static_cast(::PackageFeature_PackagePath_Mutable), "PackageFeature::PackagePath_Mutable != PackageFeature_PackagePath_Mutable");
+ static_assert(static_cast(PackageFeature::PackagePath_ExternalLocation) == static_cast(::PackageFeature_PackagePath_ExternalLocation), "PackageFeature::PackagePath_ExternalLocation != PackageFeature_PackagePath_ExternalLocation");
+
+ static_assert(static_cast(GetFilePathOptions::None) == static_cast(::GetPackageFilePathOptions_None), "GetFilePathOptions::None != FindPackageFileOptions_None");
+ static_assert(static_cast(GetFilePathOptions::SearchInstallPath) == static_cast(::GetPackageFilePathOptions_SearchInstallPath), "GetFilePathOptions::SearchInstallPath != GetPackageFilePathOptions_SearchInstallPath");
+ static_assert(static_cast(GetFilePathOptions::SearchMutablePath) == static_cast(::GetPackageFilePathOptions_SearchMutablePath), "GetFilePathOptions::SearchMutablePath != GetPackageFilePathOptions_SearchMutablePath");
+ static_assert(static_cast(GetFilePathOptions::SearchMachineExternalPath) == static_cast(::GetPackageFilePathOptions_SearchMachineExternalPath), "GetFilePathOptions::SearchMachineExternalPath != GetPackageFilePathOptions_SearchMachineExternalPath");
+ static_assert(static_cast(GetFilePathOptions::SearchUserExternalPath) == static_cast(::GetPackageFilePathOptions_SearchUserExternalPath), "GetFilePathOptions::SearchUserExternalPath != GetPackageFilePathOptions_SearchUserExternalPath");
+ static_assert(static_cast(GetFilePathOptions::SearchMainPackages) == static_cast(::GetPackageFilePathOptions_SearchMainPackages), "GetFilePathOptions::SearchMainPackages!= GetPackageFilePathOptions_SearchMainPackages");
+ static_assert(static_cast(GetFilePathOptions::SearchFrameworkPackages) == static_cast(::GetPackageFilePathOptions_SearchFrameworkPackages), "GetFilePathOptions::SearchFrameworkPackages!= GetPackageFilePathOptions_SearchFrameworkPackages");
+ static_assert(static_cast(GetFilePathOptions::SearchOptionalPackages) == static_cast(::GetPackageFilePathOptions_SearchOptionalPackages), "GetFilePathOptions::SearchOptionalPackages!= GetPackageFilePathOptions_SearchOptionalPackages");
+ static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(::GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages");
+ static_assert(static_cast(GetFilePathOptions::SearchBundlePackages) == static_cast(::GetPackageFilePathOptions_SearchBundlePackages), "GetFilePathOptions::SearchBundlePackages!= GetPackageFilePathOptions_SearchBundlePackages");
+ static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(::GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies");
+
+ bool Package::IsFeatureSupported(winrt::Microsoft::Windows::ApplicationModel::PackageFeature const& feature)
+ {
+ return ::IsPackageFeatureSupported(static_cast<::PackageFeature>(feature));
+ }
+ hstring Package::GetFilePath(hstring const& filename)
+ {
+ return GetFilePath(filename, winrt::hstring{});
+ }
+ hstring Package::GetFilePath(hstring const& filename, hstring const& packageFullName)
+ {
+ return GetFilePath(filename, packageFullName, GetFilePathOptions::None);
+ }
+ hstring Package::GetFilePath(hstring const& filename, hstring const& packageFullName, winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions const& options)
+ {
+ wil::unique_process_heap_ptr packageFile;
+ THROW_IF_FAILED_MSG(::GetPackageFilePath(packageFullName.c_str(), filename.c_str(), static_cast<::GetPackageFilePathOptions>(options), wil::out_param(packageFile)),
+ "PackageFullName=%ls Options=0x%X Filename=%ls", packageFullName.c_str(), static_cast(options), filename.c_str());
+ if (!packageFile)
+ {
+ return winrt::hstring{};
+ }
+ return winrt::hstring{ packageFile.get() };
+ }
+}
diff --git a/dev/Package/M.W.A.Package.h b/dev/Package/M.W.A.Package.h
new file mode 100644
index 0000000000..9fea38fc08
--- /dev/null
+++ b/dev/Package/M.W.A.Package.h
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#pragma once
+
+#include "Microsoft.Windows.ApplicationModel.Package.g.h"
+
+namespace winrt::Microsoft::Windows::ApplicationModel::implementation
+{
+ struct Package
+ {
+ Package() = default;
+
+ static bool IsFeatureSupported(winrt::Microsoft::Windows::ApplicationModel::PackageFeature const& feature);
+ static hstring GetFilePath(hstring const& filename);
+ static hstring GetFilePath(hstring const& filename, hstring const& packageFullName);
+ static hstring GetFilePath(hstring const& filename, hstring const& packageFullName, winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions const& options);
+ };
+}
+namespace winrt::Microsoft::Windows::ApplicationModel::factory_implementation
+{
+ struct Package : PackageT
+ {
+ };
+}
diff --git a/dev/Package/M.W.A.PackageGraph.cpp b/dev/Package/M.W.A.PackageGraph.cpp
new file mode 100644
index 0000000000..f29bfde230
--- /dev/null
+++ b/dev/Package/M.W.A.PackageGraph.cpp
@@ -0,0 +1,42 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+#include "M.W.A.PackageGraph.h"
+#include "Microsoft.Windows.ApplicationModel.PackageGraph.g.cpp"
+
+#include "package_runtime.h"
+
+#include "PackageTelemetry.h"
+
+namespace winrt::Microsoft::Windows::ApplicationModel::implementation
+{
+ static_assert(static_cast(GetFilePathOptions::None) == static_cast(GetPackageFilePathOptions_None), "GetFilePathOptions::None != FindPackageFileOptions_None");
+ static_assert(static_cast(GetFilePathOptions::SearchInstallPath) == static_cast(GetPackageFilePathOptions_SearchInstallPath), "GetFilePathOptions::SearchInstallPath != GetPackageFilePathOptions_SearchInstallPath");
+ static_assert(static_cast(GetFilePathOptions::SearchMutablePath) == static_cast(GetPackageFilePathOptions_SearchMutablePath), "GetFilePathOptions::SearchMutablePath != GetPackageFilePathOptions_SearchMutablePath");
+ static_assert(static_cast(GetFilePathOptions::SearchMachineExternalPath) == static_cast(GetPackageFilePathOptions_SearchMachineExternalPath), "GetFilePathOptions::SearchMachineExternalPath != GetPackageFilePathOptions_SearchMachineExternalPath");
+ static_assert(static_cast(GetFilePathOptions::SearchUserExternalPath) == static_cast(GetPackageFilePathOptions_SearchUserExternalPath), "GetFilePathOptions::SearchUserExternalPath != GetPackageFilePathOptions_SearchUserExternalPath");
+ static_assert(static_cast(GetFilePathOptions::SearchMainPackages) == static_cast(GetPackageFilePathOptions_SearchMainPackages), "GetFilePathOptions::SearchMainPackages!= GetPackageFilePathOptions_SearchMainPackages");
+ static_assert(static_cast(GetFilePathOptions::SearchFrameworkPackages) == static_cast(GetPackageFilePathOptions_SearchFrameworkPackages), "GetFilePathOptions::SearchFrameworkPackages!= GetPackageFilePathOptions_SearchFrameworkPackages");
+ static_assert(static_cast(GetFilePathOptions::SearchOptionalPackages) == static_cast(GetPackageFilePathOptions_SearchOptionalPackages), "GetFilePathOptions::SearchOptionalPackages!= GetPackageFilePathOptions_SearchOptionalPackages");
+ static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages");
+ static_assert(static_cast(GetFilePathOptions::SearchBundlePackages) == static_cast(GetPackageFilePathOptions_SearchBundlePackages), "GetFilePathOptions::SearchBundlePackages!= GetPackageFilePathOptions_SearchBundlePackages");
+ static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies");
+
+ hstring PackageGraph::GetFilePath(hstring const& filename)
+ {
+ return GetFilePath(filename, GetFilePathOptions::None);
+ }
+ hstring PackageGraph::GetFilePath(hstring const& filename, winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions const& options)
+ {
+ wil::unique_process_heap_ptr packageFile;
+ THROW_IF_FAILED_MSG(::GetPackageFilePathInPackageGraph(filename.c_str(), static_cast<::GetPackageFilePathOptions>(options), wil::out_param(packageFile)),
+ "Options=0x%X Filename=%ls", static_cast(options), filename.c_str());
+ if (!packageFile)
+ {
+ return winrt::hstring{};
+ }
+ return winrt::hstring{ packageFile.get() };
+ }
+}
diff --git a/dev/Package/M.W.A.PackageGraph.h b/dev/Package/M.W.A.PackageGraph.h
new file mode 100644
index 0000000000..f888f0f1b9
--- /dev/null
+++ b/dev/Package/M.W.A.PackageGraph.h
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#pragma once
+
+#include "Microsoft.Windows.ApplicationModel.PackageGraph.g.h"
+
+namespace winrt::Microsoft::Windows::ApplicationModel::implementation
+{
+ struct PackageGraph
+ {
+ PackageGraph() = default;
+
+ static hstring GetFilePath(hstring const& filename);
+ static hstring GetFilePath(hstring const& filename, winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions const& options);
+ };
+}
+namespace winrt::Microsoft::Windows::ApplicationModel::factory_implementation
+{
+ struct PackageGraph : PackageGraphT
+ {
+ };
+}
diff --git a/dev/Package/Package.idl b/dev/Package/Package.idl
new file mode 100644
index 0000000000..76af5835e3
--- /dev/null
+++ b/dev/Package/Package.idl
@@ -0,0 +1,165 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include
+
+namespace Microsoft.Windows.ApplicationModel
+{
+ [contractversion(1)]
+ apicontract PackageRuntimeContract{};
+
+ /// Features can be queried if currently available/enabled.
+ /// @see Package.IsPackageFeatureSupported()
+ [contract(PackageRuntimeContract, 1)]
+ enum PackageFeature
+ {
+ /// Package Mutable path.
+ /// @see PackagePathType_Mutable
+ PackagePath_Mutable = 1,
+
+ /// Package ExternalLocation path.
+ /// @see PackagePathType_MachineExternal
+ /// @see PackagePathType_UserExternal
+ PackagePath_ExternalLocation = 2,
+ };
+
+ /// Options for GetFilePath*()
+ /// @see Package.GetFilePath
+ /// @see PackageGraph.GetFilePath
+ [contract(PackageRuntimeContract, 1)]
+ [flags]
+ enum GetFilePathOptions
+ {
+ /// Default behavior
+ None = 0,
+
+ /// Include the package's Install path in the file search order
+ /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
+ SearchInstallPath = 0x0001,
+
+ /// Include the package's Mutable path (if it has one) in the file search order
+ /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
+ SearchMutablePath = 0x0002,
+
+ /// Include the package's Machine External path (if it has one) in the file search order
+ /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
+ SearchMachineExternalPath = 0x0004,
+
+ /// Include the package's User External path (if it has one) in the file search order
+ /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
+ SearchUserExternalPath = 0x0008,
+
+ /// Include Main packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
+ SearchMainPackages = 0x0010,
+
+ /// Include Framework packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
+ SearchFrameworkPackages = 0x0020,
+
+ /// Include Optional packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
+ SearchOptionalPackages = 0x0040,
+
+ /// Include Resource packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
+ SearchResourcePackages = 0x0080,
+
+ /// Include Bundle packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
+ SearchBundlePackages = 0x0100,
+
+ /// Include HostRuntime dependencies in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
+ SearchHostRuntimeDependencies = 0x0200,
+ };
+
+ [contract(PackageRuntimeContract, 1)]
+ runtimeclass Package
+ {
+ /// Return true if feature is supported on the current system.
+ static Boolean IsFeatureSupported(PackageFeature feature);
+
+ /// Return the absolute path to the file in the current process' package. This uses the
+ /// current process' package identity, or fails with HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE)
+ /// if the process lacks package identity.
+ /// @param filename file to locate.
+ /// @param packageFile absolute path to the packaged file, or empty string ("") if not found.
+ /// @note The package path search order is External(User or Machine) -> Mutable -> Install.
+ /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one).
+ /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2
+ /// @see PackageGraph.GetFilePath
+ static String GetFilePath(String filename);
+
+ /// Return the absolute path to the file in the package.
+ /// @param filename file to locate.
+ /// @param packageFullName the package.
+ /// @param packageFile absolute path to the packaged file, or empty string ("") if not found.
+ /// @note The package path search order is External(User or Machine) -> Mutable -> Install.
+ /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one).
+ /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2
+ /// @see PackageGraph.GetFilePath
+ [method_name("GetFilePathInPackage")]
+ static String GetFilePath(String filename, String packageFullName);
+
+ /// Return the absolute path to the file in the package.
+ /// @param filename file to locate.
+ /// @param packageFullName the package.
+ /// @param packageFile absolute path to the packaged file, or empty string ("") if not found.
+ /// @param options options for the search.
+ /// @note The package path search order is External(User or Machine) -> Mutable -> Install.
+ /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one).
+ /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2
+ /// @see PackageGraph.GetFilePath
+ /// @see PackageGraph.GetFilePathOptions
+ [method_name("GetFilePathInPackageWithOptions")]
+ static String GetFilePath(String filename, String packageFullName, GetFilePathOptions options);
+ }
+
+ [contract(PackageRuntimeContract, 1)]
+ runtimeclass PackageGraph
+ {
+ /// Return the absolute path to the file in the package graph.
+ /// @param filename file to locate.
+ /// @param packageFile absolute path to the packaged file, or empty string ("") if not found.
+ /// @note The package paths search order is External(User or Machine) -> Mutable -> Install.
+ /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one).
+ /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2
+ /// @see Package.GetFilePath
+ static String GetFilePath(String filename);
+
+ /// Return the absolute path to the file in the package graph.
+ /// @param filename file to locate.
+ /// @param packageFile absolute path to the packaged file, or empty string ("") if not found.
+ /// @param options options for the search.
+ /// @note The package paths search order is External(User or Machine) -> Mutable -> Install.
+ /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one).
+ /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2
+ /// @see Package.GetFilePath
+ /// @see GetPackageFilePathOptions
+ [method_name("GetFilePathWithOptions")]
+ static String GetFilePath(String filename, GetFilePathOptions options);
+ };
+}
diff --git a/dev/Package/Package.vcxitems b/dev/Package/Package.vcxitems
new file mode 100644
index 0000000000..67039d5f16
--- /dev/null
+++ b/dev/Package/Package.vcxitems
@@ -0,0 +1,34 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ {3D652B4A-AC29-4BA2-A2CA-2ACC08EAD1E9}
+
+
+
+ %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/Package/Package.vcxitems.filters b/dev/Package/Package.vcxitems.filters
new file mode 100644
index 0000000000..2a72bbe298
--- /dev/null
+++ b/dev/Package/Package.vcxitems.filters
@@ -0,0 +1,44 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+
+
diff --git a/dev/Package/PackageTelemetry.h b/dev/Package/PackageTelemetry.h
new file mode 100644
index 0000000000..6d1c8cab58
--- /dev/null
+++ b/dev/Package/PackageTelemetry.h
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT license.
+
+#pragma once
+
+#include
+
+DECLARE_TRACELOGGING_CLASS(PackageTelemetryProvider,
+ "Microsoft.WindowsAppSDK.Package",
+ // {95308938-292a-46ea-9ea4-4d729ab287a6}
+ (0x95308938, 0x292a, 0x46ea, 0x9e, 0xa4, 0x4d, 0x72, 0x9a, 0xb2, 0x87, 0xa6));
+
+class PackageTelemetry : public wil::TraceLoggingProvider
+{
+ IMPLEMENT_TELEMETRY_CLASS(PackageTelemetry, PackageTelemetryProvider);
+
+public:
+
+ BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(FindPackageFile, PDT_ProductAndServicePerformance);
+ DEFINE_ACTIVITY_START(winrt::hstring const& packageFullName, winrt::hstring const& filename) noexcept try
+ {
+ TraceLoggingClassWriteStart(
+ FindPackageFile,
+ _GENERIC_PARTB_FIELDS_ENABLED,
+ TraceLoggingWideString(packageFullName.c_str(), "PackageFullName"),
+ TraceLoggingWideString(filename.c_str(), "Filename"));
+ }
+ CATCH_LOG()
+ END_ACTIVITY_CLASS();
+};
diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp
new file mode 100644
index 0000000000..75565b863b
--- /dev/null
+++ b/dev/Package/package_runtime.cpp
@@ -0,0 +1,399 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+#include "package_runtime.h"
+
+namespace appmodel
+{
+static bool IsPathSupported_Mutable()
+{
+ // Cache the answer on first query
+ static bool s_isSupported{ !!::IsPackageFeatureSupported(PackageFeature_PackagePath_Mutable) };
+ return s_isSupported;
+}
+
+static bool IsPathSupported_ExternalLocation()
+{
+ // Cache the answer on first query
+ static bool s_isSupported{ !!::IsPackageFeatureSupported(PackageFeature_PackagePath_ExternalLocation) };
+ return s_isSupported;
+}
+
+inline GetPackageFilePathOptions package_properties_to_options(
+ std::uint32_t packageInfoFlags)
+{
+ const auto hostRuntimeMatch{ WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_HOSTRUNTIME) ?
+ GetPackageFilePathOptions_SearchHostRuntimeDependencies :
+ GetPackageFilePathOptions_None };
+ if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_FRAMEWORK))
+ {
+ return GetPackageFilePathOptions_SearchFrameworkPackages | hostRuntimeMatch;
+ }
+ else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_OPTIONAL))
+ {
+ return GetPackageFilePathOptions_SearchOptionalPackages | hostRuntimeMatch;
+ }
+ else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_RESOURCE))
+ {
+ return GetPackageFilePathOptions_SearchResourcePackages | hostRuntimeMatch;
+ }
+ else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_BUNDLE))
+ {
+ return GetPackageFilePathOptions_SearchBundlePackages | hostRuntimeMatch;
+ }
+ else
+ {
+ // PACKAGE_INFO.flags has no PACKAGE_PROPERTY_MAIN so we can only determine PackageType=Main
+ // by first verifying it's not any other type of package (Bundle|Framework|Optional|Resource).
+ // When all else is ruled out what we're left with must be a Main package
+ return GetPackageFilePathOptions_SearchMainPackages | hostRuntimeMatch;
+ }
+}
+
+inline GetPackageFilePathOptions get_package_properties(
+ PCWSTR packageFullName,
+ PACKAGE_INFO_REFERENCE packageInfoReference)
+{
+ // Fetch the package's properties
+ constexpr auto flags{ PACKAGE_FILTER_BUNDLE | PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_RESOURCE | PACKAGE_FILTER_OPTIONAL | PACKAGE_FILTER_HOSTRUNTIME | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC };
+ std::uint32_t bufferLength{};
+ std::uint32_t count{};
+ auto rc{ ::GetPackageInfo(packageInfoReference, flags, &bufferLength, nullptr, &count) };
+ if (rc != ERROR_INSUFFICIENT_BUFFER)
+ {
+ if (rc == ERROR_SUCCESS)
+ {
+ if (count == 0)
+ {
+ // Package not found
+ return GetPackageFilePathOptions_None;
+ }
+ THROW_HR(E_UNEXPECTED); // This should never occur
+ }
+ THROW_WIN32_MSG(rc, "GetPackageInfo(...query...) %ls", packageFullName);
+ }
+ std::unique_ptr buffer{ std::make_unique(bufferLength) };
+ THROW_IF_WIN32_ERROR_MSG(::GetPackageInfo(packageInfoReference, flags, &bufferLength, buffer.get(), &count),
+ "GetPackageInfo: %ls", packageFullName);
+ THROW_HR_IF(E_UNEXPECTED, count == 0); // This should never occur
+ const auto& packageInfo{ *reinterpret_cast(buffer.get()) };
+
+ // Convert the package properties to options
+ return package_properties_to_options(packageInfo.flags);
+}
+
+inline bool is_match_for_package_properties(
+ PCWSTR packageFullName,
+ _In_ GetPackageFilePathOptions options,
+ PACKAGE_INFO_REFERENCE packageInfoReference)
+{
+ // Detect PackageType|HostRuntimeDependency
+ //
+ // If options = All or None specified then all packages are a match thus no need to fetch the package's properties
+ constexpr auto maskMatchPackageType{ GetPackageFilePathOptions_SearchMainPackages |
+ GetPackageFilePathOptions_SearchFrameworkPackages |
+ GetPackageFilePathOptions_SearchOptionalPackages |
+ GetPackageFilePathOptions_SearchResourcePackages |
+ GetPackageFilePathOptions_SearchBundlePackages |
+ GetPackageFilePathOptions_SearchHostRuntimeDependencies };
+ const auto optionsToMatch{ options & maskMatchPackageType };
+ if ((optionsToMatch == GetPackageFilePathOptions_None) || (optionsToMatch == maskMatchPackageType))
+ {
+ return true;
+ }
+
+ // Fetch the package's properties
+ const auto packageProperties{ get_package_properties(packageFullName, packageInfoReference) };
+
+ // Does this package meet the criteria?
+ return WI_IsAnyFlagSet(packageProperties, optionsToMatch);
+}
+
+inline bool is_match_for_package_properties(
+ _In_ GetPackageFilePathOptions options,
+ std::uint32_t packageInfoFlags)
+{
+ // Detect PackageType|HostRuntimeDependency
+ //
+ // If options = All or None specified then all packages are a match thus no need to fetch the package's properties
+ constexpr auto maskMatchPackageType{ GetPackageFilePathOptions_SearchMainPackages |
+ GetPackageFilePathOptions_SearchFrameworkPackages |
+ GetPackageFilePathOptions_SearchOptionalPackages |
+ GetPackageFilePathOptions_SearchResourcePackages |
+ GetPackageFilePathOptions_SearchBundlePackages |
+ GetPackageFilePathOptions_SearchHostRuntimeDependencies };
+ constexpr auto maskMatchAll{ maskMatchPackageType };
+ const auto optionsToMatch{ options & maskMatchAll };
+ if ((optionsToMatch == GetPackageFilePathOptions_None) || (optionsToMatch == maskMatchAll))
+ {
+ return true;
+ }
+
+ // Does this package meet the criteria?
+ return WI_IsAnyFlagSet(packageInfoFlags, optionsToMatch);
+}
+
+inline std::filesystem::path get_package_file_for_location(
+ PCWSTR packageFullName,
+ _In_ PCWSTR filename,
+ PackagePathType packagePathType)
+{
+ // Availability is a matter of timeline:
+ // * PackagePathType_Install is available since Win8
+ // * PackagePathType_Mutable is available since 19H1
+ // * PackagePathType_Effective is available since 19H1
+ // * PackagePathType_MachineExternalLocation is available since 20H1
+ // * PackagePathType_UserExternalLocation is available since 20H1
+ // * PackagePathType_EffectiveExternalLocation is available since 20H1
+ // GetPackagePathByFullName() is available since Win8
+ // GetPackagePathByFullName2() is available since 19H1 (though not all PackagePathType values were supported that early)
+ //
+ // Treat asks for locations not supported by the current system the same as not-found
+ //
+ // This is all handled by GetPackagePathByFullName2IfSupported() so just ask it for the path
+ std::wstring packagePath{ ::AppModel::Package::GetPath(packageFullName, packagePathType) };
+ if (!packagePath.empty())
+ {
+ std::filesystem::path absoluteFilename{ packagePath };
+ absoluteFilename /= filename;
+ if (std::filesystem::exists(absoluteFilename))
+ {
+ return absoluteFilename;
+ }
+ }
+ return std::filesystem::path{};
+}
+
+inline std::filesystem::path get_package_file(
+ PCWSTR packageFullName,
+ _In_ PCWSTR filename,
+ _In_ GetPackageFilePathOptions options)
+{
+ // Search External location
+ std::filesystem::path path;
+ if (IsPathSupported_ExternalLocation())
+ {
+ if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchUserExternalPath))
+ {
+ if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath))
+ {
+ // EffectiveExternal == UserExternal if package/user has one else MachineExternal
+ path = get_package_file_for_location(packageFullName, filename, PackagePathType_EffectiveExternal);
+ }
+ else
+ {
+ path = get_package_file_for_location(packageFullName, filename, PackagePathType_UserExternal);
+ }
+ }
+ else if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath))
+ {
+ path = get_package_file_for_location(packageFullName, filename, PackagePathType_MachineExternal);
+ }
+ }
+ if (path.empty())
+ {
+ // Search Mutable location
+ if (IsPathSupported_Mutable() && WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMutablePath))
+ {
+ path = get_package_file_for_location(packageFullName, filename, PackagePathType_Mutable);
+ }
+ if (path.empty())
+ {
+ // Search Install location
+ if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchInstallPath))
+ {
+ path = get_package_file_for_location(packageFullName, filename, PackagePathType_Install);
+ }
+ }
+ }
+ return path;
+}
+
+inline std::filesystem::path get_package_file(
+ PCWSTR packageFullName,
+ _In_ PCWSTR filename,
+ _In_ GetPackageFilePathOptions effectiveOptions,
+ PACKAGE_INFO_REFERENCE packageInfoReference)
+{
+ // Does the package's properties match our search criteria?
+ if (!is_match_for_package_properties(packageFullName, effectiveOptions, packageInfoReference))
+ {
+ return std::filesystem::path{};
+ }
+
+ // Search the package's locations for the file
+ return get_package_file(packageFullName, filename, effectiveOptions);
+}
+
+inline GetPackageFilePathOptions ToEffectiveOptions(
+ GetPackageFilePathOptions options)
+{
+ // If options == None then use default behavior (search everything)
+ if (options == GetPackageFilePathOptions_None)
+ {
+ // 'All' locations supported by the current system is one of...
+ // * Install
+ // * Install | Mutable
+ // * Install | Mutable | ExternalLocation
+ constexpr auto nonLocationOptions{
+ GetPackageFilePathOptions_SearchMainPackages |
+ GetPackageFilePathOptions_SearchFrameworkPackages |
+ GetPackageFilePathOptions_SearchOptionalPackages |
+ GetPackageFilePathOptions_SearchResourcePackages |
+ GetPackageFilePathOptions_SearchBundlePackages |
+ GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ };
+ if (IsPathSupported_ExternalLocation())
+ {
+ return GetPackageFilePathOptions_SearchInstallPath |
+ GetPackageFilePathOptions_SearchMutablePath |
+ GetPackageFilePathOptions_SearchMachineExternalPath |
+ GetPackageFilePathOptions_SearchUserExternalPath |
+ nonLocationOptions;
+ }
+ else if (IsPathSupported_Mutable())
+ {
+ return GetPackageFilePathOptions_SearchInstallPath |
+ GetPackageFilePathOptions_SearchMutablePath |
+ nonLocationOptions;
+ }
+ else
+ {
+ return GetPackageFilePathOptions_SearchInstallPath |
+ nonLocationOptions;
+ GetPackageFilePathOptions_SearchHostRuntimeDependencies;
+ }
+ }
+
+ // If Search*Dependencies are all clear then search them all
+ // where * = Main | Framework | Optional | Resource | Bundle | HostRuntime
+ //
+ // NOTE: HostRuntime isn't a PackageType but little white lie here for our filtering.
+ // For example, a Main package shouldn't be searched given options=SearchFrameworkDependnecies
+ // but it should be search if the Main package declares a and
+ // options=SearchFrameworkDependencies | SearchHostRuntimeDependencies.
+ constexpr auto maskPackageTypes{ GetPackageFilePathOptions_SearchMainPackages |
+ GetPackageFilePathOptions_SearchFrameworkPackages |
+ GetPackageFilePathOptions_SearchOptionalPackages |
+ GetPackageFilePathOptions_SearchResourcePackages |
+ GetPackageFilePathOptions_SearchBundlePackages |
+ GetPackageFilePathOptions_SearchHostRuntimeDependencies };
+ if (WI_AreAllFlagsClear(options, maskPackageTypes))
+ {
+ return options | maskPackageTypes;
+ }
+ return options;
+}
+}
+
+STDAPI_(BOOL) IsPackageFeatureSupported(
+ PackageFeature feature) noexcept
+{
+ switch (feature)
+ {
+ case PackageFeature_PackagePath_Mutable:
+ {
+ // Supported on Windows >= 19H1
+ return ::WindowsVersion::IsWindows10_19H1OrGreater() ? TRUE : FALSE;
+ }
+ case PackageFeature_PackagePath_ExternalLocation:
+ {
+ // Supported on Windows >= VB (20H1)
+ return ::WindowsVersion::IsWindows10_20H1OrGreater() ? TRUE : FALSE;
+ }
+ }
+
+ std::ignore = LOG_HR_MSG(E_INVALIDARG, "PackageFeature:%d", static_cast(feature));
+ return FALSE;
+}
+
+STDAPI GetPackageFilePath(
+ PCWSTR packageFullName,
+ _In_ PCWSTR filename,
+ _In_ GetPackageFilePathOptions options,
+ _Outptr_result_maybenull_ PWSTR* packageFile) noexcept try
+{
+ *packageFile = nullptr;
+
+ RETURN_HR_IF(E_INVALIDARG, ::Microsoft::Foundation::String::IsNullOrEmpty(filename));
+
+ // If packageFullName = NULL or "" use the caller's package identity
+ WCHAR packageFullNameBuffer[PACKAGE_FULL_NAME_MAX_LENGTH + 1]{};
+ if (::Microsoft::Foundation::String::IsNullOrEmpty(packageFullName))
+ {
+ std::uint32_t packageFullNameBufferLength{ ARRAYSIZE(packageFullNameBuffer) };
+ RETURN_IF_WIN32_ERROR(::GetCurrentPackageFullName(&packageFullNameBufferLength, packageFullNameBuffer));
+ packageFullName = packageFullNameBuffer;
+ }
+
+ // Let's do it...
+ const auto effectiveOptions{ appmodel::ToEffectiveOptions(options) };
+ wil::unique_package_info_reference packageInfoReference;
+ auto rc{ ::OpenPackageInfoByFullName(packageFullName, 0, wil::out_param(packageInfoReference)) };
+ if (rc != ERROR_SUCCESS)
+ {
+ const auto hr{ HRESULT_FROM_WIN32(rc) };
+ if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
+ {
+ // Package not found == File not found
+ return S_OK;
+ }
+ THROW_WIN32_MSG(rc, "OpenPackageInfoByFullName(%ls,...)", packageFullName);
+ }
+ auto path{ appmodel::get_package_file(packageFullName, filename, effectiveOptions, packageInfoReference.get()) };
+ if (!path.empty())
+ {
+ auto absoluteFilename{ wil::make_process_heap_string(path.c_str()) };
+ *packageFile = absoluteFilename.release();
+ }
+ return S_OK;
+}
+CATCH_RETURN();
+
+STDAPI GetPackageFilePathInPackageGraph(
+ _In_ PCWSTR filename,
+ _In_ GetPackageFilePathOptions options,
+ _Outptr_result_maybenull_ PWSTR* packageFile) noexcept try
+{
+ *packageFile = nullptr;
+
+ RETURN_HR_IF(E_INVALIDARG, ::Microsoft::Foundation::String::IsNullOrEmpty(filename));
+
+ // Compute the effective options
+ const auto effectiveOptions{ appmodel::ToEffectiveOptions(options) };
+
+ // Search the package graph
+ //
+ // Ideally we'd pass our filtering needs down to package graph query API (e.g. GetCurrentPackageGraph)
+ // but it doesn't quite give us the semantics we need, so we'll do it the hard way
+ constexpr std::uint32_t flags{ PACKAGE_FILTER_BUNDLE | PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_RESOURCE | PACKAGE_FILTER_OPTIONAL | PACKAGE_FILTER_HOSTRUNTIME | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC };
+ std::uint32_t packageGraphCount{};
+ const PACKAGE_INFO* packageInfos{};
+ wil::unique_cotaskmem_ptr buffer;
+ RETURN_IF_FAILED(::AppModel::PackageGraph::GetCurrentPackageGraph(flags, packageGraphCount, packageInfos, buffer));
+ for (std::uint32_t index=0; index < packageGraphCount; ++index)
+ {
+ const auto& packageInfo{ packageInfos[index] };
+
+ // Does the package's properties match our search criteria?
+ const auto packageInfoFlags{ appmodel::package_properties_to_options(packageInfo.flags) };
+ if (!appmodel::is_match_for_package_properties(effectiveOptions, packageInfoFlags))
+ {
+ continue;
+ }
+
+ // This package is included in our search. Check for the file
+ const auto packageFullName{ packageInfo.packageFullName };
+ auto path{ appmodel::get_package_file(packageFullName, filename, effectiveOptions) };
+ if (!path.empty())
+ {
+ auto absoluteFilename{ wil::make_process_heap_string(path.c_str()) };
+ *packageFile = absoluteFilename.release();
+ break;
+ }
+ }
+ return S_OK;
+}
+CATCH_RETURN();
diff --git a/dev/Package/package_runtime.h b/dev/Package/package_runtime.h
new file mode 100644
index 0000000000..535e2909d6
--- /dev/null
+++ b/dev/Package/package_runtime.h
@@ -0,0 +1,129 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#if !defined(PACKAGE_RUNTIME_H)
+#define PACKAGE_RUNTIME_H
+
+/// Features can be queried if currently available/enabled.
+/// @see IsPackageFeatureSupported()
+typedef enum PackageFeature
+{
+ /// Package Mutable path.
+ /// @see PackagePathType_Mutable
+ PackageFeature_PackagePath_Mutable = 1,
+
+ /// Package External Location path (MachineExternal + UserExternal)
+ /// @see PackagePathType_MachineExternal
+ /// @see PackagePathType_UserExternal
+ PackageFeature_PackagePath_ExternalLocation = 2,
+} PackageFeature;
+
+/// Return TRUE if feature is supported on the current system.
+STDAPI_(BOOL) IsPackageFeatureSupported(
+ PackageFeature feature) noexcept;
+
+/// Options for GetPackageFilePath*() functions
+typedef enum GetPackageFilePathOptions
+{
+ /// Default behavior
+ GetPackageFilePathOptions_None = 0,
+
+ /// Include the package's Install path in the file search order
+ /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath,
+ /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchInstallPath = 0x0001,
+
+ /// Include the package's Mutable path (if it has one) in the file search order
+ /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath,
+ /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchMutablePath = 0x0002,
+
+ /// Include the package's Machine External path (if it has one) in the file search order
+ /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath,
+ /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchMachineExternalPath = 0x0004,
+
+ /// Include the package's User External path (if it has one) in the file search order
+ /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath,
+ /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchUserExternalPath = 0x0008,
+
+ /// Include Main packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchMainPackages = 0x0010,
+
+ /// Include Framework packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchFrameworkPackages = 0x0020,
+
+ /// Include Optional packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchOptionalPackages = 0x0040,
+
+ /// Include Resource packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchResourcePackages = 0x0080,
+
+ /// Include Bundle packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchBundlePackages = 0x0100,
+
+ /// Include HostRuntime dependencies in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0200,
+} GetPackageFilePathOptions;
+DEFINE_ENUM_FLAG_OPERATORS(GetPackageFilePathOptions)
+
+/// Return the absolute path to the file in the package.
+/// @param packageFullName the package, or NULL or "" to use the current process' package identity.
+/// @param filename file to locate.
+/// @param options options for the search.
+/// @param packageFile absolute path to the packaged file, or NULL if not found. Allocated via HeapAlloc; use HeapFree to deallocate
+/// @note The package path search order is External(User or Machine) -> Mutable -> Install.
+/// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one).
+/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2
+/// @see GetPackageFilePathInPackageGraph()
+/// @see GetPackageFilePathOptions
+STDAPI GetPackageFilePath(
+ PCWSTR packageFullName,
+ _In_ PCWSTR filename,
+ _In_ GetPackageFilePathOptions options,
+ _Outptr_result_maybenull_ PWSTR* packageFile) noexcept;
+
+/// Return the absolute path to the file in the caller's package graph.
+/// @param filename file to locate.
+/// @param options options for the search.
+/// @param packageFile absolute path to the packaged file, or NULL if not found. Allocated via HeapAlloc; use HeapFree to deallocate
+/// @note The search order is External(User or Machine) -> Mutable -> Install for each package in the package graph.
+/// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one).
+/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2
+/// @see GetPackageFilePath()
+/// @see GetPackageFilePathOptions
+STDAPI GetPackageFilePathInPackageGraph(
+ _In_ PCWSTR filename,
+ _In_ GetPackageFilePathOptions options,
+ _Outptr_result_maybenull_ PWSTR* packageFile) noexcept;
+
+#endif // PACKAGE_RUNTIME_H
diff --git a/dev/Package/pch.h b/dev/Package/pch.h
new file mode 100644
index 0000000000..ec82c53552
--- /dev/null
+++ b/dev/Package/pch.h
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#pragma once
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
diff --git a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp
index 6bbdabd248..18833ef4d1 100644
--- a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp
+++ b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp
@@ -1585,13 +1585,13 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation
THROW_HR_MSG(E_INVALIDARG, "%ls", package.c_str());
}
winrt::Windows::Foundation::IAsyncOperationWithProgress
- PackageDeploymentManager::ProvisionPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options)
+ PackageDeploymentManager::ProvisionPackageByUriAsync(winrt::Windows::Foundation::Uri /*packageUri*/, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions /*options*/)
{
//TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId()
throw hresult_not_implemented();
}
winrt::Windows::Foundation::IAsyncOperationWithProgress
- PackageDeploymentManager::ProvisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options)
+ PackageDeploymentManager::ProvisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet /*packageSet*/, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions /*options*/)
{
//TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId()
throw hresult_not_implemented();
@@ -1613,13 +1613,13 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation
THROW_HR_MSG(E_INVALIDARG, "%ls", package.c_str());
}
winrt::Windows::Foundation::IAsyncOperationWithProgress
- PackageDeploymentManager::DeprovisionPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri)
+ PackageDeploymentManager::DeprovisionPackageByUriAsync(winrt::Windows::Foundation::Uri /*packageUri*/)
{
//TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId()
throw hresult_not_implemented();
}
winrt::Windows::Foundation::IAsyncOperationWithProgress
- PackageDeploymentManager::DeprovisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet)
+ PackageDeploymentManager::DeprovisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet /*packageSet*/ )
{
//TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId()
throw hresult_not_implemented();
@@ -1642,7 +1642,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation
}
winrt::Windows::Foundation::IAsyncOperationWithProgress
- PackageDeploymentManager::AddPackageByAppInstallerFileAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options)
+ PackageDeploymentManager::AddPackageByAppInstallerFileAsync(winrt::Windows::Foundation::Uri /*packageUri*/, winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions /*options*/)
{
//TODO add via AddPackageByAppInstallerFileAsync()
throw hresult_not_implemented();
diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def
index c487bfd388..82944a5660 100644
--- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def
+++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def
@@ -29,3 +29,7 @@ EXPORTS
WindowsAppRuntime_VersionInfo_TestInitialize
WindowsAppRuntime_EnsureIsLoaded
+
+ GetPackageFilePath
+ GetPackageFilePathInPackageGraph
+ IsPackageFeatureSupported
diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj
index 444615c099..c371ecc00e 100644
--- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj
+++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj
@@ -108,6 +108,7 @@
+
diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h
index 8dcd8e87ea..65b5886ba2 100644
--- a/dev/WindowsAppRuntime_DLL/pch.h
+++ b/dev/WindowsAppRuntime_DLL/pch.h
@@ -54,8 +54,12 @@
#include
#include
+#include
#include
+#include
+#include
#include
+#include
#include
#include
#include
diff --git a/specs/package/Package.md b/specs/package/Package.md
index 0de5f61fa0..fd6fdeae6e 100644
--- a/specs/package/Package.md
+++ b/specs/package/Package.md
@@ -297,8 +297,8 @@ string GetResourcesPri(string packageFullName)
std::wstring GetResourcesPri(PCWSTR packageFullName)
{
GetPackageFilePathOptions options{ GetPackageFilePathOptions_SearchInstallPath |
- GetPackageFilePathOptions_SearchMachineExternalPath |
- GetPackageFilePathOptions_SearchUserExternalPath };
+ GetPackageFilePathOptions_SearchMachineExternalPath |
+ GetPackageFilePathOptions_SearchUserExternalPath };
wil::unique_process_heap_string absoluteFilename;
const HRESULT hr{ GetPackageFilePath(
packageFullName, L"resources.pri", options, wistd::out_param(absoluteFilename)) };
@@ -363,7 +363,7 @@ std::wstring GetXamlWinMD()
## 4.5. Get a file path in the current process' package graph with options
Locate `Microsoft.UI.Xaml.winmd` in the current process' package graph but ignore Mutable locations,
-Resource packages and HostRuntime dependencies.
+Resource and Resource packages and HostRuntime dependencies.
### 4.5.1. C# Example
@@ -377,9 +377,7 @@ string GetXamlWinMD()
GetPackageFilePathOptions.SearchUserExternalPath |
GetPackageFilePathOptions.SearchMainPackages |
GetPackageFilePathOptions.SearchFrameworkPath |
- GetPackageFilePathOptions.SearchOptionalPath |
- GetPackageFilePathOptions.SearchStaticDependencies |
- GetPackageFilePathOptions.SearchDynamicDependencies;
+ GetPackageFilePathOptions.SearchOptionalPath;
var absoluteFilename = PackageGraph.GetFilePath("Microsoft.UI.Xaml.winmd", options);
if (absoluteFilename == null)
{
@@ -400,9 +398,7 @@ std::wstring GetXamlWinMD()
GetPackageFilePathOptions_SearchUserExternalPath |
GetPackageFilePathOptions_SearchMainPackages |
GetPackageFilePathOptions_SearchFrameworkPath |
- GetPackageFilePathOptions_SearchOptionalPath |
- GetPackageFilePathOptions_SearchStaticDependencies |
- GetPackageFilePathOptions_SearchDynamicDependencies };
+ GetPackageFilePathOptions_SearchOptionalPath };
wil::unique_process_heap_string absoluteFilename;
const HRESULT hr{ GetPackageFilePathInPackageGraph(
L"Microsoft.UI.Xaml.winmd", options, wistd::out_param(absoluteFilename)) };
@@ -447,38 +443,67 @@ namespace Microsoft.Windows.ApplicationModel
None = 0,
/// Include the package's Install path in the file search order
+ /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
SearchInstallPath = 0x0001,
/// Include the package's Mutable path (if it has one) in the file search order
+ /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
SearchMutablePath = 0x0002,
/// Include the package's Machine External path (if it has one) in the file search order
+ /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
SearchMachineExternalPath = 0x0004,
/// Include the package's User External path (if it has one) in the file search order
+ /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
SearchUserExternalPath = 0x0008,
/// Include Main packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
SearchMainPackages = 0x0010,
/// Include Framework packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
SearchFrameworkPackages = 0x0020,
/// Include Optional packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
SearchOptionalPackages = 0x0040,
/// Include Resource packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
SearchResourcePackages = 0x0080,
- /// Include HostRuntime dependencies in the file search order
- SearchHostRuntimeDependencies = 0x0100,
-
- /// Include Static package dependencies in the file search order
- SearchStaticDependencies = 0x0200,
+ /// Include Bundle packages in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
+ SearchBundlePackages = 0x0100,
- /// Include Dynamic package dependencies in the file search order
- SearchDynamicDependencies = 0x0400,
- }
+ /// Include HostRuntime dependencies in the file search order
+ /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages,
+ /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none
+ /// yields the same result).
+ SearchHostRuntimeDependencies = 0x0200,
+ };
[contract(PackageRuntimeContract, 1)]
runtimeclass Package
@@ -541,7 +566,7 @@ namespace Microsoft.Windows.ApplicationModel
/// @see Package.GetFilePath
/// @see GetPackageFilePathOptions
[method_name("GetFilePathWithOptions")]
- static String GetFilePath(String filename, GetPackageFilePathOptions options);
+ static String GetFilePath(String filename, GetFilePathOptions options);
};
}
```
@@ -564,38 +589,72 @@ typedef enum GetPackageFilePathOptions
GetPackageFilePathOptions_None = 0,
/// Include the package's Install path in the file search order
+ /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath,
+ /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
GetPackageFilePathOptions_SearchInstallPath = 0x0001,
/// Include the package's Mutable path (if it has one) in the file search order
+ /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath,
+ /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
GetPackageFilePathOptions_SearchMutablePath = 0x0002,
/// Include the package's Machine External path (if it has one) in the file search order
+ /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath,
+ /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
GetPackageFilePathOptions_SearchMachineExternalPath = 0x0004,
/// Include the package's User External path (if it has one) in the file search order
+ /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath,
+ /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath
+ /// are omitted then all locations are searched (i.e. specify all or none yields the same result).
GetPackageFilePathOptions_SearchUserExternalPath = 0x0008,
/// Include Main packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
GetPackageFilePathOptions_SearchMainPackages = 0x0010,
/// Include Framework packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
GetPackageFilePathOptions_SearchFrameworkPackages = 0x0020,
/// Include Optional packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
GetPackageFilePathOptions_SearchOptionalPackages = 0x0040,
/// Include Resource packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
GetPackageFilePathOptions_SearchResourcePackages = 0x0080,
- /// Include HostRuntime dependencies in the file search order
- GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0100,
-
- /// Include Static package dependencies in the file search order
- GetPackageFilePathOptions_SearchStaticDependencies = 0x0200,
+ /// Include Bundle packages in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchBundlePackages = 0x0100,
- /// Include Dynamic package dependencies in the file search order
- GetPackageFilePathOptions_SearchDynamicDependencies = 0x0400,
-}
+ /// Include HostRuntime dependencies in the file search order
+ /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages,
+ /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages,
+ /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies
+ /// are omitted then all package types are searched (i.e. specify all or none yields the same result).
+ GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0200,
+} GetPackageFilePathOptions;
+DEFINE_ENUM_FLAG_OPERATORS(GetPackageFilePathOptions)
/// Return the absolute path to the file in the package.
/// @param packageFullName the package, or NULL or "" to use the current process' package identity.
diff --git a/test/ABForward/ABForward.vcxproj b/test/ABForward/ABForward.vcxproj
index a8c7dfaa4c..02cf728f1c 100644
--- a/test/ABForward/ABForward.vcxproj
+++ b/test/ABForward/ABForward.vcxproj
@@ -126,28 +126,13 @@
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- WIN32;NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
-
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs)
-
-
-
+
Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- WIN32;_DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
true
pch.h
+ %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common
+ %(PreprocessorDefinitions);INLINE_TEST_METHOD_MARKUP
Windows
@@ -156,65 +141,20 @@
Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
+ _DEBUG;%(PreprocessorDefinitions)
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
+ NDEBUG;%(PreprocessorDefinitions)
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_DLL\Generated Files;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
+ WIN32;%(PreprocessorDefinitions)
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_DLL\Generated Files;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
-
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
@@ -327,4 +267,4 @@
$(RepoTestCertificatePFX)
$(RepoTestCertificatePassword)
-
\ No newline at end of file
+
diff --git a/test/AccessControlTests/AccessControlTests.vcxproj b/test/AccessControlTests/AccessControlTests.vcxproj
index 36aa8bb2ba..3bbbdf09cb 100644
--- a/test/AccessControlTests/AccessControlTests.vcxproj
+++ b/test/AccessControlTests/AccessControlTests.vcxproj
@@ -101,7 +101,7 @@
WIN32;_DEBUG;%(PreprocessorDefinitions)
Use
pch.h
- $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories)
+ $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories)
Windows
@@ -116,7 +116,7 @@
WIN32;_DEBUG;%(PreprocessorDefinitions)
Use
pch.h
- $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories)
+ $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories)
Windows
@@ -131,7 +131,7 @@
WIN32;NDEBUG;%(PreprocessorDefinitions)
Use
pch.h
- $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories)
+ $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories)
Windows
@@ -146,7 +146,7 @@
WIN32;NDEBUG;%(PreprocessorDefinitions)
Use
pch.h
- $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories)
+ $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories)
Windows
@@ -161,7 +161,7 @@
_DEBUG;%(PreprocessorDefinitions)
Use
pch.h
- $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories)
+ $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories)
Windows
@@ -176,7 +176,7 @@
NDEBUG;%(PreprocessorDefinitions)
Use
pch.h
- $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories)
+ $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories)
Windows
@@ -215,7 +215,7 @@
-
+
{f76b776e-86f5-48c5-8fc7-d2795ecc9746}
diff --git a/test/AppLifecycle/AppLifecycle.vcxproj b/test/AppLifecycle/AppLifecycle.vcxproj
index 3e3cb5d208..1b3c95cc7e 100644
--- a/test/AppLifecycle/AppLifecycle.vcxproj
+++ b/test/AppLifecycle/AppLifecycle.vcxproj
@@ -104,13 +104,13 @@
-
+
Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- WIN32;NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
true
pch.h
+ %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common
+ %(PreprocessorDefinitions);INLINE_TEST_METHOD_MARKUP
Windows
@@ -119,80 +119,20 @@
Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- WIN32;_DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
+ _DEBUG;%(PreprocessorDefinitions)
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
+ NDEBUG;%(PreprocessorDefinitions)
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
+ WIN32;%(PreprocessorDefinitions)
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
-
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
-
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
diff --git a/test/Decimal/CPP/DecimalTests.cpp b/test/Decimal/CPP/DecimalTests.cpp
index 780c8e7846..6087a3d71a 100644
--- a/test/Decimal/CPP/DecimalTests.cpp
+++ b/test/Decimal/CPP/DecimalTests.cpp
@@ -137,7 +137,7 @@ namespace Test::Decimal::Tests
TEST_CLASS_SETUP(ClassSetup)
{
::TD::DumpExecutionContext();
- ::TB::Setup(TB::Packages::Framework);
+ ::TB::Setup();
return true;
}
diff --git a/test/Decimal/CS/DecimalTest_CS.csproj b/test/Decimal/CS/DecimalTest_CS.csproj
index d67992768a..5f631ad762 100644
--- a/test/Decimal/CS/DecimalTest_CS.csproj
+++ b/test/Decimal/CS/DecimalTest_CS.csproj
@@ -3,6 +3,7 @@
Exe
net6.0-windows10.0.19041.0
+ 10.0.19041.0
x86;x64;arm64
disable
disable
diff --git a/test/Decimal/WinRT/DecimalTest_WinRT.cpp b/test/Decimal/WinRT/DecimalTest_WinRT.cpp
index ce3fe4992f..7d63f41c96 100644
--- a/test/Decimal/WinRT/DecimalTest_WinRT.cpp
+++ b/test/Decimal/WinRT/DecimalTest_WinRT.cpp
@@ -80,7 +80,7 @@ namespace Test::DecimalValue::Tests
TEST_CLASS_SETUP(ClassSetup)
{
::TD::DumpExecutionContext();
- ::TB::Setup(TB::Packages::Framework);
+ ::TB::Setup();
return true;
}
diff --git a/test/Deployment/API/DeploymentTests.vcxproj b/test/Deployment/API/DeploymentTests.vcxproj
index 706f411c26..ea876ee025 100644
--- a/test/Deployment/API/DeploymentTests.vcxproj
+++ b/test/Deployment/API/DeploymentTests.vcxproj
@@ -104,13 +104,13 @@
-
+
Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- WIN32;NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
true
pch.h
+ %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common
+ %(PreprocessorDefinitions);INLINE_TEST_METHOD_MARKUP
Windows
@@ -118,75 +118,20 @@
onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- WIN32;_DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
-
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
-
-
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
-
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
-
-
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
+ _DEBUG;%(PreprocessorDefinitions)
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
+ NDEBUG;%(PreprocessorDefinitions)
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
- NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP
- true
- pch.h
+ WIN32;%(PreprocessorDefinitions)
-
- Windows
- $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
-
diff --git a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml
index 4da765d04d..c88ab90500 100644
--- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml
+++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml
@@ -66,6 +66,13 @@
+
+
+ Microsoft.WindowsAppRuntime.dll
+
+
+
+
Microsoft.WindowsAppRuntime.dll
diff --git a/test/Package/API/PackageTests.Packages.h b/test/Package/API/PackageTests.Packages.h
new file mode 100644
index 0000000000..082c54a073
--- /dev/null
+++ b/test/Package/API/PackageTests.Packages.h
@@ -0,0 +1,364 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#ifndef __PACKAGETESTS_PACKAGES_H
+#define __PACKAGETESTS_PACKAGES_H
+
+namespace Test::Package::Tests{}
+//
+namespace TD = ::Test::Diagnostics;
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+
+namespace Test::Packages
+{
+namespace Framework
+{
+ constexpr PCWSTR c_packageDirName{ L"Package.Test.Framework.msix" };
+ constexpr PCWSTR c_packageFamilyName{ L"Test.Package.Framework_8wekyb3d8bbwe" };
+ constexpr PCWSTR c_packageFullName{ L"Test.Package.Framework_1.2.3.4_neutral__8wekyb3d8bbwe" };
+}
+namespace Main
+{
+ constexpr PCWSTR c_packageDirName{ L"Package.Test.Main.msix" };
+ constexpr PCWSTR c_packageFamilyName{ L"Test.Package.Main_8wekyb3d8bbwe" };
+ constexpr PCWSTR c_packageFullName{ L"Test.Package.Main_1.2.3.4_neutral__8wekyb3d8bbwe" };
+}
+namespace Mutable
+{
+ constexpr PCWSTR c_packageDirName{ L"Package.Test.Mutable.msix" };
+ constexpr PCWSTR c_packageFamilyName{ L"Test.Package.Mutable_8wekyb3d8bbwe" };
+ constexpr PCWSTR c_packageFullName{ L"Test.Package.Mutable_1.2.3.4_neutral__8wekyb3d8bbwe" };
+}
+namespace UserExternal
+{
+ constexpr PCWSTR c_packageDirName{ L"Package.Test.UserExternal.msix" };
+ constexpr PCWSTR c_packageFamilyName{ L"Test.Package.UserExternal_8wekyb3d8bbwe" };
+ constexpr PCWSTR c_packageFullName{ L"Test.Package.UserExternal_1.2.3.4_neutral__8wekyb3d8bbwe" };
+}
+namespace MachineExternal
+{
+ constexpr PCWSTR c_packageDirName{ L"Package.Test.MachineExternal.msix" };
+ constexpr PCWSTR c_packageFamilyName{ L"Test.Package.MachineExternal_8wekyb3d8bbwe" };
+ constexpr PCWSTR c_packageFullName{ L"Test.Package.MachineExternal_1.2.3.4_neutral__8wekyb3d8bbwe" };
+}
+}
+
+namespace Test::Package::Tests
+{
+ namespace TP = ::Test::Packages;
+
+ inline bool IsMutableLocationSupported()
+ {
+ return !!::IsPackageFeatureSupported(PackageFeature_PackagePath_Mutable);
+ }
+
+ inline bool IsExternalLocationSupported()
+ {
+ return !!::IsPackageFeatureSupported(PackageFeature_PackagePath_ExternalLocation);
+ }
+
+
+ inline bool IsPackageRegistered_Framework()
+ {
+ return TP::IsPackageRegistered(TP::Framework::c_packageFullName);
+ }
+ inline bool IsPackageStaged_Framework()
+ {
+ return TP::IsPackageStaged(TP::Framework::c_packageFullName);
+ }
+ inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_Framework()
+ {
+ return TP::GetPackageStatus(TP::Framework::c_packageFullName);
+ }
+ inline void AddPackage_Framework()
+ {
+ TP::AddPackageIfNecessary(TP::Framework::c_packageDirName, TP::Framework::c_packageFullName);
+ }
+ inline void AddPackageDefer_Framework()
+ {
+ TP::AddPackageDeferIfNecessary(TP::Framework::c_packageDirName, TP::Framework::c_packageFullName);
+ }
+ inline void StagePackage_Framework()
+ {
+ TP::StagePackageIfNecessary(TP::Framework::c_packageDirName, TP::Framework::c_packageFullName);
+ }
+ inline void RegisterPackage_Framework()
+ {
+ TP::RegisterPackageIfNecessary(TP::Framework::c_packageFullName);
+ }
+ inline void RemovePackage_Framework()
+ {
+ if (IsPackageRegistered_Framework())
+ {
+ TP::RemovePackage(TP::Framework::c_packageFullName);
+ }
+ else if (IsPackageStaged_Framework())
+ {
+ // We can't directly remove a Stage package not registered for current user
+ // w/o admin privilege but we can add it to make it registered and then remove it.
+ AddPackage_Framework();
+ TP::RemovePackage(TP::Framework::c_packageFullName);
+ }
+ }
+ inline void RemovePackageFamily_Framework()
+ {
+ RemovePackage_Framework();
+ }
+ inline bool IsPackageProvisioned_Framework()
+ {
+ return TP::IsPackageProvisioned(TP::Framework::c_packageFamilyName);
+ }
+ inline void ProvisionPackage_Framework()
+ {
+ TP::ProvisionPackage(TP::Framework::c_packageFamilyName);
+ }
+ inline void DeprovisionPackage_Framework()
+ {
+ TP::DeprovisionPackageIfNecessary(TP::Framework::c_packageFamilyName);
+ }
+
+ inline bool IsPackageRegistered_Main()
+ {
+ return TP::IsPackageRegistered(TP::Main::c_packageFullName);
+ }
+ inline bool IsPackageStaged_Main()
+ {
+ return TP::IsPackageStaged(TP::Main::c_packageFullName);
+ }
+ inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_Main()
+ {
+ return TP::GetPackageStatus(TP::Main::c_packageFullName);
+ }
+ inline void AddPackage_Main()
+ {
+ TP::AddPackageIfNecessary(TP::Main::c_packageDirName, TP::Main::c_packageFullName);
+ }
+ inline void AddPackageDefer_Main()
+ {
+ TP::AddPackageDeferIfNecessary(TP::Main::c_packageDirName, TP::Main::c_packageFullName);
+ }
+ inline void StagePackage_Main()
+ {
+ TP::StagePackageIfNecessary(TP::Main::c_packageDirName, TP::Main::c_packageFullName);
+ }
+ inline void RegisterPackage_Main()
+ {
+ TP::RegisterPackageIfNecessary(TP::Main::c_packageFullName);
+ }
+ inline void RemovePackage_Main()
+ {
+ if (IsPackageRegistered_Main())
+ {
+ TP::RemovePackage(TP::Main::c_packageFullName);
+ }
+ else if (IsPackageStaged_Main())
+ {
+ // We can't directly remove a Stage package not registered for current user
+ // w/o admin privilege but we can add it to make it registered and then remove it.
+ AddPackage_Main();
+ TP::RemovePackage(TP::Main::c_packageFullName);
+ }
+ }
+ inline void RemovePackageFamily_Main()
+ {
+ RemovePackage_Main();
+ }
+ inline bool IsPackageProvisioned_Main()
+ {
+ return TP::IsPackageProvisioned(TP::Main::c_packageFamilyName);
+ }
+ inline void ProvisionPackage_Main()
+ {
+ TP::ProvisionPackage(TP::Main::c_packageFamilyName);
+ }
+ inline void DeprovisionPackage_Main()
+ {
+ TP::DeprovisionPackageIfNecessary(TP::Main::c_packageFamilyName);
+ }
+
+ inline bool IsPackageRegistered_Mutable()
+ {
+ return TP::IsPackageRegistered(TP::Mutable::c_packageFullName);
+ }
+ inline bool IsPackageStaged_Mutable()
+ {
+ return TP::IsPackageStaged(TP::Mutable::c_packageFullName);
+ }
+ inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_Mutable()
+ {
+ return TP::GetPackageStatus(TP::Mutable::c_packageFullName);
+ }
+ inline void AddPackage_Mutable()
+ {
+ TP::AddPackageIfNecessary(TP::Mutable::c_packageDirName, TP::Mutable::c_packageFullName);
+ }
+ inline void AddPackageDefer_Mutable()
+ {
+ TP::AddPackageDeferIfNecessary(TP::Mutable::c_packageDirName, TP::Mutable::c_packageFullName);
+ }
+ inline void StagePackage_Mutable()
+ {
+ TP::StagePackageIfNecessary(TP::Mutable::c_packageDirName, TP::Mutable::c_packageFullName);
+ }
+ inline void RegisterPackage_Mutable()
+ {
+ TP::RegisterPackageIfNecessary(TP::Mutable::c_packageFullName);
+ }
+ inline void RemovePackage_Mutable()
+ {
+ if (IsPackageRegistered_Mutable())
+ {
+ TP::RemovePackage(TP::Mutable::c_packageFullName);
+ }
+ else if (IsPackageStaged_Mutable())
+ {
+ // We can't directly remove a Stage package not registered for current user
+ // w/o admin privilege but we can add it to make it registered and then remove it.
+ AddPackage_Mutable();
+ TP::RemovePackage(TP::Mutable::c_packageFullName);
+ }
+ }
+ inline void RemovePackageFamily_Mutable()
+ {
+ RemovePackage_Mutable();
+ }
+ inline bool IsPackageProvisioned_Mutable()
+ {
+ return TP::IsPackageProvisioned(TP::Mutable::c_packageFamilyName);
+ }
+ inline void ProvisionPackage_Mutable()
+ {
+ TP::ProvisionPackage(TP::Mutable::c_packageFamilyName);
+ }
+ inline void DeprovisionPackage_Mutable()
+ {
+ TP::DeprovisionPackageIfNecessary(TP::Mutable::c_packageFamilyName);
+ }
+
+ inline bool IsPackageRegistered_UserExternal()
+ {
+ return TP::IsPackageRegistered(TP::UserExternal::c_packageFullName);
+ }
+ inline bool IsPackageStaged_UserExternal()
+ {
+ return TP::IsPackageStaged(TP::UserExternal::c_packageFullName);
+ }
+ inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_UserExternal()
+ {
+ return TP::GetPackageStatus(TP::UserExternal::c_packageFullName);
+ }
+ inline void AddPackage_UserExternal()
+ {
+ const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName).parent_path()};
+ TP::AddPackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str());
+ }
+ inline void AddPackageDefer_UserExternal()
+ {
+ const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName).parent_path() };
+ TP::AddPackageDeferIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str());
+ }
+ inline void StagePackage_UserExternal()
+ {
+ const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName).parent_path() };
+ TP::StagePackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str());
+ }
+ inline void RegisterPackage_UserExternal()
+ {
+ TP::RegisterPackageIfNecessary(TP::UserExternal::c_packageFullName);
+ }
+ inline void RemovePackage_UserExternal()
+ {
+ if (IsPackageRegistered_UserExternal())
+ {
+ TP::RemovePackage(TP::UserExternal::c_packageFullName);
+ }
+ else if (IsPackageStaged_UserExternal())
+ {
+ // We can't directly remove a Stage package not registered for current user
+ // w/o admin privilege but we can add it to make it registered and then remove it.
+ AddPackage_UserExternal();
+ TP::RemovePackage(TP::UserExternal::c_packageFullName);
+ }
+ }
+ inline void RemovePackageFamily_UserExternal()
+ {
+ RemovePackage_UserExternal();
+ }
+ inline bool IsPackageProvisioned_UserExternal()
+ {
+ return TP::IsPackageProvisioned(TP::UserExternal::c_packageFamilyName);
+ }
+ inline void ProvisionPackage_UserExternal()
+ {
+ TP::ProvisionPackage(TP::UserExternal::c_packageFamilyName);
+ }
+ inline void DeprovisionPackage_UserExternal()
+ {
+ TP::DeprovisionPackageIfNecessary(TP::UserExternal::c_packageFamilyName);
+ }
+
+ inline bool IsPackageRegistered_MachineExternal()
+ {
+ return TP::IsPackageRegistered(TP::MachineExternal::c_packageFullName);
+ }
+ inline bool IsPackageStaged_MachineExternal()
+ {
+ return TP::IsPackageStaged(TP::MachineExternal::c_packageFullName);
+ }
+ inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_MachineExternal()
+ {
+ return TP::GetPackageStatus(TP::MachineExternal::c_packageFullName);
+ }
+ inline void AddPackage_MachineExternal()
+ {
+ const auto path{ TP::GetMsixPackagePath(TP::MachineExternal::c_packageDirName).parent_path()};
+ TP::AddPackageIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName, path.c_str());
+ }
+ inline void AddPackageDefer_MachineExternal()
+ {
+ const auto path{ TP::GetMsixPackagePath(TP::MachineExternal::c_packageDirName).parent_path() };
+ TP::AddPackageDeferIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName, path.c_str());
+ }
+ inline void StagePackage_MachineExternal()
+ {
+ const auto path{ TP::GetMsixPackagePath(TP::MachineExternal::c_packageDirName).parent_path() };
+ TP::StagePackageIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName, path.c_str());
+ }
+ inline void RegisterPackage_MachineExternal()
+ {
+ TP::RegisterPackageIfNecessary(TP::MachineExternal::c_packageFullName);
+ }
+ inline void RemovePackage_MachineExternal()
+ {
+ if (IsPackageRegistered_MachineExternal())
+ {
+ TP::RemovePackage(TP::MachineExternal::c_packageFullName);
+ }
+ else if (IsPackageStaged_MachineExternal())
+ {
+ // We can't directly remove a Stage package not registered for current user
+ // w/o admin privilege but we can add it to make it registered and then remove it.
+ AddPackage_MachineExternal();
+ TP::RemovePackage(TP::MachineExternal::c_packageFullName);
+ }
+ }
+ inline void RemovePackageFamily_MachineExternal()
+ {
+ RemovePackage_MachineExternal();
+ }
+ inline bool IsPackageProvisioned_MachineExternal()
+ {
+ return TP::IsPackageProvisioned(TP::MachineExternal::c_packageFamilyName);
+ }
+ inline void ProvisionPackage_MachineExternal()
+ {
+ TP::ProvisionPackage(TP::MachineExternal::c_packageFamilyName);
+ }
+ inline void DeprovisionPackage_MachineExternal()
+ {
+ TP::DeprovisionPackageIfNecessary(TP::MachineExternal::c_packageFamilyName);
+ }
+}
+
+#endif // __PACKAGETESTS_PACKAGES_H
diff --git a/test/Package/API/PackageTests.vcxproj b/test/Package/API/PackageTests.vcxproj
new file mode 100644
index 0000000000..5d8b590aa1
--- /dev/null
+++ b/test/Package/API/PackageTests.vcxproj
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ 16.0
+ {f8a40421-cede-4ba2-8df5-d00c33df16b7}
+ Win32Proj
+ PackageTests
+ 10.0
+ NativeUnitTestProject
+ PackageTests
+
+
+ DynamicLibrary
+ false
+ v143
+ Unicode
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use
+ true
+ pch.h
+ $(MSBuildThisFileDirectory);$(RepoRoot)\test\inc;$(RepoRoot)\dev\common;$(VCInstallDir)UnitTest\include;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories)
+ $(RepoRoot);%(AdditionalIncludeDirectories)
+
+
+ Windows
+ onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
+ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
+ Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
+ Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs)
+ api-ms-win-appmodel-runtime-l1-1-5.dll;%(DelayLoadDLLs)
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+
+
+ WIN32;%(PreprocessorDefinitions)
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.winmd
+ true
+
+
+
+
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd
+ true
+
+
+
+
+
+
+
+ {f76b776e-86f5-48c5-8fc7-d2795ecc9746}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/API/PackageTests.vcxproj.filters b/test/Package/API/PackageTests.vcxproj.filters
new file mode 100644
index 0000000000..930d5a96a5
--- /dev/null
+++ b/test/Package/API/PackageTests.vcxproj.filters
@@ -0,0 +1,57 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+
+
diff --git a/test/Package/API/PackageTests_PackageGraph_Base.h b/test/Package/API/PackageTests_PackageGraph_Base.h
new file mode 100644
index 0000000000..90de854625
--- /dev/null
+++ b/test/Package/API/PackageTests_PackageGraph_Base.h
@@ -0,0 +1,112 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include
+
+namespace TD = ::Test::Diagnostics;
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+namespace TD = ::Test::Diagnostics;
+
+namespace Test::Package::Tests
+{
+ constexpr auto Framework_PackageFamilyName{ ::TP::Framework::c_packageFamilyName };
+ constexpr auto Framework_PackageFullName{ ::TP::Framework::c_packageFullName };
+ constexpr auto Main_PackageFamilyName{ ::TP::Main::c_packageFamilyName };
+ constexpr auto Main_PackageFullName{ ::TP::Main::c_packageFullName };
+ constexpr auto Mutable_PackageFamilyName{ ::TP::Mutable::c_packageFamilyName };
+ constexpr auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName };
+ constexpr auto UserExternal_PackageFamilyName{ ::TP::UserExternal::c_packageFamilyName };
+ constexpr auto UserExternal_PackageFullName{ ::TP::UserExternal::c_packageFullName };
+ constexpr auto MachineExternal_PackageFamilyName{ ::TP::MachineExternal::c_packageFamilyName };
+ constexpr auto MachineExternal_PackageFullName{ ::TP::MachineExternal::c_packageFullName };
+
+ class PackageTests_PackageGraph_Base
+ {
+ private:
+ wil::unique_package_dependency_context m_windowsAppRuntimeFramework_packageDependencyContext;
+
+ protected:
+ bool ClassSetup()
+ {
+ if (!::WindowsVersion::IsWindows11_24H2OrGreater())
+ {
+ WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests");
+ return true;
+ }
+
+ RemovePackage_MachineExternal();
+ RemovePackage_UserExternal();
+ RemovePackage_Mutable();
+ RemovePackage_Main();
+ RemovePackage_Framework();
+ ::TP::RemovePackage_WindowsAppRuntimeFramework();
+
+ ::TP::AddPackage_WindowsAppRuntimeFramework();
+ AddPackage_Framework();
+ AddPackage_Main();
+ AddPackage_Mutable();
+ AddPackage_UserExternal();
+ StagePackage_MachineExternal();
+ RegisterPackage_MachineExternal();
+
+ constexpr std::int32_t frameworkRank{ 1000 };
+ m_windowsAppRuntimeFramework_packageDependencyContext.reset(AddDynamicDependency(::TP::WindowsAppRuntimeFramework::c_PackageFamilyName, frameworkRank));
+
+ return true;
+ }
+
+ bool ClassCleanup()
+ {
+ m_windowsAppRuntimeFramework_packageDependencyContext.reset();
+
+ RemovePackage_MachineExternal();
+ RemovePackage_UserExternal();
+ RemovePackage_Mutable();
+ RemovePackage_Main();
+ RemovePackage_Framework();
+ ::TP::RemovePackage_WindowsAppRuntimeFramework();
+
+ return true;
+ }
+
+ public:
+ PACKAGEDEPENDENCY_CONTEXT AddDynamicDependency(
+ PCWSTR packageFamilyName,
+ const std::int32_t rank = -1000)
+ {
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AddDynamicDependency(): %ls", packageFamilyName));
+
+ const PACKAGE_VERSION minVersion{};
+ const auto architectures{ PackageDependencyProcessorArchitectures_None };
+ const auto lifetimeKind{ PackageDependencyLifetimeKind_Process};
+ const auto tryCreateOptions{ CreatePackageDependencyOptions_None };
+ wil::unique_process_heap_string packageDependencyId;
+ VERIFY_SUCCEEDED(::TryCreatePackageDependency(nullptr, packageFamilyName, minVersion, architectures, lifetimeKind, nullptr, tryCreateOptions, wil::out_param(packageDependencyId)));
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"PackageDependencyId: %ls", packageDependencyId.get()));
+
+ PACKAGEDEPENDENCY_CONTEXT packageDependencyContext{};
+ const auto addOptions{ AddPackageDependencyOptions_None };
+ wil::unique_process_heap_string packageFullName;
+ VERIFY_SUCCEEDED(::AddPackageDependency(packageDependencyId.get(), rank, addOptions, &packageDependencyContext, wil::out_param(packageFullName)));
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"PackageDependencyContext: %p", packageDependencyId.get()));
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"PackageFullName: %ls", packageFullName.get()));
+
+ VERIFY_SUCCEEDED(::DeletePackageDependency(packageDependencyId.get()));
+
+ return packageDependencyContext;
+ }
+
+ PACKAGEDEPENDENCY_CONTEXT AddDynamicDependency(
+ const std::wstring& packageFamilyName)
+ {
+ return AddDynamicDependency(packageFamilyName.c_str());
+ }
+
+ PACKAGEDEPENDENCY_CONTEXT AddDynamicDependency(
+ const winrt::hstring& packageFamilyName)
+ {
+ return AddDynamicDependency(packageFamilyName.c_str());
+ }
+ };
+}
diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp
new file mode 100644
index 0000000000..1137839abd
--- /dev/null
+++ b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp
@@ -0,0 +1,175 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+#include
+
+#include
+
+#include "PackageTests_PackageGraph_Base.h"
+
+namespace TD = ::Test::Diagnostics;
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+namespace TD = ::Test::Diagnostics;
+
+namespace Test::Package::Tests
+{
+ class PackageTests_PackageGraph_Packaged_CPP : PackageTests_PackageGraph_Base
+ {
+ public:
+ BEGIN_TEST_CLASS(PackageTests_PackageGraph_Packaged_CPP)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
+ TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
+ TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust")
+ END_TEST_CLASS()
+
+ TEST_CLASS_SETUP(ClassSetup)
+ {
+ // Windows App SDK's Dynamic Dependency API doesn't support packaged processes
+ // Use the OS Dynamic Dependency API (if available)
+ if (!::WindowsVersion::IsWindows11_24H2OrGreater())
+ {
+ WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests");
+ return true;
+ }
+
+ return PackageTests_PackageGraph_Base::ClassSetup();
+ }
+
+ TEST_CLASS_CLEANUP(ClassCleanup)
+ {
+ return PackageTests_PackageGraph_Base::ClassCleanup();
+ }
+
+ TEST_METHOD(GetFilePath)
+ {
+ PCWSTR packageFullName{ Framework_PackageFullName };
+ PCWSTR packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_None };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges
+ // with Mutable or External locations so we'll resolve the Install path
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) };
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_InstallPath)
+ {
+ PCWSTR packageFullName{ Framework_PackageFullName };
+ PCWSTR packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_SearchInstallPath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) };
+ VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get()));
+ }
+
+ TEST_METHOD(GetFilePath_MutablePath)
+ {
+ PCWSTR packageFullName{ Mutable_PackageFullName };
+ PCWSTR packageFamilyName{ Mutable_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_SearchMutablePath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ std::filesystem::path expected;
+ if (IsMutableLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable);
+ }
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_MachineExternalPath)
+ {
+ PCWSTR packageFullName{ MachineExternal_PackageFullName };
+ PCWSTR packageFamilyName{ MachineExternal_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal);
+ }
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_UserExternalPath)
+ {
+ PCWSTR packageFullName{ UserExternal_PackageFullName };
+ PCWSTR packageFamilyName{ UserExternal_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchUserExternalPath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal);
+ }
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch)
+ {
+ PCWSTR packageFamilyName{ Main_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchInstallPath |
+ GetPackageFilePathOptions_SearchFrameworkPackages };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+ VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get())));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch)
+ {
+ PCWSTR packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchInstallPath |
+ GetPackageFilePathOptions_SearchMainPackages };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+ VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get())));
+ }
+ };
+}
diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp
new file mode 100644
index 0000000000..8cf75c2ad0
--- /dev/null
+++ b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp
@@ -0,0 +1,195 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+#include
+
+#include "PackageTests_PackageGraph_Base.h"
+
+namespace TD = ::Test::Diagnostics;
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+namespace TD = ::Test::Diagnostics;
+
+static const winrt::hstring null_hstring;
+
+namespace Test::Package::Tests
+{
+ class PackageTests_PackageGraph_Packaged_WinRT : PackageTests_PackageGraph_Base
+ {
+ public:
+ BEGIN_TEST_CLASS(PackageTests_PackageGraph_Packaged_WinRT)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
+ TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
+ TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust")
+ END_TEST_CLASS()
+
+ TEST_CLASS_SETUP(ClassSetup)
+ {
+ // Windows App SDK's Dynamic Dependency API doesn't support packaged processes
+ // Use the OS Dynamic Dependency API (if available)
+ if (!::WindowsVersion::IsWindows11_24H2OrGreater())
+ {
+ WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests");
+ return true;
+ }
+
+ return PackageTests_PackageGraph_Base::ClassSetup();
+ }
+
+ TEST_CLASS_CLEANUP(ClassCleanup)
+ {
+ return PackageTests_PackageGraph_Base::ClassCleanup();
+ }
+
+ TEST_METHOD(GetFilePath_InvalidParameter)
+ {
+ try
+ {
+ winrt::hstring noFileName;
+ std::ignore = winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(noFileName);
+ VERIFY_FAIL(L"Success is not expected");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str()));
+ }
+
+ try
+ {
+ winrt::hstring noFileName;
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None };
+ std::ignore = winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(noFileName, options);
+ VERIFY_FAIL(L"Success is not expected");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str()));
+ }
+ }
+
+ TEST_METHOD(GetFilePath)
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges
+ // with Mutable or External locations so we'll resolve the Install path
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) };
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_InstallPath)
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) };
+ VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()});
+ }
+
+ TEST_METHOD(GetFilePath_MutablePath)
+ {
+ winrt::hstring packageFullName{ Mutable_PackageFullName };
+ winrt::hstring packageFamilyName{ Mutable_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ std::filesystem::path expected;
+ if (IsMutableLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable);
+ }
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_MachineExternalPath)
+ {
+ winrt::hstring packageFullName{ MachineExternal_PackageFullName };
+ winrt::hstring packageFamilyName{ MachineExternal_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal);
+ }
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_UserExternalPath)
+ {
+ winrt::hstring packageFullName{ UserExternal_PackageFullName };
+ winrt::hstring packageFamilyName{ UserExternal_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal);
+ }
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch)
+ {
+ winrt::hstring packageFullName{ Main_PackageFullName };
+ winrt::hstring packageFamilyName{ Main_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath |
+ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+ VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch)
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath |
+ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+ VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str()));
+ }
+ };
+}
diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp
new file mode 100644
index 0000000000..df13bb7126
--- /dev/null
+++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp
@@ -0,0 +1,183 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+#include
+
+#include
+
+#include "PackageTests_PackageGraph_Base.h"
+
+namespace TD = ::Test::Diagnostics;
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+namespace TD = ::Test::Diagnostics;
+
+namespace Test::Package::Tests
+{
+ class PackageTests_PackageGraph_Unpackaged_CPP : PackageTests_PackageGraph_Base
+ {
+ public:
+ BEGIN_TEST_CLASS(PackageTests_PackageGraph_Unpackaged_CPP)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
+ TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser")
+ END_TEST_CLASS()
+
+ TEST_CLASS_SETUP(ClassSetup)
+ {
+ if (!::WindowsVersion::IsWindows11_24H2OrGreater())
+ {
+ WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests");
+ return true;
+ }
+
+ return PackageTests_PackageGraph_Base::ClassSetup();
+ }
+
+ TEST_CLASS_CLEANUP(ClassCleanup)
+ {
+ return PackageTests_PackageGraph_Base::ClassCleanup();
+ }
+
+ TEST_METHOD(GetFilePath_InvalidParameter)
+ {
+ PCWSTR packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR noFileName{};
+ wil::unique_process_heap_ptr absoluteFilename;
+ const auto options{ GetPackageFilePathOptions_None };
+ VERIFY_ARE_EQUAL(E_INVALIDARG, ::GetPackageFilePathInPackageGraph(noFileName, options, wil::out_param(absoluteFilename)));
+ }
+
+ TEST_METHOD(GetFilePath)
+ {
+ PCWSTR packageFullName{ Framework_PackageFullName };
+ PCWSTR packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_None };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges
+ // with Mutable or External locations so we'll resolve the Install path
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) };
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_InstallPath)
+ {
+ PCWSTR packageFullName{ Framework_PackageFullName };
+ PCWSTR packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_SearchInstallPath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) };
+ VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get()));
+ }
+
+ TEST_METHOD(GetFilePath_MutablePath)
+ {
+ PCWSTR packageFullName{ Mutable_PackageFullName };
+ PCWSTR packageFamilyName{ Mutable_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_SearchMutablePath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ std::filesystem::path expected;
+ if (IsMutableLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable);
+ }
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_MachineExternalPath)
+ {
+ PCWSTR packageFullName{ MachineExternal_PackageFullName };
+ PCWSTR packageFamilyName{ MachineExternal_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal);
+ }
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_UserExternalPath)
+ {
+ PCWSTR packageFullName{ UserExternal_PackageFullName };
+ PCWSTR packageFamilyName{ UserExternal_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchUserExternalPath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal);
+ }
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch)
+ {
+ PCWSTR packageFamilyName{ Main_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchInstallPath |
+ GetPackageFilePathOptions_SearchFrameworkPackages };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+ VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get())));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch)
+ {
+ PCWSTR packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchInstallPath |
+ GetPackageFilePathOptions_SearchMainPackages };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename)));
+ VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get())));
+ }
+ };
+}
diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp
new file mode 100644
index 0000000000..2906fbec3b
--- /dev/null
+++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp
@@ -0,0 +1,190 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+#include
+
+#include "PackageTests_PackageGraph_Base.h"
+
+namespace TD = ::Test::Diagnostics;
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+namespace TD = ::Test::Diagnostics;
+
+static const winrt::hstring null_hstring;
+
+namespace Test::Package::Tests
+{
+ class PackageTests_PackageGraph_Unpackaged_WinRT : PackageTests_PackageGraph_Base
+ {
+ public:
+ BEGIN_TEST_CLASS(PackageTests_PackageGraph_Unpackaged_WinRT)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
+ TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser")
+ END_TEST_CLASS()
+
+ TEST_CLASS_SETUP(ClassSetup)
+ {
+ if (!::WindowsVersion::IsWindows11_24H2OrGreater())
+ {
+ WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests");
+ return true;
+ }
+
+ return PackageTests_PackageGraph_Base::ClassSetup();
+ }
+
+ TEST_CLASS_CLEANUP(ClassCleanup)
+ {
+ return PackageTests_PackageGraph_Base::ClassCleanup();
+ }
+
+ TEST_METHOD(GetFilePath_InvalidParameter)
+ {
+ try
+ {
+ winrt::hstring noFileName;
+ std::ignore = winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(noFileName);
+ VERIFY_FAIL(L"Success is not expected");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str()));
+ }
+
+ try
+ {
+ winrt::hstring noFileName;
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None };
+ std::ignore = winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(noFileName, options);
+ VERIFY_FAIL(L"Success is not expected");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str()));
+ }
+ }
+
+ TEST_METHOD(GetFilePath)
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges
+ // with Mutable or External locations so we'll resolve the Install path
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) };
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_InstallPath)
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) };
+ VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()});
+ }
+
+ TEST_METHOD(GetFilePath_MutablePath)
+ {
+ winrt::hstring packageFullName{ Mutable_PackageFullName };
+ winrt::hstring packageFamilyName{ Mutable_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ std::filesystem::path expected;
+ if (IsMutableLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable);
+ }
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_MachineExternalPath)
+ {
+ winrt::hstring packageFullName{ MachineExternal_PackageFullName };
+ winrt::hstring packageFamilyName{ MachineExternal_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal);
+ }
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_UserExternalPath)
+ {
+ winrt::hstring packageFullName{ UserExternal_PackageFullName };
+ winrt::hstring packageFamilyName{ UserExternal_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal);
+ }
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch)
+ {
+ winrt::hstring packageFamilyName{ Main_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath |
+ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+ VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch)
+ {
+ winrt::hstring packageFamilyName{ Framework_PackageFamilyName };
+ wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) };
+
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath |
+ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) };
+ VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str()));
+ }
+ };
+}
diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp
new file mode 100644
index 0000000000..bf1b689f3a
--- /dev/null
+++ b/test/Package/API/PackageTests_Package_CPP.cpp
@@ -0,0 +1,229 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+#include
+
+#include
+
+namespace TD = ::Test::Diagnostics;
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+namespace TD = ::Test::Diagnostics;
+
+namespace Test::Package::Tests
+{
+ const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName };
+ const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName };
+ const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName };
+ const auto UserExternal_PackageFullName{ ::TP::UserExternal::c_packageFullName };
+ const auto MachineExternal_PackageFullName{ ::TP::MachineExternal::c_packageFullName };
+
+ class PackageTests_Package_CPP
+ {
+ public:
+ BEGIN_TEST_CLASS(PackageTests_Package_CPP)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
+ TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser")
+ END_TEST_CLASS()
+
+ public:
+ TEST_CLASS_SETUP(ClassSetup)
+ {
+ ::TB::Setup();
+
+ if (IsExternalLocationSupported())
+ {
+ RemovePackage_MachineExternal();
+ RemovePackage_UserExternal();
+ }
+ if (IsMutableLocationSupported())
+ {
+ RemovePackage_Mutable();
+ }
+
+ if (IsMutableLocationSupported())
+ {
+ AddPackage_Mutable();
+ }
+ if (IsExternalLocationSupported())
+ {
+ AddPackage_UserExternal();
+ StagePackage_MachineExternal();
+ AddPackage_MachineExternal();
+ }
+
+ return true;
+ }
+
+ TEST_CLASS_CLEANUP(ClassCleanup)
+ {
+ ::TB::Cleanup();
+
+ if (IsExternalLocationSupported())
+ {
+ RemovePackage_MachineExternal();
+ RemovePackage_UserExternal();
+ }
+ if (IsMutableLocationSupported())
+ {
+ RemovePackage_Mutable();
+ }
+
+ return true;
+ }
+
+ TEST_METHOD(GetPackageFilePath_InvalidParameter)
+ {
+ PCWSTR packageFullName{ Framework_PackageFullName };
+ PCWSTR noFileName{};
+ wil::unique_process_heap_ptr absoluteFilename;
+ const auto options{ GetPackageFilePathOptions_None };
+ VERIFY_ARE_EQUAL(E_INVALIDARG, ::GetPackageFilePath(packageFullName, noFileName, options, wil::out_param(absoluteFilename)));
+ }
+
+ TEST_METHOD(GetPackageFilePath_NullPackageFullName_UnpackagedProcess_NoPackage)
+ {
+ PCWSTR noPackageFullName{};
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_None };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), ::GetPackageFilePath(noPackageFullName, fileName, options, wil::out_param(absoluteFilename)));
+ }
+
+ TEST_METHOD(GetPackageFilePath_NoSuchPackage)
+ {
+ PCWSTR packageFullName{ L"Does.Not.Exist_1.2.3.4_neutral__1234567890abc" };
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_None };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"Actual:%ls", !absoluteFilename ? L"" : absoluteFilename.get()));
+ }
+
+ TEST_METHOD(GetPackageFilePath)
+ {
+ PCWSTR packageFullName{ Framework_PackageFullName };
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_None };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ // GetPackageFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges
+ // with Mutable or External locations so we'll resolve the Install path
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) };
+ const std::filesystem::path actual{ !absoluteFilename ? L"" : absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetPackageFilePath_InstallPath)
+ {
+ PCWSTR packageFullName{ Framework_PackageFullName };
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_SearchInstallPath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) };
+ VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()});
+ }
+
+ TEST_METHOD(GetPackageFilePath_MutablePath)
+ {
+ PCWSTR packageFullName{ Mutable_PackageFullName };
+ PCWSTR fileName{ L"AppxManifest.xml" };
+ const auto options{ GetPackageFilePathOptions_SearchMutablePath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ std::filesystem::path expected;
+ if (IsMutableLocationSupported())
+ {
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable);
+ }
+ else
+ {
+ VERIFY_IS_NULL(absoluteFilename);
+ }
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetPackageFilePath_MachineExternalPath)
+ {
+ PCWSTR packageFullName{ MachineExternal_PackageFullName };
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal);
+ }
+ else
+ {
+ VERIFY_IS_NULL(absoluteFilename);
+ }
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetPackageFilePath_UserExternalPath)
+ {
+ PCWSTR packageFullName{ UserExternal_PackageFullName };
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchUserExternalPath };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)));
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get()));
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ VERIFY_IS_NOT_NULL(absoluteFilename);
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal);
+ }
+ else
+ {
+ VERIFY_IS_NULL(absoluteFilename);
+ }
+ const std::filesystem::path actual{ absoluteFilename.get() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetPackageFilePath_FilterPackageType_Main_NoMatch)
+ {
+ PCWSTR packageFullName{ Main_PackageFullName };
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchInstallPath |
+ GetPackageFilePathOptions_SearchFrameworkPackages };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)));
+ VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get())));
+ }
+
+ TEST_METHOD(GetPackageFilePath_FilterPackageType_Framework_NoMatch)
+ {
+ PCWSTR packageFullName{ Framework_PackageFullName };
+ PCWSTR fileName{ L"Shadow.cat" };
+ const auto options{ GetPackageFilePathOptions_SearchInstallPath |
+ GetPackageFilePathOptions_SearchMainPackages };
+ wil::unique_process_heap_ptr absoluteFilename;
+ VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)));
+ VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get())));
+ }
+ };
+}
diff --git a/test/Package/API/PackageTests_Package_WinRT.cpp b/test/Package/API/PackageTests_Package_WinRT.cpp
new file mode 100644
index 0000000000..ca563a8fbd
--- /dev/null
+++ b/test/Package/API/PackageTests_Package_WinRT.cpp
@@ -0,0 +1,269 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+#include
+
+namespace TD = ::Test::Diagnostics;
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+namespace TD = ::Test::Diagnostics;
+
+static const winrt::hstring null_hstring;
+
+namespace Test::Package::Tests
+{
+ const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName };
+ const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName };
+ const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName };
+ const auto UserExternal_PackageFullName{ ::TP::UserExternal::c_packageFullName };
+ const auto MachineExternal_PackageFullName{ ::TP::MachineExternal::c_packageFullName };
+
+ class PackageTests_Package_WinRT
+ {
+ public:
+ BEGIN_TEST_CLASS(PackageTests_Package_WinRT)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
+ TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser")
+ END_TEST_CLASS()
+
+ private:
+ bool IsMutableLocationSupported() const
+ {
+ return winrt::Microsoft::Windows::ApplicationModel::Package::IsFeatureSupported(winrt::Microsoft::Windows::ApplicationModel::PackageFeature::PackagePath_Mutable);
+ }
+
+ bool IsExternalLocationSupported() const
+ {
+ return winrt::Microsoft::Windows::ApplicationModel::Package::IsFeatureSupported(winrt::Microsoft::Windows::ApplicationModel::PackageFeature::PackagePath_ExternalLocation);
+ }
+
+
+ public:
+ TEST_CLASS_SETUP(ClassSetup)
+ {
+ ::TB::Setup();
+
+ if (IsExternalLocationSupported())
+ {
+ RemovePackage_MachineExternal();
+ RemovePackage_UserExternal();
+ }
+ if (IsMutableLocationSupported())
+ {
+ RemovePackage_Mutable();
+ }
+
+ if (IsMutableLocationSupported())
+ {
+ AddPackage_Mutable();
+ }
+ if (IsExternalLocationSupported())
+ {
+ AddPackage_UserExternal();
+ StagePackage_MachineExternal();
+ AddPackage_MachineExternal();
+ }
+
+ return true;
+ }
+
+ TEST_CLASS_CLEANUP(ClassCleanup)
+ {
+ ::TB::Cleanup();
+
+ if (IsExternalLocationSupported())
+ {
+ RemovePackage_MachineExternal();
+ RemovePackage_UserExternal();
+ }
+ if (IsMutableLocationSupported())
+ {
+ RemovePackage_Mutable();
+ }
+
+ return true;
+ }
+
+ TEST_METHOD(GetFilePath_InvalidParameter)
+ {
+ try
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring noFileName;
+ std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noFileName, packageFullName);
+ VERIFY_FAIL(L"Success is not expected");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str()));
+ }
+
+ try
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring noFileName;
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None };
+ std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noFileName, packageFullName, options);
+ VERIFY_FAIL(L"Success is not expected");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str()));
+ }
+ }
+
+ TEST_METHOD(GetFilePath_NullPackageFullName_UnpackagedProcess_NoPackage)
+ {
+ try
+ {
+ winrt::hstring noPackageFullName;
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, noPackageFullName);
+ VERIFY_FAIL(L"Success is not expected");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str()));
+ }
+
+ try
+ {
+ winrt::hstring noPackageFullName;
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None };
+ std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, noPackageFullName, options);
+ VERIFY_FAIL(L"Success is not expected");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str()));
+ }
+ }
+
+ TEST_METHOD(GetFilePath_NoSuchPackage)
+ {
+ winrt::hstring packageFullName{ L"Does.Not.Exist_1.2.3.4_neutral__1234567890abc" };
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_TRUE(absoluteFilename.empty());
+ }
+
+ TEST_METHOD(GetFilePath)
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges
+ // with Mutable or External locations so we'll resolve the Install path
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) };
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_InstallPath)
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) };
+ VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()});
+ }
+
+ TEST_METHOD(GetFilePath_MutablePath)
+ {
+ winrt::hstring packageFullName{ Mutable_PackageFullName };
+ winrt::hstring fileName{ L"AppxManifest.xml" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ std::filesystem::path expected;
+ if (IsMutableLocationSupported())
+ {
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable);
+ }
+ else
+ {
+ VERIFY_IS_TRUE(absoluteFilename.empty());
+ }
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_MachineExternalPath)
+ {
+ winrt::hstring packageFullName{ MachineExternal_PackageFullName };
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal);
+ }
+ else
+ {
+ VERIFY_IS_TRUE(absoluteFilename.empty());
+ }
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_UserExternalPath)
+ {
+ winrt::hstring packageFullName{ UserExternal_PackageFullName };
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) };
+
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str()));
+ std::filesystem::path expected;
+ if (IsExternalLocationSupported())
+ {
+ VERIFY_IS_FALSE(absoluteFilename.empty());
+ expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal);
+ }
+ else
+ {
+ VERIFY_IS_TRUE(absoluteFilename.empty());
+ }
+ const std::filesystem::path actual{ absoluteFilename.c_str() };
+ VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch)
+ {
+ winrt::hstring packageFullName{ Main_PackageFullName };
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath |
+ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) };
+ VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str()));
+ }
+
+ TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch)
+ {
+ winrt::hstring packageFullName{ Framework_PackageFullName };
+ winrt::hstring fileName{ L"Shadow.cat" };
+ const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath |
+ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages };
+ const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) };
+ VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str()));
+ }
+ };
+}
diff --git a/test/Package/API/Test.testdef b/test/Package/API/Test.testdef
new file mode 100644
index 0000000000..c843bed7ad
--- /dev/null
+++ b/test/Package/API/Test.testdef
@@ -0,0 +1,11 @@
+{
+ "Tests": [
+ {
+ "Description": "PackageTests tests for feature Package",
+ "Filename": "PackageTests.dll",
+ "Parameters": "",
+ "Architectures": ["x86", "x64", "arm64"],
+ "Status": "Enabled"
+ }
+ ]
+}
diff --git a/test/Package/API/dllmain.cpp b/test/Package/API/dllmain.cpp
new file mode 100644
index 0000000000..1e024a3c62
--- /dev/null
+++ b/test/Package/API/dllmain.cpp
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+
+// Including this file once per binary will automatically opt WIL error handling macros into calling RoOriginateError when they
+// begin logging a new error. This greatly improves the debuggability of errors that propagate before a failfast.
+#include
+
+BOOL APIENTRY DllMain(HMODULE hmodule, DWORD reason, LPVOID reserved)
+{
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hmodule);
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ break;
+ }
+
+ // Give WIL a crack at DLLMain processing
+ // See DLLMain() in wil/result_macros.h for why
+ wil::DLLMain(hmodule, reason, reserved);
+
+ return TRUE;
+}
diff --git a/test/Package/API/packages.config b/test/Package/API/packages.config
new file mode 100644
index 0000000000..0c13ff7b9c
--- /dev/null
+++ b/test/Package/API/packages.config
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/API/pch.cpp b/test/Package/API/pch.cpp
new file mode 100644
index 0000000000..f59e66e263
--- /dev/null
+++ b/test/Package/API/pch.cpp
@@ -0,0 +1,6 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
diff --git a/test/Package/API/pch.h b/test/Package/API/pch.h
new file mode 100644
index 0000000000..8c49dacc88
--- /dev/null
+++ b/test/Package/API/pch.h
@@ -0,0 +1,42 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#ifndef PCH_H
+#define PCH_H
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#endif //PCH_H
diff --git a/test/Package/data/Framework/Package.Framework.vcxproj.filters b/test/Package/data/Framework/Package.Framework.vcxproj.filters
new file mode 100644
index 0000000000..2df21c891a
--- /dev/null
+++ b/test/Package/data/Framework/Package.Framework.vcxproj.filters
@@ -0,0 +1,17 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj b/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj
new file mode 100644
index 0000000000..2fcb8fc520
--- /dev/null
+++ b/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ {F41B5211-4E18-4625-96A3-0130001B57C8}
+ VCProjectVersion
+ Package.Test.Mutable.Msix
+ en-US
+ 16.0
+ 10.0.26100.0
+ 10.0.17763.0
+ 10.0
+
+
+ Utility
+ v143
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(TargetName)
+
+
+
+
+
+
+
+ $(RepoTestCertificatePFX)
+ $(RepoTestCertificatePassword)
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj.filters b/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj.filters
new file mode 100644
index 0000000000..2df21c891a
--- /dev/null
+++ b/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj.filters
@@ -0,0 +1,17 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Framework/Shadow.cat b/test/Package/data/Framework/Shadow.cat
new file mode 100644
index 0000000000..defd12bba0
--- /dev/null
+++ b/test/Package/data/Framework/Shadow.cat
@@ -0,0 +1 @@
+Catch me if you can...
diff --git a/test/Package/data/Framework/appxmanifest.xml b/test/Package/data/Framework/appxmanifest.xml
new file mode 100644
index 0000000000..35e0cfed85
--- /dev/null
+++ b/test/Package/data/Framework/appxmanifest.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+ Test.Package.Framework
+ Microsoft Corporation
+ logo.png
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Framework/logo.png b/test/Package/data/Framework/logo.png
new file mode 100644
index 0000000000..5bd7c0ce4d
Binary files /dev/null and b/test/Package/data/Framework/logo.png differ
diff --git a/test/Package/data/Framework/packages.config b/test/Package/data/Framework/packages.config
new file mode 100644
index 0000000000..d9db55a1b3
--- /dev/null
+++ b/test/Package/data/Framework/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj b/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj
new file mode 100644
index 0000000000..dcfd668959
--- /dev/null
+++ b/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ {3347E246-6BF5-469F-9C91-7D6E33B66786}
+ VCProjectVersion
+ Package.Test.UserExternal.Msix
+ en-US
+ 16.0
+ 10.0.26100.0
+ 10.0.17763.0
+ 10.0
+
+
+ Utility
+ v143
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(TargetName)
+
+
+
+
+
+
+ $(RepoTestCertificatePFX)
+ $(RepoTestCertificatePassword)
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj.filters b/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj.filters
new file mode 100644
index 0000000000..93e09be5b1
--- /dev/null
+++ b/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj.filters
@@ -0,0 +1,12 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
diff --git a/test/Package/data/MachineExternal/Package.Test.MachineExternal.vcxproj.filters b/test/Package/data/MachineExternal/Package.Test.MachineExternal.vcxproj.filters
new file mode 100644
index 0000000000..fb91a1a002
--- /dev/null
+++ b/test/Package/data/MachineExternal/Package.Test.MachineExternal.vcxproj.filters
@@ -0,0 +1,15 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/MachineExternal/Shadow.cat b/test/Package/data/MachineExternal/Shadow.cat
new file mode 100644
index 0000000000..defd12bba0
--- /dev/null
+++ b/test/Package/data/MachineExternal/Shadow.cat
@@ -0,0 +1 @@
+Catch me if you can...
diff --git a/test/Package/data/MachineExternal/appxmanifest.xml b/test/Package/data/MachineExternal/appxmanifest.xml
new file mode 100644
index 0000000000..eb2ff59152
--- /dev/null
+++ b/test/Package/data/MachineExternal/appxmanifest.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ Test.Package.MachineExternal
+ Microsoft Corporation
+ logo.png
+ true
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/MachineExternal/logo.png b/test/Package/data/MachineExternal/logo.png
new file mode 100644
index 0000000000..5bd7c0ce4d
Binary files /dev/null and b/test/Package/data/MachineExternal/logo.png differ
diff --git a/test/Package/data/MachineExternal/packages.config b/test/Package/data/MachineExternal/packages.config
new file mode 100644
index 0000000000..d9db55a1b3
--- /dev/null
+++ b/test/Package/data/MachineExternal/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/test/Package/data/Main/Package.Main.vcxproj.filters b/test/Package/data/Main/Package.Main.vcxproj.filters
new file mode 100644
index 0000000000..2df21c891a
--- /dev/null
+++ b/test/Package/data/Main/Package.Main.vcxproj.filters
@@ -0,0 +1,17 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Main/Package.Test.Main.msix.vcxproj b/test/Package/data/Main/Package.Test.Main.msix.vcxproj
new file mode 100644
index 0000000000..dfd05f7fc9
--- /dev/null
+++ b/test/Package/data/Main/Package.Test.Main.msix.vcxproj
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ {472B8D93-9200-48B7-BFB6-9D9B85AA4025}
+ VCProjectVersion
+ Package.Test.Mutable.Msix
+ en-US
+ 16.0
+ 10.0.26100.0
+ 10.0.17763.0
+ 10.0
+
+
+ Utility
+ v143
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(TargetName)
+
+
+
+
+
+
+
+ $(RepoTestCertificatePFX)
+ $(RepoTestCertificatePassword)
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Main/Package.Test.Main.msix.vcxproj.filters b/test/Package/data/Main/Package.Test.Main.msix.vcxproj.filters
new file mode 100644
index 0000000000..2df21c891a
--- /dev/null
+++ b/test/Package/data/Main/Package.Test.Main.msix.vcxproj.filters
@@ -0,0 +1,17 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Main/Shadow.cat b/test/Package/data/Main/Shadow.cat
new file mode 100644
index 0000000000..defd12bba0
--- /dev/null
+++ b/test/Package/data/Main/Shadow.cat
@@ -0,0 +1 @@
+Catch me if you can...
diff --git a/test/Package/data/Main/appxmanifest.xml b/test/Package/data/Main/appxmanifest.xml
new file mode 100644
index 0000000000..55c6405f73
--- /dev/null
+++ b/test/Package/data/Main/appxmanifest.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ Test.Package.Main
+ Microsoft Corporation
+ logo.png
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Main/logo.png b/test/Package/data/Main/logo.png
new file mode 100644
index 0000000000..5bd7c0ce4d
Binary files /dev/null and b/test/Package/data/Main/logo.png differ
diff --git a/test/Package/data/Main/packages.config b/test/Package/data/Main/packages.config
new file mode 100644
index 0000000000..d9db55a1b3
--- /dev/null
+++ b/test/Package/data/Main/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/test/Package/data/Mutable/Package.Mutable.vcxproj.filters b/test/Package/data/Mutable/Package.Mutable.vcxproj.filters
new file mode 100644
index 0000000000..2df21c891a
--- /dev/null
+++ b/test/Package/data/Mutable/Package.Mutable.vcxproj.filters
@@ -0,0 +1,17 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj b/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj
new file mode 100644
index 0000000000..08fd96ab4e
--- /dev/null
+++ b/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ {469EE821-0FB5-4B9A-82D9-91292B0593D0}
+ VCProjectVersion
+ Package.Test.Mutable.Msix
+ en-US
+ 16.0
+ 10.0.26100.0
+ 10.0.17763.0
+ 10.0
+
+
+ Utility
+ v143
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(TargetName)
+
+
+
+
+
+
+
+ $(RepoTestCertificatePFX)
+ $(RepoTestCertificatePassword)
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj.filters b/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj.filters
new file mode 100644
index 0000000000..2df21c891a
--- /dev/null
+++ b/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj.filters
@@ -0,0 +1,17 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Mutable/Shadow.cat b/test/Package/data/Mutable/Shadow.cat
new file mode 100644
index 0000000000..defd12bba0
--- /dev/null
+++ b/test/Package/data/Mutable/Shadow.cat
@@ -0,0 +1 @@
+Catch me if you can...
diff --git a/test/Package/data/Mutable/appxmanifest.xml b/test/Package/data/Mutable/appxmanifest.xml
new file mode 100644
index 0000000000..ad6306b1dd
--- /dev/null
+++ b/test/Package/data/Mutable/appxmanifest.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+ Test.Package.Mutable
+ Microsoft Corporation
+ logo.png
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/Mutable/logo.png b/test/Package/data/Mutable/logo.png
new file mode 100644
index 0000000000..5bd7c0ce4d
Binary files /dev/null and b/test/Package/data/Mutable/logo.png differ
diff --git a/test/Package/data/Mutable/packages.config b/test/Package/data/Mutable/packages.config
new file mode 100644
index 0000000000..d9db55a1b3
--- /dev/null
+++ b/test/Package/data/Mutable/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj b/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj
new file mode 100644
index 0000000000..ee56886400
--- /dev/null
+++ b/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}
+ VCProjectVersion
+ Package.Test.UserExternal.Msix
+ en-US
+ 16.0
+ 10.0.26100.0
+ 10.0.17763.0
+ 10.0
+
+
+ Utility
+ v143
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(TargetName)
+
+
+
+
+
+
+ $(RepoTestCertificatePFX)
+ $(RepoTestCertificatePassword)
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj.filters b/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj.filters
new file mode 100644
index 0000000000..93e09be5b1
--- /dev/null
+++ b/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj.filters
@@ -0,0 +1,12 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
diff --git a/test/Package/data/UserExternal/Package.Test.UserExternal.vcxproj.filters b/test/Package/data/UserExternal/Package.Test.UserExternal.vcxproj.filters
new file mode 100644
index 0000000000..fb91a1a002
--- /dev/null
+++ b/test/Package/data/UserExternal/Package.Test.UserExternal.vcxproj.filters
@@ -0,0 +1,15 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/UserExternal/Shadow.cat b/test/Package/data/UserExternal/Shadow.cat
new file mode 100644
index 0000000000..defd12bba0
--- /dev/null
+++ b/test/Package/data/UserExternal/Shadow.cat
@@ -0,0 +1 @@
+Catch me if you can...
diff --git a/test/Package/data/UserExternal/appxmanifest.xml b/test/Package/data/UserExternal/appxmanifest.xml
new file mode 100644
index 0000000000..421446df6e
--- /dev/null
+++ b/test/Package/data/UserExternal/appxmanifest.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ Test.Package.UserExternal
+ Microsoft Corporation
+ logo.png
+ true
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Package/data/UserExternal/logo.png b/test/Package/data/UserExternal/logo.png
new file mode 100644
index 0000000000..5bd7c0ce4d
Binary files /dev/null and b/test/Package/data/UserExternal/logo.png differ
diff --git a/test/Package/data/UserExternal/packages.config b/test/Package/data/UserExternal/packages.config
new file mode 100644
index 0000000000..d9db55a1b3
--- /dev/null
+++ b/test/Package/data/UserExternal/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/test/PowerNotifications/PowerNotifications.vcxproj b/test/PowerNotifications/PowerNotifications.vcxproj
index 4a6083f0a4..eeedd50ee9 100644
--- a/test/PowerNotifications/PowerNotifications.vcxproj
+++ b/test/PowerNotifications/PowerNotifications.vcxproj
@@ -69,53 +69,32 @@
-
+
- WIN32;_DEBUG;POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
Use
pch.h
- $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\
+ $(RepoRoot)\test\inc;$(RepoRoot)\dev\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common
+ %(PreprocessorDefinitions);POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL;
Windows
false
-
+
- WIN32;NDEBUG;POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- Use
- pch.h
- $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\
+ _DEBUG;%(PreprocessorDefinitions)
-
- Windows
- false
-
-
+
- _DEBUG;POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- Use
- pch.h
- $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\
+ NDEBUG;%(PreprocessorDefinitions)
-
- Windows
- false
-
-
+
- NDEBUG;POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- Use
- pch.h
- $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\
+ WIN32;%(PreprocessorDefinitions)
-
- Windows
- false
-
diff --git a/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj b/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj
index 227342c347..1273112adb 100644
--- a/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj
+++ b/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj
@@ -42,13 +42,13 @@
- $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Security.AccessControl.winmd
+ $(OutDir)..\WindowsAppRuntime_DLL\Microsoft.Windows.Security.AccessControl.winmd
true
- $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll
+ $(OutDir)..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll
-
+
{f76b776e-86f5-48c5-8fc7-d2795ecc9746}
@@ -122,89 +122,33 @@
-
+
Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
- WIN32;_DEBUG;%(PreprocessorDefinitions)
pch.h
+ %(AdditionalIncludeDirectories);$(OutDir)..\WindowsAppRuntime_DLL;$(OutDir)..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\test\inc;$(RepoRoot)\dev\common
Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
+ %(AdditionalLibraryDirectories);$(OutDir)..\WindowsAppRuntime_DLL
onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
- WIN32;NDEBUG;%(PreprocessorDefinitions)
- pch.h
-
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
_DEBUG;%(PreprocessorDefinitions)
- pch.h
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
NDEBUG;%(PreprocessorDefinitions)
- pch.h
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
- _DEBUG;%(PreprocessorDefinitions)
- pch.h
+ WIN32;%(PreprocessorDefinitions)
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
- NDEBUG;%(PreprocessorDefinitions)
- pch.h
-
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
@@ -222,6 +166,6 @@
-
+
diff --git a/test/TestApps/ToastNotificationsTestApp/ToastNotificationsTestApp.vcxproj b/test/TestApps/ToastNotificationsTestApp/ToastNotificationsTestApp.vcxproj
index 04e3858dbc..bf385b6d38 100644
--- a/test/TestApps/ToastNotificationsTestApp/ToastNotificationsTestApp.vcxproj
+++ b/test/TestApps/ToastNotificationsTestApp/ToastNotificationsTestApp.vcxproj
@@ -59,7 +59,7 @@
-
+
$(RepoRoot);%(AdditionalIncludeDirectories)
@@ -136,12 +136,11 @@
-
+
Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
- WIN32;_DEBUG;%(PreprocessorDefinitions)
pch.h
+ %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\test\inc;$(RepoRoot)\dev\common
Console
@@ -150,75 +149,20 @@
Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
- WIN32;NDEBUG;%(PreprocessorDefinitions)
- pch.h
-
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
_DEBUG;%(PreprocessorDefinitions)
- pch.h
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
NDEBUG;%(PreprocessorDefinitions)
- pch.h
-
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
-
-
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
- _DEBUG;%(PreprocessorDefinitions)
- pch.h
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
-
+
- Use
- %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc
- NDEBUG;%(PreprocessorDefinitions)
- pch.h
+ WIN32;%(PreprocessorDefinitions)
-
- Console
- %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
- onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
- Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)
-
diff --git a/test/VersionInfo/VersionInfoTests.vcxproj b/test/VersionInfo/VersionInfoTests.vcxproj
index 029e9305d3..e2fc22358e 100644
--- a/test/VersionInfo/VersionInfoTests.vcxproj
+++ b/test/VersionInfo/VersionInfoTests.vcxproj
@@ -77,7 +77,7 @@
Use
true
pch.h
- $(RepoRoot)\test\inc;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
+ $(RepoRoot)\test\inc;$(RepoRoot)\dev\common;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL
$(RepoRoot);%(AdditionalIncludeDirectories)
diff --git a/test/inc/WindowsAppRuntime.Test.Package.h b/test/inc/WindowsAppRuntime.Test.Package.h
index 38defe0671..03ad957739 100644
--- a/test/inc/WindowsAppRuntime.Test.Package.h
+++ b/test/inc/WindowsAppRuntime.Test.Package.h
@@ -6,6 +6,8 @@
#include
+#include
+
#include
#include
#include
@@ -283,7 +285,14 @@ inline std::filesystem::path GetMsixPackagePath(PCWSTR packageDirName)
WIN32_FILE_ATTRIBUTE_DATA data{};
const auto ok{ GetFileAttributesExW(msix.c_str(), GetFileExInfoStandard, &data) };
const auto lastError{ ::GetLastError() };
- WEX::Logging::Log::Comment(WEX::Common::String().Format(L"GetFileAttributesExW(%ls):%d LastError:%u", msix.c_str(), static_cast(ok), lastError));
+ if (ok)
+ {
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"GetFileAttributesExW(%ls):TRUE", msix.c_str()));
+ }
+ else
+ {
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"GetFileAttributesExW(%ls):FALSE LastError:%u", msix.c_str(), lastError));
+ }
std::error_code errorcode{};
auto isregularfile{ std::filesystem::is_regular_file(msix, errorcode) };
@@ -316,24 +325,59 @@ inline void AddPackage(PCWSTR packageDirName, PCWSTR packageFullName)
{
auto msixUri{ GetMsixPackageUri(packageDirName) };
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(L"packageManager.AddPackageAsync(): uri=%ls", msixUri.ToString().c_str()));
winrt::Windows::Management::Deployment::PackageManager packageManager;
auto options{ winrt::Windows::Management::Deployment::DeploymentOptions::None };
auto deploymentResult{ packageManager.AddPackageAsync(msixUri, nullptr, options).get() };
VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"AddPackageAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str()));
}
-inline void AddPackageDefer(PCWSTR packageDirName, PCWSTR packageFullName)
+inline void AddPackageByUri(
+ winrt::Windows::Foundation::Uri packageUri,
+ PCWSTR packageFullName,
+ bool DeferRegistrationWhenPackagesAreInUse = false,
+ PCWSTR externalLocation = nullptr)
{
- auto msixUri{ GetMsixPackageUri(packageDirName) };
+ // AddPackageByUri added in 20H1
+ VERIFY_IS_TRUE(::WindowsVersion::IsWindows10_20H1OrGreater());
winrt::Windows::Management::Deployment::PackageManager packageManager;
winrt::Windows::Management::Deployment::AddPackageOptions options;
- options.DeferRegistrationWhenPackagesAreInUse(true);
- auto deploymentResult{ packageManager.AddPackageByUriAsync(msixUri, options).get() };
- VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"AddPackageByUriAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str()));
+ options.DeferRegistrationWhenPackagesAreInUse(DeferRegistrationWhenPackagesAreInUse);
+ if (externalLocation)
+ {
+ auto externalLocationUri{ winrt::Windows::Foundation::Uri{ externalLocation } };
+ options.ExternalLocationUri(externalLocationUri);
+ }
+ auto deploymentResult{ packageManager.AddPackageByUriAsync(packageUri, options).get() };
+ if (externalLocation)
+ {
+ VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(),
+ WEX::Common::String().Format(L"AddPackageByUriAsync('%s', ExtLoc='%s') = 0x%0X %s",
+ packageFullName, externalLocation ? externalLocation : L"", deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str()));
+ }
+ else
+ {
+ VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"AddPackageByUriAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str()));
+ }
+}
+
+inline void AddPackageByUri(
+ PCWSTR packageDirName,
+ PCWSTR packageFullName,
+ bool DeferRegistrationWhenPackagesAreInUse = false,
+ PCWSTR externalLocation = nullptr)
+{
+ auto msixUri{ GetMsixPackageUri(packageDirName) };
+ AddPackageByUri(msixUri, packageFullName, DeferRegistrationWhenPackagesAreInUse, externalLocation);
}
-inline void AddPackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName)
+inline void AddPackageDefer(PCWSTR packageDirName, PCWSTR packageFullName, PCWSTR externalLocation = nullptr)
+{
+ AddPackageByUri(packageDirName, packageFullName, true, externalLocation);
+}
+
+inline void AddPackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName, PCWSTR externalLocation = nullptr)
{
if (IsPackageRegistered(packageFullName))
{
@@ -342,11 +386,18 @@ inline void AddPackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName)
else
{
WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AddPackageIfNecessary: %s not registered, adding...", packageFullName));
- AddPackage(packageDirName, packageFullName);
+ if (externalLocation)
+ {
+ AddPackageByUri(packageDirName, packageFullName, false, externalLocation);
+ }
+ else
+ {
+ AddPackage(packageDirName, packageFullName);
+ }
}
}
-inline void AddPackageDeferIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName)
+inline void AddPackageDeferIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName, PCWSTR externalLocation = nullptr)
{
if (IsPackageRegistered(packageFullName))
{
@@ -355,7 +406,7 @@ inline void AddPackageDeferIfNecessary(PCWSTR packageDirName, PCWSTR packageFull
else
{
WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AddPackageDeferIfNecessary: %s not registered, adding...", packageFullName));
- AddPackageDefer(packageDirName, packageFullName);
+ AddPackageDefer(packageDirName, packageFullName, externalLocation);
}
}
@@ -369,7 +420,44 @@ inline void StagePackage(PCWSTR packageDirName, PCWSTR packageFullName)
VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"StagePackageAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str()));
}
-inline void StagePackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName)
+inline void StagePackageByUri(
+ winrt::Windows::Foundation::Uri packageUri,
+ PCWSTR packageFullName,
+ PCWSTR externalLocation = nullptr)
+{
+ // StagePackageByUri added in 20H1
+ VERIFY_IS_TRUE(::WindowsVersion::IsWindows10_20H1OrGreater());
+
+ winrt::Windows::Management::Deployment::PackageManager packageManager;
+ winrt::Windows::Management::Deployment::StagePackageOptions options;
+ if (externalLocation)
+ {
+ auto externalLocationUri{ winrt::Windows::Foundation::Uri{ externalLocation } };
+ options.ExternalLocationUri(externalLocationUri);
+ }
+ auto deploymentResult{ packageManager.StagePackageByUriAsync(packageUri, options).get() };
+ if (externalLocation)
+ {
+ VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(),
+ WEX::Common::String().Format(L"StagePackageAsync('%s', ExtLoc='%s') = 0x%0X %s",
+ packageFullName, externalLocation, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str()));
+ }
+ else
+ {
+ VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"StagePackageAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str()));
+ }
+}
+
+inline void StagePackageByUri(
+ PCWSTR packageDirName,
+ PCWSTR packageFullName,
+ PCWSTR externalLocation = nullptr)
+{
+ auto msixUri{ GetMsixPackageUri(packageDirName) };
+ StagePackageByUri(msixUri, packageFullName, externalLocation);
+}
+
+inline void StagePackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName, PCWSTR externalLocation=nullptr)
{
if (IsPackageAvailable(packageFullName))
{
@@ -378,7 +466,14 @@ inline void StagePackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullNam
else
{
WEX::Logging::Log::Comment(WEX::Common::String().Format(L"StagePackageIfNecessary: %s not staged, staging...", packageFullName));
- StagePackage(packageDirName, packageFullName);
+ if (externalLocation)
+ {
+ StagePackageByUri(packageDirName, packageFullName, externalLocation);
+ }
+ else
+ {
+ StagePackage(packageDirName, packageFullName);
+ }
}
}
diff --git a/test/inc/WindowsAppRuntime.Test.TAEF.cppwinrt.h b/test/inc/WindowsAppRuntime.Test.TAEF.cppwinrt.h
index 2662a1eb27..22734fee7c 100644
--- a/test/inc/WindowsAppRuntime.Test.TAEF.cppwinrt.h
+++ b/test/inc/WindowsAppRuntime.Test.TAEF.cppwinrt.h
@@ -71,7 +71,7 @@ namespace WEX::TestExecution
}
else
{
- return CompareStringOrdinal(left .c_str(), -1, right.c_str(), -1, FALSE) - CSTR_EQUAL;
+ return CompareStringOrdinal(left.c_str(), -1, right.c_str(), -1, FALSE) - CSTR_EQUAL;
}
}
};
diff --git a/test/inc/WindowsAppRuntime.Test.TAEF.stl.h b/test/inc/WindowsAppRuntime.Test.TAEF.stl.h
new file mode 100644
index 0000000000..17e2e39287
--- /dev/null
+++ b/test/inc/WindowsAppRuntime.Test.TAEF.stl.h
@@ -0,0 +1,104 @@
+// Copyright (c) Microsoft Corporation and Contributors. All rights reserved.
+// Licensed under the MIT License.
+
+#ifndef __WINDOWSAPPRUNTIME_TEST_TAEF_CPPWINRT_H
+#define __WINDOWSAPPRUNTIME_TEST_TAEF_CPPWINRT_H
+
+namespace WEX::TestExecution
+{
+ // Teach TAEF how to format a std::wstring
+ template <>
+ class VerifyOutputTraits
+ {
+ public:
+ static WEX::Common::NoThrowString ToString(std::wstring const& value)
+ {
+ return WEX::Common::NoThrowString().Format(L"%s", s);
+ }
+ };
+
+ // Teach TAEF how to compare a std::wstring
+ template <>
+ class VerifyCompareTraits
+ {
+ public:
+ static bool AreEqual(std::wstring const& expected, std::wstring const& actual)
+ {
+ return Compare(expected, actual) == 0;
+ }
+
+ static bool AreSame(std::wstring const& expected, std::wstring const& actual)
+ {
+ return &expected == &actual;
+ }
+
+ static bool IsLessThan(std::wstring const& expectedLess, std::wstring const& expectedGreater)
+ {
+ return Compare(expectedLess, expectedGreater) < 0;
+ }
+
+ static bool IsGreaterThan(std::wstring const& expectedGreater, std::wstring const& expectedLess)
+ {
+ return Compare(expectedGreater, expectedLess) > 0;
+ }
+
+ static bool IsNull(std::wstring const& object)
+ {
+ return object.c_str() == nullptr;
+ }
+ private:
+ static int Compare(std::wstring const& left, std::wstring const& right)
+ {
+ return CompareStringOrdinal(left.c_str(), -1, right.c_str(), -1, FALSE) - CSTR_EQUAL;
+ }
+ };
+
+ // Teach TAEF how to format a std::filesystem::path
+ template <>
+ class VerifyOutputTraits
+ {
+ public:
+ static WEX::Common::NoThrowString ToString(std::filesystem::path const& value)
+ {
+ return WEX::Common::NoThrowString().Format(L"%s", s);
+ }
+ };
+
+ // Teach TAEF how to compare a std::filesystem::path
+ template <>
+ class VerifyCompareTraits
+ {
+ public:
+ static bool AreEqual(std::filesystem::path const& expected, std::filesystem::path const& actual)
+ {
+ return Compare(expected, actual) == 0;
+ }
+
+ static bool AreSame(std::filesystem::path const& expected, std::filesystem::path const& actual)
+ {
+ return &expected == &actual;
+ }
+
+ static bool IsLessThan(std::filesystem::path const& expectedLess, std::filesystem::path const& expectedGreater)
+ {
+ return Compare(expectedLess, expectedGreater) < 0;
+ }
+
+ static bool IsGreaterThan(std::filesystem::path const& expectedGreater, std::filesystem::path const& expectedLess)
+ {
+ return Compare(expectedGreater, expectedLess) > 0;
+ }
+
+ static bool IsNull(std::filesystem::path const& object)
+ {
+ return object.c_str() == nullptr;
+ }
+ private:
+ static int Compare(std::filesystem::path const& left, std::filesystem::path const& right)
+ {
+ return CompareStringOrdinal(left.c_str(), -1, right.c_str(), -1, FALSE) - CSTR_EQUAL;
+ }
+ };
+}
+
+#endif // __WINDOWSAPPRUNTIME_TEST_TAEF_CPPWINRT_H