【问题标题】:.NET loading incorrect resource file.NET 加载不正确的资源文件
【发布时间】:2015-10-26 16:28:19
【问题描述】:

我遇到了一个问题,即 .NET 似乎正在加载不正确的资源文件,并且我没有在网上找到任何遇到类似问题的资源。到目前为止,这仅在我们尝试获取要通过电子邮件发送的信息时发生在后端服务器上。运行它的服务器上的文化是 en-US。

这是我得到的(略微编辑的)堆栈跟踪:

Could not find file ''C:\Customer\App\SubDir1\SubDir2\SubDir3\ClassLibrary.resources.dll''.
mscorlib
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) 
   at <Custom Wrapper for Assembly Loading>

 at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(String name, CultureInfo culture, Version version, Boolean throwOnFileNotFound, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GetSatelliteAssembly(CultureInfo lookForCulture, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary`2 localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   at System.Resources.ResourceManager.GetString(String name, CultureInfo culture) 
   at Project.ClassLibraryResources.SubNamespace2.get_Unit()

我们确实有资源(其中两个在 ClassLibrary.dll 中,在不同的命名空间下),但它们嵌入在 DLL 中,因此 ClassLibrary.resources.dll 文件不存在。

我们没有更改资源搜索位置的 .config 文件,因此我们没有让它寻找附属程序集(即 ClassLibrary.resources.dll)。

其他资源似乎加载成功,而这个问题是在我们升级到 .NET 4.5.2 后才开始出现的,几年来没有对失败的 DLL 进行任何代码更改。

根据顶部的评论here,我一直在尝试使用 PerfMonitor 来跟踪资源管理器的事件以查看它正在尝试做什么,但我没有任何运气让它工作至今。我也一直在思考链接文件中的代码以查看可能发生的情况,但结果并不理想。

我已经修改了尝试访问 Unit 资源的函数以打印出当前线程的文化,并按预期打印出 en-US。

编辑: 通过fusionview logger运行它后,我看到它首先尝试在en文化下加载资源,然后再次在en-US文化下加载。它检查应用程序的配置文件,没有找到主机配置文件,并检查机器配置文件。这些都没有告诉资源寻找附属程序集。 结束编辑。

第二次编辑: 我还想重申我们确实有一个自定义程序集解析器/加载器。它检查文件是否存在,如果存在,则对其执行 Assembly.LoadFrom()。如果它不存在,它会检查第二个可能的位置并尝试对其执行 Assembly.LoadFrom()。当我们打开文件流时,这在第二个 Assembly.LoadFrom 之前失败。我意识到我们可能应该将其更改为使用配置文件来更改查看位置。我不认为这是问题所在。 结束第二次编辑。

什么可能导致此错误?有没有更好的方法来访问 ResourceManager 的跟踪详细信息?

任何指针将不胜感激!

【问题讨论】:

  • 你得到了什么例外?
  • “找不到文件”。大概是 FileNotFound 异常。 FusionLogVw报0x80070002-“系统找不到指定的文件。”
  • 嗯...应该是 MissingManifestResourceException 或 MissingSatelliteAssemblyExcwption according to the docs。如果它是可能指向您的其中之一,那么它就是正确的方向。
  • 我会仔细检查一下到底是哪个异常被抛出。文档确实提到有时可以抛出 FileLoadException,但你说得对,其他异常听起来更有可能。在检查了确切的异常之后,它是 FileNotFoundException。我们确实有许多这样的异常,但看起来大多数都得到了优雅的处理,除了这个 ClassLibrary.resources.dll 之一。这至少意味着我可以检查其他地方,看看我们是否在那里吞下了异常。

标签: c# .net resource-files


【解决方案1】:

堆栈跟踪表明您正在使用CultureInfo 调用GetString 重载。究竟为 Culture 传递了什么值?为什么不调用没有文化的 GetString 重载? 您是否在程序集中指定了NeutralResourcesLanguageAttribute

【讨论】:

  • GetString 调用是 Visual Studios 生成的默认调用,它传入当前线程的 CurrentUICulture 属性。看起来以前我正在检查线程的 CurrentCulture,所以我也会仔细检查 CurrentUICulture。我没有指定那个属性。我也会调查一下,谢谢!
  • CurrentCulture 和 CurrentUICulture 都设置为 en-US。
  • 将 NeutralResourcesLanguage 属性添加到 AssemblyInfo.cs 文件可解决此问题。这似乎与 ClassLibrary.dll 将其资源设置为公共的事实有关,而我们应用程序中的所有其他内容都将它们设为私有。 .NET 4.5.2 一定改变了处理方式,但它现在可以工作了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
  • 2015-11-20
相关资源
最近更新 更多