首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Assembly.Load和它的怪异..。“找不到文件或程序集”错误

Assembly.Load和它的怪异..。“找不到文件或程序集”错误
EN

Stack Overflow用户
提问于 2020-05-15 04:37:57
回答 1查看 180关注 0票数 0

我们的本地化团队正在尝试使用LocBaml (.NET框架版本,4.6.1)来本地化一些资源。他们不断收到“找不到文件或程序集...”的错误。所以,我查看了一下,发现x.resources.dll文件必须与x.dll位于相同的目录中。("x“只是指某个名字)。我试过了,还是会犯同样的错误。然后,我构建了一个调试版本,并下载了.NET源代码。原来在.NET内部发生了一些异常,如果我可以总结一下,它在尝试执行Assembly.Load("x")时失败了。所以我写了一个程序试图复制这种情况...

代码语言:javascript
复制
using System;
using System.Reflection;
using System.Linq;

namespace Nothing
{
   class Loader
   {
      public static void Main(string[] args)
      {
         try
         {
            if (args.Count() == 1)
            {
               Assembly asm = Assembly.Load(args[0]);

               Console.WriteLine($"Name of asembly: {asm.FullName}");
            }
            else
            {
               Console.WriteLine("Need to specify filename");
            }
         }
         catch (Exception x)
         {
            Console.WriteLine("Exception: {0}", x);
         }
      }
   }
}

该文件被命名为AsmLoader.cs并编译为AsmLoader.exe。

在x.dll所在的目录中,我输入了\path\to\AsmLoader.exe x.dll和\path\to\AsmLoader.exe x。同样的错误,“找不到文件或程序集...”

查看了异常的堆栈跟踪,发现"codebase“是堆栈上某个函数的参数。考虑了一下,并将AsmLoader.exe复制到与x.dll相同的目录中。

已向.\AsmLoader.exe x.dll发送与try..still相同的错误。记住异常的参数只是"x“。已尝试.\AsmLoader.exe x....答对了。起作用了。对于grins,将LocBaml.exe和它的.config文件复制到同一目录,并尝试.\LocBaml x.resources.dll ...丁丁丁...成功。终于来了。

因此,现在,我将告诉本地化团队将LocBaml复制到与文件相同的目录中,一切都应该很好。

然而,我不禁觉得这可以通过代码来解决。如何对示例中的代码进行更改,使AsmLoader.exe不必与要加载的DLL位于同一目录中?我甚至更改了path环境变量,以确保AsmLoader.exe和两个x.dll目录都在path中。那不管用。

那么我需要做些什么才能让它在我的基本program...and中工作,然后也许我可以对LocBaml做同样的事情...?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-15 23:34:55

好吧,我想出了一个解决方案,将AssemblyResolve事件处理程序添加到当前应用程序域中。解决了这个简单的例子和我重建的LocBaml...

在main中,添加:

代码语言:javascript
复制
AppDomain.CurrentDomain.AssemblyResolve += LoadFromCurrentDirectory;

像这样实现LoadFromCurrentDirectly:

代码语言:javascript
复制
static Assembly LoadFromCurrentDirectory(object sender, ResolveEventArgs args)
{
   string name = args.Name;

   bool bCheckVersion = false;
   int idx = name.IndexOf(',');
   if (idx != -1)
   {
      name = name.Substring(0, idx);
      bCheckVersion = true;
   }

   string sCurrentDir = Directory.GetCurrentDirectory();

   if (!name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && !name.EndsWith(".exe"))
   {
      string[] exts = { ".dll", ".exe" };
      foreach( string ext in exts)
      {
         string tryPath = Path.Combine(sCurrentDir, name + ext);
         if (File.Exists(tryPath))
         {
            name = name += ext;
            break;
         }
      }
   }

   string path = Path.Combine(sCurrentDir, name);
   if (!string.IsNullOrEmpty(path) && File.Exists(path))
   {
      Assembly assembly = Assembly.LoadFrom(path);
      if (assembly != null & bCheckVersion)
      {
         if (assembly.FullName != args.Name)
            return null;
      }
      return assembly;
   }
   else
   {
      var reqAsm = args.RequestingAssembly;

      if (reqAsm != null)
      {
         string requestingName = reqAsm.GetName().FullName;
         Console.WriteLine($"Could not resolve {name}, {path}, requested by {requestingName}");
      }
      else
      {
         Console.WriteLine($"Could not resolve {args.Name}, {path}");
      }
   }
   return null;
}

我确信它可以进行优化,添加一个全局目录列表,或者在搜索要加载的文件时使用路径。然而,对于我们的用例来说,工作得很好。当我将它添加到我们的LocBaml代码中时,它解决了us...also的加载问题,而不需要将en\x.resources.dll文件复制到我们的输出目录中。只要我们从输出目录运行程序,LocBaml就会完成解析。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61806978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档