You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于CultureInfo获取.resx翻译文件失败及.NET版本不匹配问题排查

问题:基于CultureInfo获取.resx翻译文件失败,且翻译程序集版本不兼容

问题现象

  • 翻译解决方案包含4个.resx文件:对应意大利语(it)、荷兰语(nl)、德语(de)、英语(默认)版本
  • 应用程序引用Qit.WindowsStrings.dll,通过以下代码调用翻译内容:
    lblAddress1.Text = Qit.WindowsStrings.WinStrings.Address1;
    
  • 始终只能获取默认英文.resx内容,无法加载对应CultureInfo的翻译文件
  • 目标框架为.NET Framework 3.5的应用程序加载部分翻译程序集时,抛出错误:

    This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

排查结果

使用DotPeek分析发现,无法正常工作的翻译程序集是基于.NET Framework 4.0构建的,但包含这些.resx的项目本身目标框架是.NET Framework 3.5。

疑问

  1. 为何项目目标框架为3.5,但生成的部分翻译程序集却是4.0版本?
  2. 如何解决该问题?是否需要删除现有语言.resx文件(如winstrings.de.resx)重新创建并构建?

附:Qit.WindowsStrings项目的.csproj文件内容

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.30703</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{005BF8BB-23CE-402A-BB2D-CC1AE9CC326B}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Qit.WindowsStrings</RootNamespace>
    <AssemblyName>Qit.WindowsStrings</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <SccProjectName>SAK</SccProjectName>
    <SccLocalPath>SAK</SccLocalPath>
    <SccAuxPath>SAK</SccAuxPath>
    <SccProvider>SAK</SccProvider>
    <TargetFrameworkProfile />
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup>
    <SignAssembly>true</SignAssembly>
  </PropertyGroup>
  <PropertyGroup>
    <AssemblyOriginatorKeyFile>qit.snk</AssemblyOriginatorKeyFile>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Core">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Utils.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="WinStrings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>WinStrings.resx</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="WinStrings.de.resx">
      <SubType>Designer</SubType>
    </EmbeddedResource>
    <EmbeddedResource Include="WinStrings.it.resx" />
    <EmbeddedResource Include="WinStrings.nl.resx" />
    <EmbeddedResource Include="WinStrings.resx">
      <Generator>PublicResXFileCodeGenerator</Generator>
      <LastGenOutput>WinStrings.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="qit.snk" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

分析与解决方案

异常点排查

从.csproj文件可发现两处关键问题:

  1. 项目指定ToolsVersion="4.0",但.NET Framework 3.5通常对应MSBuild ToolsVersion 3.5,工具版本不匹配可能导致构建逻辑异常
  2. 非默认语言的.resx文件配置不一致:WinStrings.de.resx设置了<SubType>Designer</SubType>但未指定<Generator>,而默认WinStrings.resx使用了PublicResXFileCodeGenerator,配置差异会导致附属程序集生成逻辑混乱

版本不匹配的原因

  1. MSBuild工具链冲突:项目使用ToolsVersion 4.0构建,即使目标框架是3.5,若构建环境优先调用.NET 4.0的MSBuild,会导致附属程序集(如Qit.WindowsStrings.de.dll)在生成时继承4.0版本的运行时依赖
  2. 附属程序集构建逻辑:资源附属程序集的构建过程未严格遵循主项目的目标框架配置,转而使用了当前MSBuild工具的默认版本

解决步骤

  1. 统一MSBuild工具版本
    修改.csproj文件头部的ToolsVersion为3.5,确保构建工具与目标框架匹配:

    <Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
  2. 规范资源文件配置
    为所有非默认语言的.resx文件添加统一的生成器配置,确保附属程序集生成逻辑一致:

    <EmbeddedResource Include="WinStrings.de.resx">
      <Generator>PublicResXFileCodeGenerator</Generator>
      <LastGenOutput>WinStrings.de.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
    <EmbeddedResource Include="WinStrings.it.resx">
      <Generator>PublicResXFileCodeGenerator</Generator>
      <LastGenOutput>WinStrings.it.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
    <EmbeddedResource Include="WinStrings.nl.resx">
      <Generator>PublicResXFileCodeGenerator</Generator>
      <LastGenOutput>WinStrings.nl.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
    
  3. 清理并重新构建

    • 删除项目的bin、obj目录,彻底清除旧的构建产物
    • 重新构建整个解决方案,确保所有附属程序集均基于.NET Framework 3.5生成
  4. 验证CultureInfo设置
    确保应用程序中正确设置线程的区域信息,例如:

    Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");
    

内容的提问来源于stack exchange,提问作者r-m85

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:06:03