Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Where is the generic.xbf file associated with the WindowsAppSDK NuGet? #8741

Closed
Ajith-GS opened this issue Jul 23, 2023 · 4 comments
Closed
Labels
team-Markup Issue for the Markup team

Comments

@Ajith-GS
Copy link

Describe the bug

When we create a custom WinUI3 NuGet with xaml resources (e.g., Resource Dictionaries with custom styles), we need to provide the corresponding XBF/XAML files along with other NuGet files(e.g.: .dll, .winmd etc) in order to copy them to the client application's output location. However, the self-contained WinUI3 application's output directory does not contain any XBF/XAML files associated with WindowsAppSDK NuGet, such as generic.xaml or generic.xbf.
How does the client application getting XAML resources from WindowsAppSDK NuGet ?
Does the WindowsAppSDK have a specific location where it stores its XBF/XAML files?
If so, may we incorporate this method into our custom NuGet?

Steps to reproduce the bug

Custom NuGet is created by referring https://learn.microsoft.com/en-us/nuget/guides/create-uwp-packages

Expected behavior

No response

Screenshots

No response

NuGet package version

Windows App SDK 1.3.2: 1.3.230602002

Packaging type

Unpackaged

Windows version

Windows 10 version 21H2 (19044, November 2021 Update)

IDE

Visual Studio 2022

Additional context

No response

@DarranRowe
Copy link

DarranRowe commented Jul 23, 2023

The generic.xaml file is in the nuget package.
There are three copies in the package, there is the one under lib\net6.0-windows10.0.17763.0\Microsoft.WinUI\Themes, which is the one you would likely reference if you are targeting Windows 10 1809 (17763) with .NET. There is one under lib\net6.0-windows10.0.18362.0\Microsoft.WinUI\Themes which is for Windows 10 1903 (18362) with .NET. Finally, there is the one under lib\uap10.0\Microsoft.UI\Themes which would be for the languages that use direct .winmd references. Although the files should be identical.
As far as where the WinUI resources end up in a self contained application, you really have to understand that by default there is only one .pri file for an application (UWP applications could really only have one per package). This means that if you bring the component into the application, you also have to bring the resources in too.
As an example, suppose I have the amazingly named WinUI 3 application named meh.exe. This is set to be unpackaged and self contained. I don't think this is really documented, but the resources file that MRT Core looks for by default for an unpackaged application is (executable name).pri, so meh.pri in this case. MRT Core looks in the same directory as the executable. If it is packaged then it looks for resources.pri, and this is documented.
If we then use makepri to dump the contents of meh.pri,
makepri dump /if meh.pri /of meh.pri.xml
It is possible to look at the content of the resource file for the application. In this case, the file starts off with:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PriInfo>
	<ResourceMap name="Meh" version="1.0" primary="true">
		<Qualifiers>
			<Language>EN-US,EN-GB,AF-ZA,AM-ET,AR-SA,AS-IN,AZ-LATN-AZ,BG-BG,BN-IN,BS-LATN-BA,CA-ES,CA-ES-VALENCIA,CS-CZ,CY-GB,DA-DK,DE-DE,EL-GR,ES-ES,ES-MX,ET-EE,EU-ES,FA-IR,FI-FI,FIL-PH,FR-CA,FR-FR,GA-IE,GD-GB,GL-ES,GU-IN,HE-IL,HI-IN,HR-HR,HU-HU,HY-AM,ID-ID,IS-IS,IT-IT,JA-JP,KA-GE,KK-KZ,KM-KH,KN-IN,KO-KR,KOK-IN,LB-LU,LO-LA,LT-LT,LV-LV,MI-NZ,MK-MK,ML-IN,MR-IN,MS-MY,MT-MT,NB-NO,NE-NP,NL-NL,NN-NO,OR-IN,PA-IN,PL-PL,PT-BR,PT-PT,QUZ-PE,RO-RO,RU-RU,SK-SK,SL-SI,SQ-AL,SR-CYRL-BA,SR-CYRL-RS,SR-LATN-RS,SV-SE,TA-IN,TE-IN,TH-TH,TR-TR,TT-RU,UG-CN,UK-UA,UR-PK,UZ-LATN-UZ,VI-VN,ZH-CN,ZH-TW</Language>
		</Qualifiers>
		<ResourceMapSubtree name="Files">
			<NamedResource name="App.xbf" uri="ms-resource://Meh/Files/App.xbf">
				<Candidate type="Path">
					<Value>App.xbf</Value>
				</Candidate>
			</NamedResource>
			<NamedResource name="MainWindow.xbf" uri="ms-resource://Meh/Files/MainWindow.xbf">
				<Candidate type="Path">
					<Value>MainWindow.xbf</Value>
				</Candidate>
			</NamedResource>
			<ResourceMapSubtree name="Microsoft.UI.Xaml">
				<ResourceMapSubtree name="Assets">
					<NamedResource name="NoiseAsset_256X256_PNG.png" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/Assets/NoiseAsset_256X256_PNG.png">
						<Candidate type="Path">
							<Value>Microsoft.UI.Xaml\Assets\NoiseAsset_256X256_PNG.png</Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
				<ResourceMapSubtree name="DensityStyles">
					<NamedResource name="Compact.xbf" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/DensityStyles/Compact.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
					<NamedResource name="CompactDatePickerTimePickerFlyout.xbf" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/DensityStyles/CompactDatePickerTimePickerFlyout.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
				<ResourceMapSubtree name="Themes">
					<NamedResource name="generic.xbf" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/Themes/generic.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
					<NamedResource name="themeresources.xbf" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/Themes/themeresources.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
			</ResourceMapSubtree>
		</ResourceMapSubtree>

This is incomplete since the file is around 1.7MiB, but do you notice the Microsoft.UI.Xaml subtree? These are the WinUI 3 resources that were merged with the application's resources. It is possible to verify this by grabbing the resources.pri out of the Windows App SDK package (the .msix file is just a renamed .zip file) and use makepri to dump the contents in the same way. This file starts off with the following:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PriInfo>
	<ResourceMap name="Microsoft.WindowsAppRuntime.1.3" version="1.0" primary="true">
		<Qualifiers>
			<Language>EN-US,EN-GB,AF-ZA,AM-ET,AR-SA,AS-IN,AZ-LATN-AZ,BG-BG,BN-IN,BS-LATN-BA,CA-ES,CA-ES-VALENCIA,CS-CZ,CY-GB,DA-DK,DE-DE,EL-GR,ES-ES,ES-MX,ET-EE,EU-ES,FA-IR,FI-FI,FIL-PH,FR-CA,FR-FR,GA-IE,GD-GB,GL-ES,GU-IN,HE-IL,HI-IN,HR-HR,HU-HU,HY-AM,ID-ID,IS-IS,IT-IT,JA-JP,KA-GE,KK-KZ,KM-KH,KN-IN,KO-KR,KOK-IN,LB-LU,LO-LA,LT-LT,LV-LV,MI-NZ,MK-MK,ML-IN,MR-IN,MS-MY,MT-MT,NB-NO,NE-NP,NL-NL,NN-NO,OR-IN,PA-IN,PL-PL,PT-BR,PT-PT,QUZ-PE,RO-RO,RU-RU,SK-SK,SL-SI,SQ-AL,SR-CYRL-BA,SR-CYRL-RS,SR-LATN-RS,SV-SE,TA-IN,TE-IN,TH-TH,TR-TR,TT-RU,UG-CN,UK-UA,UR-PK,UZ-LATN-UZ,VI-VN,ZH-CN,ZH-TW</Language>
		</Qualifiers>
		<ResourceMapSubtree name="Files">
			<ResourceMapSubtree name="Microsoft.UI.Xaml">
				<ResourceMapSubtree name="Assets">
					<NamedResource name="NoiseAsset_256X256_PNG.png" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/Assets/NoiseAsset_256X256_PNG.png">
						<Candidate type="Path">
							<Value>Microsoft.UI.Xaml\Assets\NoiseAsset_256X256_PNG.png</Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
				<ResourceMapSubtree name="DensityStyles">
					<NamedResource name="Compact.xbf" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/DensityStyles/Compact.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
					<NamedResource name="CompactDatePickerTimePickerFlyout.xbf" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/DensityStyles/CompactDatePickerTimePickerFlyout.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
				<ResourceMapSubtree name="Themes">
					<NamedResource name="generic.xbf" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/Themes/generic.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
					<NamedResource name="themeresources.xbf" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/Themes/themeresources.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
			</ResourceMapSubtree>
		</ResourceMapSubtree>

The biggest difference is the root path of the URI is set up to target the Windows App SDK package directory.
Anyway, the interesting thing about both of these is under the WinUI 3 .xbf files, do you notice the references to embedded data? This means that the data for these files is stored in the .pri file itself. This means that you don't have to do anything out of the ordinary to get these files since MRT Core should just look in the application/package resource file.

If there is any problem in particular that you are facing then it would be better to describe that problem as precisely as you can.

--Edit--
I forgot to mention. If you want to embed the resources yourself then it is possible. One reference to this that I have found is microsoft/WindowsAppSDK#348. This is the only reference that I found which shows how to embed resources, I'm not sure if much has changed between when that was written and 1.3 or 1.4.

@Ajith-GS Ajith-GS reopened this Jul 24, 2023
@Ajith-GS
Copy link
Author

The generic.xaml file is in the nuget package. There are three copies in the package, there is the one under lib\net6.0-windows10.0.17763.0\Microsoft.WinUI\Themes, which is the one you would likely reference if you are targeting Windows 10 1809 (17763) with .NET. There is one under lib\net6.0-windows10.0.18362.0\Microsoft.WinUI\Themes which is for Windows 10 1903 (18362) with .NET. Finally, there is the one under lib\uap10.0\Microsoft.UI\Themes which would be for the languages that use direct .winmd references. Although the files should be identical. As far as where the WinUI resources end up in a self contained application, you really have to understand that by default there is only one .pri file for an application (UWP applications could really only have one per package). This means that if you bring the component into the application, you also have to bring the resources in too. As an example, suppose I have the amazingly named WinUI 3 application named meh.exe. This is set to be unpackaged and self contained. I don't think this is really documented, but the resources file that MRT Core looks for by default for an unpackaged application is (executable name).pri, so meh.pri in this case. MRT Core looks in the same directory as the executable. If it is packaged then it looks for resources.pri, and this is documented. If we then use makepri to dump the contents of meh.pri, makepri dump /if meh.pri /of meh.pri.xml It is possible to look at the content of the resource file for the application. In this case, the file starts off with:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PriInfo>
	<ResourceMap name="Meh" version="1.0" primary="true">
		<Qualifiers>
			<Language>EN-US,EN-GB,AF-ZA,AM-ET,AR-SA,AS-IN,AZ-LATN-AZ,BG-BG,BN-IN,BS-LATN-BA,CA-ES,CA-ES-VALENCIA,CS-CZ,CY-GB,DA-DK,DE-DE,EL-GR,ES-ES,ES-MX,ET-EE,EU-ES,FA-IR,FI-FI,FIL-PH,FR-CA,FR-FR,GA-IE,GD-GB,GL-ES,GU-IN,HE-IL,HI-IN,HR-HR,HU-HU,HY-AM,ID-ID,IS-IS,IT-IT,JA-JP,KA-GE,KK-KZ,KM-KH,KN-IN,KO-KR,KOK-IN,LB-LU,LO-LA,LT-LT,LV-LV,MI-NZ,MK-MK,ML-IN,MR-IN,MS-MY,MT-MT,NB-NO,NE-NP,NL-NL,NN-NO,OR-IN,PA-IN,PL-PL,PT-BR,PT-PT,QUZ-PE,RO-RO,RU-RU,SK-SK,SL-SI,SQ-AL,SR-CYRL-BA,SR-CYRL-RS,SR-LATN-RS,SV-SE,TA-IN,TE-IN,TH-TH,TR-TR,TT-RU,UG-CN,UK-UA,UR-PK,UZ-LATN-UZ,VI-VN,ZH-CN,ZH-TW</Language>
		</Qualifiers>
		<ResourceMapSubtree name="Files">
			<NamedResource name="App.xbf" uri="ms-resource://Meh/Files/App.xbf">
				<Candidate type="Path">
					<Value>App.xbf</Value>
				</Candidate>
			</NamedResource>
			<NamedResource name="MainWindow.xbf" uri="ms-resource://Meh/Files/MainWindow.xbf">
				<Candidate type="Path">
					<Value>MainWindow.xbf</Value>
				</Candidate>
			</NamedResource>
			<ResourceMapSubtree name="Microsoft.UI.Xaml">
				<ResourceMapSubtree name="Assets">
					<NamedResource name="NoiseAsset_256X256_PNG.png" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/Assets/NoiseAsset_256X256_PNG.png">
						<Candidate type="Path">
							<Value>Microsoft.UI.Xaml\Assets\NoiseAsset_256X256_PNG.png</Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
				<ResourceMapSubtree name="DensityStyles">
					<NamedResource name="Compact.xbf" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/DensityStyles/Compact.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
					<NamedResource name="CompactDatePickerTimePickerFlyout.xbf" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/DensityStyles/CompactDatePickerTimePickerFlyout.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
				<ResourceMapSubtree name="Themes">
					<NamedResource name="generic.xbf" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/Themes/generic.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
					<NamedResource name="themeresources.xbf" uri="ms-resource://Meh/Files/Microsoft.UI.Xaml/Themes/themeresources.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
			</ResourceMapSubtree>
		</ResourceMapSubtree>

This is incomplete since the file is around 1.7MiB, but do you notice the Microsoft.UI.Xaml subtree? These are the WinUI 3 resources that were merged with the application's resources. It is possible to verify this by grabbing the resources.pri out of the Windows App SDK package (the .msix file is just a renamed .zip file) and use makepri to dump the contents in the same way. This file starts off with the following:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PriInfo>
	<ResourceMap name="Microsoft.WindowsAppRuntime.1.3" version="1.0" primary="true">
		<Qualifiers>
			<Language>EN-US,EN-GB,AF-ZA,AM-ET,AR-SA,AS-IN,AZ-LATN-AZ,BG-BG,BN-IN,BS-LATN-BA,CA-ES,CA-ES-VALENCIA,CS-CZ,CY-GB,DA-DK,DE-DE,EL-GR,ES-ES,ES-MX,ET-EE,EU-ES,FA-IR,FI-FI,FIL-PH,FR-CA,FR-FR,GA-IE,GD-GB,GL-ES,GU-IN,HE-IL,HI-IN,HR-HR,HU-HU,HY-AM,ID-ID,IS-IS,IT-IT,JA-JP,KA-GE,KK-KZ,KM-KH,KN-IN,KO-KR,KOK-IN,LB-LU,LO-LA,LT-LT,LV-LV,MI-NZ,MK-MK,ML-IN,MR-IN,MS-MY,MT-MT,NB-NO,NE-NP,NL-NL,NN-NO,OR-IN,PA-IN,PL-PL,PT-BR,PT-PT,QUZ-PE,RO-RO,RU-RU,SK-SK,SL-SI,SQ-AL,SR-CYRL-BA,SR-CYRL-RS,SR-LATN-RS,SV-SE,TA-IN,TE-IN,TH-TH,TR-TR,TT-RU,UG-CN,UK-UA,UR-PK,UZ-LATN-UZ,VI-VN,ZH-CN,ZH-TW</Language>
		</Qualifiers>
		<ResourceMapSubtree name="Files">
			<ResourceMapSubtree name="Microsoft.UI.Xaml">
				<ResourceMapSubtree name="Assets">
					<NamedResource name="NoiseAsset_256X256_PNG.png" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/Assets/NoiseAsset_256X256_PNG.png">
						<Candidate type="Path">
							<Value>Microsoft.UI.Xaml\Assets\NoiseAsset_256X256_PNG.png</Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
				<ResourceMapSubtree name="DensityStyles">
					<NamedResource name="Compact.xbf" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/DensityStyles/Compact.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
					<NamedResource name="CompactDatePickerTimePickerFlyout.xbf" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/DensityStyles/CompactDatePickerTimePickerFlyout.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
				<ResourceMapSubtree name="Themes">
					<NamedResource name="generic.xbf" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/Themes/generic.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
					<NamedResource name="themeresources.xbf" uri="ms-resource://Microsoft.WindowsAppRuntime.1.3/Files/Microsoft.UI.Xaml/Themes/themeresources.xbf">
						<Candidate type="EmbeddedData">
							<Base64Value>[Embedded Binary Data]</Base64Value>
						</Candidate>
					</NamedResource>
				</ResourceMapSubtree>
			</ResourceMapSubtree>
		</ResourceMapSubtree>

The biggest difference is the root path of the URI is set up to target the Windows App SDK package directory. Anyway, the interesting thing about both of these is under the WinUI 3 .xbf files, do you notice the references to embedded data? This means that the data for these files is stored in the .pri file itself. This means that you don't have to do anything out of the ordinary to get these files since MRT Core should just look in the application/package resource file.

If there is any problem in particular that you are facing then it would be better to describe that problem as precisely as you can.

--Edit-- I forgot to mention. If you want to embed the resources yourself then it is possible. One reference to this that I have found is microsoft/WindowsAppSDK#348. This is the only reference that I found which shows how to embed resources, I'm not sure if much has changed between when that was written and 1.3 or 1.4.

Thank you so much for your response.
I have multiple .pri files from different libraries that contain .xbf files related to resource dictionaries. Is there another way to add .xbf or .xaml resources to application context using code except using the makepri command to combine these .pri files with the final .pri file (the one with .pri or resources.pri) or manually copying the .xbf/.xaml file to output location?

@DarranRowe
Copy link

There is a long and convoluted answer here, but I think your best bet is to look into how WinUI 3 merges its resources during build time. This does mean looking into the MSBuild files in the Windows App SDK nuget package and maybe looking into understanding MSBuild in general, but if you are able to do this automatically with any nuget packages then it should be worth the effort.

@bpulliam bpulliam transferred this issue from microsoft/WindowsAppSDK Aug 10, 2023
@bpulliam bpulliam added the team-Markup Issue for the Markup team label Aug 10, 2023
@Ajith-GS
Copy link
Author

The required .pri file can be loaded into application scope using the ResourceManagerRequested event available in the latest Windows App SDK preview version, Windows App SDK 1.4 Preview1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-Markup Issue for the Markup team
Projects
None yet
Development

No branches or pull requests

3 participants