卫星资源 .dll 编译为错误的 .net 框架?

Mad*_*dsN 5 .net c# resources satellite-assembly

下面的程序应该从卫星资源文件中获取资源字符串。使用 VS2015 使用目标框架 = NET Framework 4.5.2' 进行编译时,它可以正常工作。但是,设置 target framework='NET Framework 3.5' 使其无法找到卫星资源文件并回退到默认资源。

我查看了 .exe 和卫星 .dll 文件,发现它们被编译为不同的 .net 版本(尽管生成它们的是同一个编译):

Main exe got:                  .Net Framework v3.5
Satellite resource dll got:    .Net Framework v4.0 
Run Code Online (Sandbox Code Playgroud)

它接缝就像卫星 dll 获取错误的 .Net 版本。有没有人遇到过这种情况,有解决办法吗?(除了将项目升级到最新的 .Net 版本)

class Program
{
    static void Main(string[] args)
    {

        CultureInfo newCultureInfo = new System.Globalization.CultureInfo("da-DK");
        Thread.CurrentThread.CurrentUICulture = newCultureInfo;

        Console.WriteLine("Resource test");
        ResourceManager rm = new ResourceManager("ResourceTest.Resources.MyResources", Assembly.GetExecutingAssembly());

        Console.WriteLine(rm.GetString("hello"));

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:接缝就像我对我的开发环境进行了错误的更新。重新安装整台计算机有帮助,但简单地重新安装 .Net 和 Visual Studio 并没有!(我想知道注册表数据库中是否有一些东西不会通过简单的重新安装来重置)

M-P*_*ror 1

我知道这个问题已经有近六年的历史了,但这在今天的 Visual Studio 2019 中又是一个问题。我已经在 16.10.2 和 16.10.3(可能更多)中确认了这一点。构建 .Net 3.5 应用程序给我留下了无法工作的资源 dll,这让我很困惑,直到我发现您的问题暗示要调查资源 dll .Net 版本,发现这些确实链接到 .Net 4 mscorlib 而不是 3.5。

问题确认

首先确认问题。

  1. 在 Visual Studio 中,转到“工具”/“选项”/“项目和解决方案”/“
    生成并运行”,并将MS Build 项目生成输出详细程度至少设置为“正常”(默认为“最小”)。

  2. 重建您的.Net 3.5 项目。

  3. 在“输出/构建”窗口中查找任务“GenerateSatelliteAssemblies:”。下面的命令行显示C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\al.exe,这是 .Net 4.8 版本的汇编链接器。在未受影响的系统上,这应该是C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\al.exe

到目前为止,与hultqvist 对问题的评论的链接中提到的问题相同。然而,原因和解决方案是不同的。那里提到的注册表项在我的系统上完全正常。

TL;DR - 解决方案(解决方法)

  1. 转至C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(您的系统上的确切路径可能略有不同,例如 Professional 而不是 Enterprise)。
  2. 创建此文件的备份副本。
  3. 编辑该文件,找到包含文本 的行_ALExeToolPath。它应该在第 3739 行左右。看起来像这样:
    <PropertyGroup>
      <_ALExeToolPath>$(TargetFrameworkSDKToolsDirectory)</_ALExeToolPath>
      <_ALExeToolPath Condition="'$(PlatformTarget)' == 'x64'">$(TargetFrameworkSDKToolsDirectory)$(PlatformTarget)\</_ALExeToolPath>
    </PropertyGroup>
Run Code Online (Sandbox Code Playgroud)
  1. 现在向下滚动到AL下面的标签并找到该SdkToolsPath属性。
    <AL AlgorithmId="$(Satellite_AlgorithmId)"
        BaseAddress="$(Satellite_BaseAddress)"
    ...
        SdkToolsPath="$(SdkToolsPathMaybeWithx64Architecture)"  <!-- this is incorrect -->
Run Code Online (Sandbox Code Playgroud)
  1. 将属性值从 更改$(SdkToolsPathMaybeWithx64Architecture)$(_ALExeToolPath)
  2. 保存文件(可能需要海拔)
  3. 重建您的项目,使用正确的链接器,您的资源 dll 将再次工作。

原因

此处引入此问题是为了修复针对 x64 与 x86 时程序集链接器的一个小问题。如果您关注该 PR 的评论线程,您会发现错误:修复中的实际变量在讨论后被重命名,但他们忘记在合并 PR 之前更新 AL 属性中的变量。

因此,al.exe 的 sdk 工具路径为空(它提到了一个不存在的变量),这导致 msbuild 始终调用默认值,这通常是系统上最新安装的框架 sdk 的 x86 版本 --而不是与您的项目版本匹配的版本。

该版本的.targets文件已随 VS 更新一起推出。

从那时起他们就发现了错误并修复了它。截至今天,该修复尚未推出。如果我正确理解讨论,它的目标是使用 v16.11 发布。

如果您等不及,请按照我上面描述的解决方法进行操作。