如何将具有嵌入式字符串资源的 .NET 3.5 兼容程序集移植到 .NET 4.0?

发布于 2024-12-16 11:28:03 字数 1249 浏览 4 评论 0原文

我将一些基于 .NET-3.5 的项目转换为 .NET Framework 4.0,并在程序集嵌入的字符串资源方面遇到了麻烦。

该代码包含对资源字符串的引用,例如 Resources.ValidationFailedMsg。这里的Resources是一个自动生成的类。它的完全限定名称是 MyAssembly.Properties.Resources(程序集名称是 MyAssembly.dll,为了简单起见,其中所有内容的根命名空间也是 MyAssembly)。项目的“Properties”文件夹包含Resources.resx,其中定义了字符串ValidationFailedMsg(例如“验证失败!”)并从中生成Resources.Designer.cs 文件。

现在让我们运行这个东西。发生的情况如下:

System.IO.FileNotFoundException:无法加载文件或程序集“MyAssembly.resources....

请问,什么文件???

首先,我了解二进制 .resource 文件的概念,以及如何在多种文化中存在许多此类文件,但让我们首先使用默认文化。从该项目的 .NET 2.0 到 3.5 兼容版本,所有字符串都嵌入到程序集本身中,因此框架甚至不会在除 MyAssembly.dll 之外的任何地方查找它们。 如何让它查看程序集而不查看其他任何内容?

其次,我注意到项目的 bin\Debug 目录中有一个 .resource 文件,但它的名称为 MyAssembly .Properties.Resources.resources,而不是 MyAssembly.resources,并且 msbuild 不会将其复制到 bin\Debug 或引用 MyAssembly 的其他任何位置。这是对这里可能出现问题的有用提示吗?

第三,我可以在 Visual Studio 2010 中打开一个新的空项目,在属性下添加 Resources.resx,在其中放置一个字符串,在代码中将其引用为 TestProject.Properties.Resources.String1,构建,它的工作方式就像魅力一样。但在旧项目中,即使读取 Resource.resx 及其字符串也无济于事。

您能否解释一下为什么 .NET 4.0 将这些字符串编译到一个位置,然后在不同的位置查找它们,从而导致 FileNotFoundException?将具有此类嵌入字符串资源的 .NET 3.5 兼容程序集迁移到 .NET 4.0 的正确方法是什么?

I was converting some .NET-3.5-based projects to .NET Framework 4.0 and ran into trouble with assembly-embedded string resources.

The code contains references to resource strings like Resources.ValidationFailedMsg. Resources here is an automatically generated class. It's fully-qualified name is MyAssembly.Properties.Resources (the assembly name is MyAssembly.dll and, to keep it simple, the root namespace of everything in it is also MyAssembly). The project's "Properties" folder contains Resources.resx, where the string ValidationFailedMsg is defined (e.g. "Validation failed!") and the Resources.Designer.cs file is generated from it.

Now let's run this thing. Here's what happens:

System.IO.FileNotFoundException : Could not load file or assembly 'MyAssembly.resources....

Excuse me, what file???

First, I understand the concept of binary .resource files and how there may many such files for many cultures, but let's get one, default culture to work first. From .NET 2.0 to 3.5- compatible versions of this project, all strings were embedded in the assembly itself, so the framework didn't even look for them anywhere except MyAssembly.dll. How can I make it look at the assembly and not look at anything else?

Second, I noticed a .resource file in the project's bin\Debug directory, but it's named MyAssembly.Properties.Resources.resources, not MyAssembly.resources, and msbuild doesn't copy it to bin\Debug or anywhere else where MyAssembly is referenced. Is this a useful hint to what may be going wrong here?

Third, I can open a new, empty project in Visual Studio 2010, add Resources.resx under properties, put a string there, reference it in the code as TestProject.Properties.Resources.String1, build, and it works like charm. But in the old project, even readding Resource.resx with its strings doesn't help.

Can you explain why .NET 4.0 compiles these string into one place and then looks for them in a different place, causing the FileNotFoundException? And what is the proper way to migrate a .NET 3.5-compatible assembly with such embedded string resources to .NET 4.0?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

过度放纵 2024-12-23 11:28:03

谜团已解决。

.NET(4.0 之前)首先查找 .resource 文件。如果未找到该文件,它将在程序集中查找以查找请求的资源。

从 .NET 4.0 开始,如果 .resource 文件不存在,框架将触发 AppDomain.AssemblyResolve 事件并传递资源文件名来代替程序集名称。 (为什么AssemblyResolve? - 这可能是一个错误。)仅当未处理此事件时,.NET 4.0 才会在程序集中查找资源。

碰巧的是,该应用程序注册了一个 AssemblyResolve 处理程序。该处理程序被编程为定位 DLL,多年来从未失败,直到 .NET 4.0 升级那天,当时要求它定位不存在的资源文件。

Mystery solved.

.NET (before 4.0) looks for the .resource file first. If the file is not found, it looks inside the assembly to find the requested resource.

Starting with .NET 4.0, if the .resource file doesn't exist, the framework fires an AppDomain.AssemblyResolve event and passes the resource file name in place of the assembly name. (Why AssemblyResolve? - this is probably a bug.) Only if this event is not handled, does .NET 4.0 look inside the assembly for the resource.

As it happened, the application had an AssemblyResolve handler registered. The handler was programmed to locate DLLs and never failed for years until the day of the .NET 4.0 upgrade, when it was asked to locate a nonexistent resource file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文