dotnet SDK构建时生成restext本地化字符串资源的配置方法
SDK风格.NET Framework 4.8项目restext本地化资源构建配置方案
restext是和resx逻辑完全兼容的纯文本键值对资源格式,通过对接SDK原生构建任务即可实现需求,无需第三方依赖,同时兼容VS可视化构建和dotnet命令行构建。
第一步:项目基础属性配置
先调整SDK风格csproj的基础属性,关闭默认资源自动包含规则避免冲突:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net48</TargetFramework> <RootNamespace>替换为你的项目默认命名空间</RootNamespace> <AssemblyName>替换为你的输出程序集名称</AssemblyName> <!-- 关闭默认嵌入式资源自动收录,避免原始restext被误打包 --> <EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems> </PropertyGroup>
第二步:批量引入restext资源并配置元数据
在csproj中加入资源项配置,自动识别所有语种的restext文件,提取对应文化标识、生成路径等参数:
<!-- 批量收录所有带语种后缀的restext文件 --> <ItemGroup> <RestextResource Include="Resources\Strings\strings.*.restext" /> <!-- 如果你有中立主语言的无后缀restext,取消下面这行注释即可 <RestextResource Include="Resources\Strings\strings.restext" /> --> </ItemGroup> <!-- 配置每个restext文件的构建参数 --> <ItemGroup> <!-- 带语种后缀的资源配置 --> <RestextResource Update="Resources\Strings\strings.*.restext" Type="Non-ResX" LogicalName="$(RootNamespace).Resources.Strings.strings.%(Filename.Substring(8)).resources" Culture="%(Filename.Substring(8))" OutputResource="$(IntermediateOutputPath)%(Filename).resources" StronglyTypedFileName="$(IntermediateOutputPath)Strings.Designer.cs" StronglyTypedLanguage="C#" StronglyTypedNamespace="$(RootNamespace).Resources.Strings" StronglyTypedClassName="Strings" StronglyTypedPublic="true" /> <!-- 中立无后缀主语言资源配置,使用时替换上面的主语言条目即可 <RestextResource Update="Resources\Strings\strings.restext" Type="Non-ResX" LogicalName="$(RootNamespace).Resources.Strings.strings.resources" OutputResource="$(IntermediateOutputPath)strings.resources" StronglyTypedFileName="$(IntermediateOutputPath)Strings.Designer.cs" StronglyTypedLanguage="C#" StronglyTypedNamespace="$(RootNamespace).Resources.Strings" StronglyTypedClassName="Strings" StronglyTypedPublic="true" /> --> </ItemGroup>
上述配置中
Substring(8)对应strings.固定前缀的长度,如果你修改了资源文件命名规则,对应调整截取起始索引即可。
第三步:注入自定义构建目标对接原生构建任务
直接调用SDK自带的GenerateResource任务处理restext文件,生成二进制.resources资源和强类型Designer类,再将产物嵌入最终程序集:
<!-- 转换restext为二进制资源,生成强类型类 --> <Target Name="ConvertRestextToResources" BeforeTargets="BeforeCompile;GenerateResource" Inputs="@(RestextResource)" Outputs="@(RestextResource->'%(OutputResource)')"> <GenerateResource Sources="@(RestextResource)" OutputResources="@(RestextResource->'%(OutputResource)')" StronglyTypedFileName="@(RestextResource->'%(StronglyTypedFileName)')" StronglyTypedLanguage="C#" StronglyTypedNamespace="@(RestextResource->'%(StronglyTypedNamespace)')" StronglyTypedClassName="@(RestextResource->'%(StronglyTypedClassName)')" StronglyTypedPublic="@(RestextResource->'%(StronglyTypedPublic)')" UseSourcePath="true" PublicClass="true"> <Output TaskParameter="FilesWritten" ItemName="FileWrites"/> <Output TaskParameter="OutputResources" ItemName="_GeneratedRestextResources"/> </GenerateResource> <!-- 将生成的强类型类加入编译列表 --> <ItemGroup> <Compile Include="@(RestextResource->'%(StronglyTypedFileName)')" Visible="false" /> </ItemGroup> </Target> <!-- 将生成的二进制资源嵌入最终EXE --> <Target Name="EmbedGeneratedRestextResources" BeforeTargets="GenerateEmbeddedResources" DependsOnTargets="ConvertRestextToResources"> <ItemGroup> <EmbeddedResource Include="@(_GeneratedRestextResources)" LogicalName="%(RestextResource.LogicalName)" Culture="%(RestextResource.Culture)" Visible="false" /> </ItemGroup> </Target> </Project>
验证与使用
- 命令行构建:在项目根目录执行
dotnet build即可完成编译,增量构建会自动识别restext改动,不会重复全量编译 - VS构建:直接在VS2019中点击生成即可,无需重启IDE,中间生成文件默认不会显示在解决方案资源管理器中
- 运行时调用:使用标准
ResourceManager访问资源即可,示例代码:
using System.Resources; using System.Globalization; var resourceManager = new ResourceManager("你的项目默认命名空间.Resources.Strings.strings", typeof(Program).Assembly); // 读取默认语种字符串 string defaultVal = resourceManager.GetString("你的资源键名"); // 读取指定语种字符串 string deVal = resourceManager.GetString("你的资源键名", new CultureInfo("de_DE"));
注意事项
- restext文件请使用UTF-8带BOM编码保存,避免非英文字符乱码
- 如果需要强类型资源类为internal访问级别,将配置中
StronglyTypedPublic="true"改为false即可 - 所有构建逻辑完全基于SDK原生任务实现,无额外依赖,命令行和VS构建走同一套管线,不会出现产物不一致问题
内容的提问来源于stack exchange,提问作者Torsten Crass
相关产品推荐
相关产品推荐

