From 77812704f37e0c6d356f2fc60d9bab39a453f2d1 Mon Sep 17 00:00:00 2001 From: cnbluefire <909683964@qq.com> Date: Sun, 31 Mar 2024 01:40:38 +0800 Subject: [PATCH 1/2] Add support for pri files --- WinUI3Localizer.SampleApp/App.xaml.cs | 4 +- .../PriResourceReaderTest.cs | 52 ++++++++++ .../WinUI3Localizer.Tests.csproj | 9 ++ WinUI3Localizer.Tests/resources.pri | Bin 0 -> 68136 bytes WinUI3Localizer.sln | 24 ++--- WinUI3Localizer/LocalizerBuilder.cs | 41 +++++++- WinUI3Localizer/PriResourceReader.cs | 97 ++++++++++++++++++ 7 files changed, 210 insertions(+), 17 deletions(-) create mode 100644 WinUI3Localizer.Tests/PriResourceReaderTest.cs create mode 100644 WinUI3Localizer.Tests/resources.pri create mode 100644 WinUI3Localizer/PriResourceReader.cs diff --git a/WinUI3Localizer.SampleApp/App.xaml.cs b/WinUI3Localizer.SampleApp/App.xaml.cs index ca0807d..c8a5550 100644 --- a/WinUI3Localizer.SampleApp/App.xaml.cs +++ b/WinUI3Localizer.SampleApp/App.xaml.cs @@ -133,7 +133,9 @@ private async Task InitializeLocalizer() #endif ILocalizer localizer = await new LocalizerBuilder() - .AddStringResourcesFolderForLanguageDictionaries(StringsFolderPath) + .AddPriResourcesForLanguageDictionaries(new[] { "en-US", "es-ES", "ja" } ) + .AddPriResourcesForLanguageDictionaries(new[] { "en-US", "es-ES", "ja" }, "ErrorMessages") + //.AddStringResourcesFolderForLanguageDictionaries(StringsFolderPath) //.SetLogger(Host.Services // .GetRequiredService() // .CreateLogger()) diff --git a/WinUI3Localizer.Tests/PriResourceReaderTest.cs b/WinUI3Localizer.Tests/PriResourceReaderTest.cs new file mode 100644 index 0000000..a1eb482 --- /dev/null +++ b/WinUI3Localizer.Tests/PriResourceReaderTest.cs @@ -0,0 +1,52 @@ +using FluentAssertions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WinUI3Localizer.Tests; + +public class PriResourceReaderTest +{ + [Fact] + public void GetItems_ReturnsAllItems() + { + LanguageDictionary.Item[]? resourcesItems = null; + LanguageDictionary.Item[]? errorMessagesItems = null; + + Thread? thread = new Thread(() => + { + Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.Initialize(0x00010004); + + string? priFile = Path.Combine(AppContext.BaseDirectory, "resources.pri"); + PriResourceReaderFactory? factory = new(); + + PriResourceReader? reader = factory.GetPriResourceReader(priFile); + + resourcesItems = reader.GetItems("en-US").ToArray(); + errorMessagesItems = reader.GetItems("es-ES", "ErrorMessages").ToArray(); + + Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.Shutdown(); + }); + + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + thread.Join(); + + LanguageDictionary.Item item1 = new LanguageDictionary.Item("ControlsPage_Button", "ContentProperty", "Click", "ControlsPage_Button.Content"); + LanguageDictionary.Item item2 = new LanguageDictionary.Item("StylesPage_Top", "TextProperty", "Top", "StylesPage_Top.Text"); + LanguageDictionary.Item item3 = new LanguageDictionary.Item("/ErrorMessages/ErrorMessageExample", "TextProperty", "Ejemplo de mensajes de error", "/ErrorMessages/ErrorMessageExample.Text"); + + resourcesItems.Should().HaveCount(55); + resourcesItems.Should().Contain(item1); + resourcesItems.Should().Contain(item2); + resourcesItems.Should().NotContain(item3); + + errorMessagesItems.Should().HaveCount(1); + errorMessagesItems.Should().NotContain(item1); + errorMessagesItems.Should().NotContain(item2); + errorMessagesItems.Should().Contain(item3); + } + +} diff --git a/WinUI3Localizer.Tests/WinUI3Localizer.Tests.csproj b/WinUI3Localizer.Tests/WinUI3Localizer.Tests.csproj index 9b0d0f4..79fde94 100644 --- a/WinUI3Localizer.Tests/WinUI3Localizer.Tests.csproj +++ b/WinUI3Localizer.Tests/WinUI3Localizer.Tests.csproj @@ -5,11 +5,14 @@ enable enable false + x86;x64;arm64 + win10-x86;win10-x64;win10-arm64 + @@ -30,4 +33,10 @@ + + + PreserveNewest + + + diff --git a/WinUI3Localizer.Tests/resources.pri b/WinUI3Localizer.Tests/resources.pri new file mode 100644 index 0000000000000000000000000000000000000000..5cfcaffb5eaa23b373b4d5dc05f19a363175a154 GIT binary patch literal 68136 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 F{~vr#03iSX literal 0 HcmV?d00001 diff --git a/WinUI3Localizer.sln b/WinUI3Localizer.sln index 7d0fafb..a4af6de 100644 --- a/WinUI3Localizer.sln +++ b/WinUI3Localizer.sln @@ -46,20 +46,20 @@ Global {C1E60FCC-8B43-4190-ADF1-A28B954F8DEB}.Release|x64.Build.0 = Release|Any CPU {C1E60FCC-8B43-4190-ADF1-A28B954F8DEB}.Release|x86.ActiveCfg = Release|Any CPU {C1E60FCC-8B43-4190-ADF1-A28B954F8DEB}.Release|x86.Build.0 = Release|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|ARM64.Build.0 = Debug|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|x64.ActiveCfg = Debug|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|x64.Build.0 = Debug|Any CPU + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|Any CPU.ActiveCfg = Debug|x64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|Any CPU.Build.0 = Debug|x64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|ARM64.ActiveCfg = Debug|arm64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|ARM64.Build.0 = Debug|arm64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|x64.ActiveCfg = Debug|x64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|x64.Build.0 = Debug|x64 {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|x86.ActiveCfg = Debug|Any CPU {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Debug|x86.Build.0 = Debug|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|Any CPU.Build.0 = Release|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|ARM64.ActiveCfg = Release|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|ARM64.Build.0 = Release|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|x64.ActiveCfg = Release|Any CPU - {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|x64.Build.0 = Release|Any CPU + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|Any CPU.ActiveCfg = Release|x64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|Any CPU.Build.0 = Release|x64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|ARM64.ActiveCfg = Release|arm64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|ARM64.Build.0 = Release|arm64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|x64.ActiveCfg = Release|x64 + {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|x64.Build.0 = Release|x64 {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|x86.ActiveCfg = Release|Any CPU {46D3D143-8BBF-4A74-960D-8CD34F35B58E}.Release|x86.Build.0 = Release|Any CPU {CF4A3EBB-18DA-4234-B0DB-3CD45AF4B054}.Debug|Any CPU.ActiveCfg = Debug|x64 diff --git a/WinUI3Localizer/LocalizerBuilder.cs b/WinUI3Localizer/LocalizerBuilder.cs index 98bda66..ac142f8 100644 --- a/WinUI3Localizer/LocalizerBuilder.cs +++ b/WinUI3Localizer/LocalizerBuilder.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.CompilerServices; using System.Threading.Tasks; using System.Xml; @@ -27,6 +28,8 @@ private record StringResourceItems(string Language, IEnumerable Localizer.Get() is Localizer; public LocalizerBuilder SetDefaultStringResourcesFileName(string fileName) @@ -86,6 +89,33 @@ public LocalizerBuilder AddStringResourcesFolderForLanguageDictionaries( return this; } + public LocalizerBuilder AddPriResourcesForLanguageDictionaries( + string[] languages, + string? subTreeName = null, + string? priFile = null) + { + this.builderActions.Add(() => + { + if (this.priResourceReaderFactory == null) + { + this.priResourceReaderFactory = new(); + } + + for (int i = 0; i < languages.Length; i++) + { + PriResourceReader? reader = this.priResourceReaderFactory.GetPriResourceReader(priFile); + + LanguageDictionary? dictionary = new(languages[i]); + foreach (LanguageDictionary.Item item in reader.GetItems(languages[i], subTreeName)) + { + dictionary.AddItem(item); + } + this.languageDictionaries.Add(dictionary); + } + }); + return this; + } + public LocalizerBuilder AddLanguageDictionary(LanguageDictionary dictionary) { this.builderActions.Add(() => this.languageDictionaries.Add(dictionary)); @@ -167,17 +197,20 @@ private static LanguageDictionary CreateLanguageDictionaryFromStringResourceItem return dictionary; } - private static LanguageDictionary.Item CreateLanguageDictionaryItem(StringResourceItem stringResourceItem) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static LanguageDictionary.Item CreateLanguageDictionaryItem(StringResourceItem stringResourceItem) => + CreateLanguageDictionaryItem(stringResourceItem.Name, stringResourceItem.Value); + + internal static LanguageDictionary.Item CreateLanguageDictionaryItem(string name, string value) { - string name = stringResourceItem.Name; (string Uid, string DependencyPropertyName) = name.IndexOf(".") is int firstSeparatorIndex && firstSeparatorIndex > 1 ? (name[..firstSeparatorIndex], string.Concat(name.AsSpan(firstSeparatorIndex + 1), "Property")) : (name, string.Empty); return new LanguageDictionary.Item( Uid, DependencyPropertyName, - stringResourceItem.Value, - stringResourceItem.Name); + value, + name); } private static StringResourceItems? CreateStringResourceItemsFromResourcesFile(string sourceName, string filePath, string xPath = "//root/data") diff --git a/WinUI3Localizer/PriResourceReader.cs b/WinUI3Localizer/PriResourceReader.cs new file mode 100644 index 0000000..3d6b8eb --- /dev/null +++ b/WinUI3Localizer/PriResourceReader.cs @@ -0,0 +1,97 @@ +using Microsoft.Windows.ApplicationModel.Resources; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WinUI3Localizer; +internal class PriResourceReader +{ + private readonly ResourceManager resourceManager; + + internal PriResourceReader(ResourceManager resourceManager) + { + this.resourceManager = resourceManager; + } + + public IEnumerable GetItems(string language, string subTreeName = "Resources") + { + if (string.IsNullOrEmpty(subTreeName) || subTreeName == "/") + { + subTreeName = "Resources"; + } + else if (subTreeName.EndsWith('/')) + { + subTreeName = subTreeName[..^1]; + } + + ResourceMap resourceMap = this.resourceManager.MainResourceMap.TryGetSubtree(subTreeName); + if (resourceMap != null) + { + ResourceContext resourceContext = this.resourceManager.CreateResourceContext(); + resourceContext.QualifierValues[KnownResourceQualifierName.Language] = language; + + return GetItemsCore(resourceMap, subTreeName, resourceContext); + } + + return Enumerable.Empty(); + } + + + private IEnumerable GetItemsCore(ResourceMap resourceMap, string subTreeName, ResourceContext resourceContext) + { + bool isResourcesSubTree = string.Equals(subTreeName, "Resources", StringComparison.OrdinalIgnoreCase); + uint count = resourceMap.ResourceCount; + + for (uint i = 0; i < count; i++) + { + (string key, ResourceCandidate? candidate) = resourceMap.GetValueByIndex(i, resourceContext); + + if (candidate != null && candidate.Kind == ResourceCandidateKind.String) + { + key = key.Replace('/', '.'); + if (!isResourcesSubTree) + { + key = $"/{subTreeName}/{key}"; + } + yield return LocalizerBuilder.CreateLanguageDictionaryItem(key, candidate.ValueAsString); + } + } + } + +} + +internal class PriResourceReaderFactory +{ + private readonly Dictionary readers = new Dictionary(); + + internal PriResourceReader GetPriResourceReader(string? priFile) + { + string? normalizedFilePath = string.Empty; + + if (!string.IsNullOrEmpty(priFile)) + { + normalizedFilePath = System.IO.Path.GetFullPath(priFile); + } + + if (!this.readers.TryGetValue(normalizedFilePath, out PriResourceReader? reader)) + { + ResourceManager manager; + if (string.IsNullOrEmpty(normalizedFilePath)) + { + manager = new ResourceManager(); + } + else + { + manager = new ResourceManager(normalizedFilePath); + } + reader = new PriResourceReader(manager); + this.readers[normalizedFilePath] = reader; + } + + return reader; + } +} + From d8cfc795ba7af85b294b5211dcaafeb0c5cceeb5 Mon Sep 17 00:00:00 2001 From: cnbluefire <909683964@qq.com> Date: Fri, 12 Apr 2024 20:56:46 +0800 Subject: [PATCH 2/2] Update the test project's WinAppSDK package version. --- WinUI3Localizer.Tests/PriResourceReaderTest.cs | 2 +- WinUI3Localizer.Tests/WinUI3Localizer.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WinUI3Localizer.Tests/PriResourceReaderTest.cs b/WinUI3Localizer.Tests/PriResourceReaderTest.cs index a1eb482..5578c75 100644 --- a/WinUI3Localizer.Tests/PriResourceReaderTest.cs +++ b/WinUI3Localizer.Tests/PriResourceReaderTest.cs @@ -17,7 +17,7 @@ public void GetItems_ReturnsAllItems() Thread? thread = new Thread(() => { - Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.Initialize(0x00010004); + Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.Initialize(0x00010005); string? priFile = Path.Combine(AppContext.BaseDirectory, "resources.pri"); PriResourceReaderFactory? factory = new(); diff --git a/WinUI3Localizer.Tests/WinUI3Localizer.Tests.csproj b/WinUI3Localizer.Tests/WinUI3Localizer.Tests.csproj index 79fde94..f81b1e0 100644 --- a/WinUI3Localizer.Tests/WinUI3Localizer.Tests.csproj +++ b/WinUI3Localizer.Tests/WinUI3Localizer.Tests.csproj @@ -12,7 +12,7 @@ - +