5

下面的程序应该从卫星资源文件中获取资源字符串。使用 VS2015 使用 target framework='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 

看起来卫星 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();
    }
}

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

4

1 回答 1

0

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

问题确认

首先确认问题。

  1. 在 Visual Studio 中,转到 Tools / Options / Projects and Solutions /
    Build and Run 并将MS Build project build output verbosity设置为至少Normal(默认为 Minimal)。

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

  3. 在 Output / Build 窗口中查找任务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(您的系统上的确切路径可能会有所不同,例如专业版而不是企业版)。
  2. 创建此文件的备份副本。
  3. 编辑文件,找到包含文本的行_ALExeToolPath。它应该在第 3739 行附近。看起来像这样:
    <PropertyGroup>
      <_ALExeToolPath>$(TargetFrameworkSDKToolsDirectory)</_ALExeToolPath>
      <_ALExeToolPath Condition="'$(PlatformTarget)' == 'x64'">$(TargetFrameworkSDKToolsDirectory)$(PlatformTarget)\</_ALExeToolPath>
    </PropertyGroup>
  1. 现在向下滚动到AL下面的标签并找到SdkToolsPath属性。
    <AL AlgorithmId="$(Satellite_AlgorithmId)"
        BaseAddress="$(Satellite_BaseAddress)"
    ...
        SdkToolsPath="$(SdkToolsPathMaybeWithx64Architecture)"  <!-- this is incorrect -->
  1. 将属性的值从 更改$(SdkToolsPathMaybeWithx64Architecture)$(_ALExeToolPath)
  2. 保存文件(可能需要提升)
  3. 重建您的项目,使用正确的链接器,您的资源 dll 将再次工作。

原因

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

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

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

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

如果您不能等待,请按照我上面描述的解决方法。

于 2021-07-20T07:19:45.050 回答