-
Notifications
You must be signed in to change notification settings - Fork 351
Resource Management APIs for all project types #11
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
Comments
A list of flat C APIs will provide core MRT functionality. A WinRT wrapper will build on top the core MRT to provide APIs similar to Window.ApplicationModel.Resources(.Core) and some helper APIs (e.g. locate merged resource file for resource bundle). C APIs
WinRT APIs
SamplesLoad resources with C APIs
Load resources with WinRT APIs
|
One nit: I don’t think you would want to load PNG data into a variable of type |
Thanks for taking a look at the API! The string resource lookup gives you back a path to the file. You then load it however you like. That is parity behavior with the OS API. We should put a comment into the sample, and maybe have a sample for the embedded case as well. The embedded resource is for truly embedded resources, not loose files on disk (the dev can pick whether to embed files or keep them loose). We are planning to provide wrappers that abstract this away, something like MrmLoadStringOrEmbeddedResource(type, resource) return ret; |
Thanks for the comment! I have added a comment in the sample. |
When will this code be packaged and be made available on some (public) NuGet feed? Currently, I can only reference MRT Core if I use WinUI 3, since Reunion is bundled in the WinUI 3 NuGet package, or if I build it myself. |
Guidance on how to use MRT Core in other components of Project Reunion (in code in this repository) would also be welcome. |
Yes, our current release vehicle is WinUI. The code itself works from any context, but right now our build scripts are tied to the WinUI ones. We are working on standalone support, and will have that ready before the first full Reunion release. But I don't have a hard date to share right now. |
@axelandrejs is there any documentation on how to use this in an unpackaged application. All the options for WinUI rely on the packaging project. It would be good to see an example of using MRT Core without packaging. |
@nickrandolph I use MRT Core in unpackaged applications all the time; it’s part of my standard development technique now. First, you will need to vendor (include in your solution) the MRT Core projects (until and unless they are posted on NuGet independently of WinUI). I use the following technique in my private projects: First, paste the following code into a <Project>
<PropertyGroup>
<MRTCoreResourceRoot>$(MSBuildProjectDirectory)\PRIResources</MRTCoreResourceRoot>
</PropertyGroup>
</Project> Second, create a folder called PRIResources next to your csproj and dump what resources you want in there. You can include arbitrary files, and they will be embedded within the PRI file once built (assuming you use the instructions below to create your PRI file; embedding is not the default). Use
Then, create a file called <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<resources targetOsVersion="10.0.0" majorVersion="1">
<index root="\" startIndexAt="\">
<default>
<qualifier name="Language" value="en-US"/>
<qualifier name="Contrast" value="standard"/>
<qualifier name="Scale" value="100"/>
<qualifier name="HomeRegion" value="001"/>
<qualifier name="LayoutDirection" value="LTR"/>
<qualifier name="Theme" value="light"/>
<qualifier name="AlternateForm" value=""/>
<qualifier name="DXFeatureLevel" value="DX9"/>
<qualifier name="Configuration" value=""/>
<qualifier name="DeviceFamily" value="Universal"/>
</default>
<indexer-config type="folder" foldernameAsQualifier="true" filenameAsQualifier="true" qualifierDelimiter="."/>
<indexer-config type="resw" convertDotsToSlashes="false" initialPath=""/>
<indexer-config type="resjson" initialPath=""/>
<indexer-config type="resfiles" qualifierDelimiter="."/>
<indexer-config type="EmbedFiles"/>
</index>
<index root="\" startIndexAt="\Resources">
<default>
<qualifier name="Language" value="en-US"/>
<qualifier name="Contrast" value="standard"/>
<qualifier name="Scale" value="100"/>
<qualifier name="HomeRegion" value="001"/>
<qualifier name="LayoutDirection" value="LTR"/>
<qualifier name="Theme" value="light"/>
<qualifier name="AlternateForm" value=""/>
<qualifier name="DXFeatureLevel" value="DX9"/>
<qualifier name="Configuration" value=""/>
<qualifier name="DeviceFamily" value="Universal"/>
</default>
<indexer-config type="EmbedFiles"/>
</index>
</resources> This file (a slightly modified copy of the default used in WinUI apps) instructs <Project>
<PropertyGroup>
<UseMRTCore Condition="'$(UseMRTCore)' == '' and '$(MRTCoreResourceRoot)' != ''">true</UseMRTCore>
<UseMRTCore Condition="'$(UseMRTCore)' == ''">false</UseMRTCore>
</PropertyGroup>
<PropertyGroup Condition="'$(UseMRTCore)' == 'true'">
<MRTCoreConfigurationFile Condition="'$(MRTCoreConfigurationFile)' == ''">path\to\priconfig.xml</MRTCoreConfigurationFile>
</PropertyGroup>
<Target Name="LocateMakePriExe" Condition="'$(UseMRTCore)' == 'true'" DependsOnTargets="PrepareForBuild">
<PropertyGroup>
<WindowsSdkDir Condition="'$(WindowsSdkDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@InstallationFolder)</WindowsSdkDir>
<WindowsSdkDir Condition="'$(WindowsSdkDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@InstallationFolder)</WindowsSdkDir>
</PropertyGroup>
<PropertyGroup>
<MakePRIVersion Condition="'$(MakePRIVersion)' == ''">10.0.18362.0</MakePRIVersion>
<MakePRIPath>$(WindowsSdkDir)bin\$(MakePRIVersion)\x64\makepri.exe</MakePRIPath>
</PropertyGroup>
</Target>
<Target Name="CreatePRIFile" Condition="'$(UseMRTCore)' == 'true'" DependsOnTargets="LocateMakePriExe"
Inputs="$(MRTCoreResourceRoot)\**\*.*" Outputs="$(IntermediateOutputPath)$(TargetName).manual.pri">
<Error Condition="'$(MRTCoreResourceRoot)' == ''" Text="MRTCoreResourceRoot must be set" />
<Error Condition="HasTrailingSlash('$(MRTCoreResourceRoot)')" Text="MRTCoreResourceRoot property cannot end in a backslash" />
<PropertyGroup>
<MRTCoreResourceRootAbsolute>$([System.IO.Path]::GetFullPath('$(MRTCoreResourceRoot)'))</MRTCoreResourceRootAbsolute>
</PropertyGroup>
<Exec Command=""$(MakePRIPath)" new /pr "$(MRTCoreResourceRootAbsolute)" /cf "$(MRTCoreConfigurationFile)" /of "$(IntermediateOutputPath)$(TargetName).manual.pri" /o" />
<Exec Command=""$(MakePRIPath)" resourcepack /pr "$(MRTCoreResourceRootAbsolute)" /cf "$(MRTCoreConfigurationFile)" /if "$(IntermediateOutputPath)$(TargetName).manual.pri" /of "$(IntermediateOutputPath)$(TargetName).manual.pri" /o" />
<ItemGroup>
<_PriFile Include="$(IntermediateOutputPath)$(TargetName).manual.pri" />
<FileWrites Include="$(IntermediateOutputPath)$(TargetName).manual.pri" />
</ItemGroup>
<Copy Condition="'$(PriProjTaskAssembly)' == ''" SkipUnchangedFiles="true" UseHardlinksIfPossible="true"
SourceFiles="$(IntermediateOutputPath)$(TargetName).manual.pri" DestinationFiles="$(IntermediateOutputPath)$(TargetName).pri" />
<ItemGroup Condition="'$(PriProjTaskAssembly)' == ''">
<Content Include="$(IntermediateOutputPath)$(TargetName).pri">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</Content>
<FileWrites Include="$(IntermediateOutputPath)$(TargetName).pri" />
</ItemGroup>
</Target>
<PropertyGroup>
<PrepareResourcesDependsOn>
CreatePRIFile;
$(PrepareResourcesDependsOn)
</PrepareResourcesDependsOn>
</PropertyGroup> You’ll need to update the value of the Unfortunately, the C# code required for retrieving data from the PRI file (the code that calls the MRT Core APIs) uses a path syntax that is difficult to explain here, because it depends on the structure and contents of that PRIResources folder you created earlier. If you want to see the contents of your PRI file, run As a finishing touch, the above code will not conflict with WinUI’s usage of MRT Core; if you ever add WinUI to your project, the contents of your manually generated PRI file will be merged into WinUI’s automatically generated PRI file during the build. The two chunks of data will coexist perfectly; the names/URIs you use to retrieve the resources won’t even change. Let me know if you have any more questions. Hope this helps! |
@wjk that's awesome - thanks so much for this information. You mentioned adding WinUI to the project in the final paragraph - is this something you've done successfully and been able to run the app without packaging? If so, would you be willing to share a sample as I think this is an important scenario that I would love to see working. |
WinUI still requires MSIX packaging. I generally delete the automatically generated packaging project and use one I create myself. I was talking about merging WinUI's PRI content (which is substantial) with the manually created PRI data, in the normal context of a WinUI app running in a packaged environment. Glad I could be of service nonetheless! |
We're working finalizing this support, and should have something to share very soon. The basic usage will be no different from packaged. You add Reunion to your project, and then you add assets and call APIs like you would in a WinUI app. The APIs themselves work the same. Once we are done you won't need to do the manual steps outlined above. |
@jonwis I noted that this is now "code complete" yet according to the roadmap support for unpackaged apps won't appear until v0.8 (preview). Should we be expecting these issues to be in sync with the roadmap? |
0.8 Preview is now available, and there is an unpackaged sample app available - https://github.com/microsoft/WindowsAppSDK-Samples/tree/main/MrtCore/console_unpackaged_app However, it only demonstrates how to work with strings (resw), and not images or other resources. It'd be good to have some additional on how to work with MRT Core in this scenario. |
Hi everyone! Since this was shipped in 1.0 we're going to go ahead and close the issue. However, if there is additional functionality you would like to see in the product please submit further feedback to our feature portal! |
Proposal: Enable MRT for unpackaged applications
Summary
Provide a version of the MRT resource management & packaging system even for unpackaged applications. While MUI is supported, MRT is more powerful and supported directly by various "visual" tooling, and generates code for direct use by apps.
Rationale
https://docs.microsoft.com/en-us/windows/uwp/app-resources/ is a powerful system for packaged applications to deliver resources (images, XAML, html, xml, or any other data) to enable localization or customized content for form factors. Unpackaged applications would benefit from the same ability to easily use Visual Studio and other tools to build and consume resources. https://docs.microsoft.com/en-us/previous-versions/windows/apps/jj552947(v=win.10) describes the Resource Manager in depth.
Scope
The text was updated successfully, but these errors were encountered: