【问题标题】:Satellite resource .dll's compiles to wrong .net framework?卫星资源 .dll 编译为错误的 .net 框架?
【发布时间】:2015-12-06 16:04:31
【问题描述】:

下面的程序应该从卫星资源文件中获取资源字符串。使用 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 并没有! (我想知道注册表数据库中是否有一些东西不会通过简单的重新安装来重置)

【问题讨论】:

  • 不是一个常见的抱怨,唯一明显的原因是卫星 dll 没有重建。更常见的问题是 .resx 文件仍然包含 4.0 类型引用。它们只有在您对它们进行更改时才会被重写,并且在您更改框架目标后很容易被忽略。使用文本编辑器查看文件。
  • 不,事实并非如此。我也想到了它,所以为了确保不是这种情况,我删除了整个 bin 目录,然后重新编译。问题依然存在。
  • 我也有这个问题
  • 对我来说恰恰相反,它一直有效,直到我完成了 Windows 的全新安装,然后它开始为 .net 3.5 程序生成 .net 4.0 资源。因此,可悲的是,全新安装不是解决方案/解决方法。
  • 试试this solution,虽然它说的是VS2017,但修复应该适用于类似情况。

标签: c# .net resources satellite-assembly


【解决方案1】:

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

问题确认

首先确认问题。

  1. 在 Visual Studio 中,转到工具/选项/项目和解决方案/
    Build and Run 并将 MS Build project build output verbosity 设置为 至少 Normal(默认为 Minimal)。

  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

到目前为止,问题与link by hultqvist's comment 中提到的问题相同。但是,原因和解决方案是不同的。那里提到的注册表项在我的系统上非常好。

​​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 将再次工作。

原因

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

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

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

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

如果你等不及了,请按照我上面描述的解决方法。

【讨论】:

    猜你喜欢
    • 2011-08-02
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多