简体   繁体   English

GetExportedTypes()FileNotFoundException:找不到程序集

[英]GetExportedTypes() FileNotFoundException: Assembly couldn't be found

My task: Find all Forms (WindowsForm or WPF, doesn't matter) in a dll or exe file and return that list. 我的任务:在dll或exe文件中查找所有窗体(WindowsForm或WPF,不要紧),然后返回该列表。 In theory that works (meaning: if I've an assembly with a WPF or WindowsForm my code manages to get all Forms, TextBoxes, Labels etc. ). 从理论上讲,这是可行的(意思是:如果我有一个带有WPF或WindowsForm的程序集,我的代码将设法获取所有Forms,TextBoxes,Label等)。 When it comes to "real" assemblies it fails. 当涉及“真实”装配时,它将失败。 I get FileNotFound exceptions when calling GetExportedTypes() for every "custom" assembly (.NET assemblies are found, no problems there). 当为每个“自定义”程序集调用GetExportedTypes()时,我得到FileNotFound异常(找到了.NET程序集,那里没有问题)。 I already use GetReferencedAssemblies() to load the referenced assemblies (Reflection.Assembly.LoadFrom) and yes it does work (all assemblies are found and loaded into the AppDomain) but it doesn't help. 我已经使用GetReferencedAssemblies()加载引用的程序集(Reflection.Assembly.LoadFrom),是的,它确实可以工作(找到了所有程序集并将其加载到AppDomain中),但是它没有帮助。

I checked the version numbers (they match), I copied my executable and the assembly into one directory with all referenced assemblies, doesn't work. 我检查了版本号(它们是否匹配),将可执行文件和程序集复制到了一个包含所有引用程序集的目录中,但不起作用。

Here is my code, maybe someone figures out what I'm (obviously) doing wrong: 这是我的代码,也许有人发现我(显然)做错了什么:

foreach (AssemblyName reference in selectedAssembly.GetReferencedAssemblies())
{
      if (System.IO.File.Exists(
             System.IO.Path.GetDirectoryName(selectedAssembly.Location) + 
                @"\" + reference.Name + ".dll"))
      {
         System.Reflection.Assembly.LoadFrom(
            System.IO.Path.GetDirectoryName(selectedAssembly.Location) + 
               @"\" + reference.Name + ".dll");
      }
      else if (System.IO.File.Exists(@"C:\dll\" + reference.Name + ".dll"))
      {
         System.Reflection.Assembly.LoadFrom(@"C:\dll\" + reference.Name + ".dll");
      }
      else
      {
         System.Reflection.Assembly.ReflectionOnlyLoad(reference.FullName);
      }

      selectedAssembly.GetExportedTypes();       
}

at first check if the referenced dll exists in the directory where the assembly is, if not check if it exists in C:\\dll and if it's not there try and use the GAC. 首先,请检查引用的dll是否存在于程序集所在的目录中;如果不存在,请检查其是否存在于C:\\ dll中;如果不存在,请尝试使用GAC。 it does work and I've no errors from there but as soon as I come to GetExportedTypes it fails with a FileNotFound exception on the first custom library. 它确实起作用,并且从那里没有任何错误,但是一旦我进入GetExportedTypes,它就会失败,并在第一个自定义库上出现FileNotFound异常。

*edit 1 what do I mean by "real assemblies": I mean assemblies which are more complex and have references to non-standard-.NET libraries/assemblies * edit 1我所说的“真实程序集”是什么意思:我的意思是程序集更加复杂,并且引用了非标准的.NET库/程序集


Thanks for the hint to fuslogvw.exe Hans Passant but what do you mean by "with code like this"? 感谢fuslogvw.exe Hans Passant的提示,但是“使用这样的代码”是什么意思?


okay I used fuslogvw.exe and I get two exceptions for every single dll that is referenced by the "selectedAssembly". 好的,我使用了fuslogvw.exe,对于“ selectedAssembly”所引用的每个dll,我都会得到两个异常。 The first one says something like "The binding starts in LoadFrom-context The image owned by the system isn't searched in LoadFrom-Context" 第一个说类似“绑定从LoadFrom-context开始。在LoadFrom-Context中不搜索系统拥有的图像”

the other logentry says that the dll referenced by the selectedAssembly couldn't be found and it tried to download it from application's base path and all directories below...but not from it's actual location...so, key question: how do I change the Load-context to LoadFrom? 另一个登录项表明找不到selectedAssembly引用的dll,它试图从应用程序的基本路径和下面的所有目录中下载该dll ...但不是从其实际位置下载...因此,关键问题:我该怎么办将加载上下文更改为LoadFrom? And why is .NET so stubborn on this? 为什么.NET如此固执? I mean the assemblies are loaded in the AppDomain, it shouldn't care about the actual location of the assembly. 我的意思是程序集已加载到AppDomain中,它不必关心程序集的实际位置。


okay problem solved. 好的问题解决了。 Here is the solution: http://ayende.com/blog/1376/solving-the-assembly-load-context-problem 解决方案如下: http : //ayende.com/blog/1376/solving-the-assembly-load-context-problem

I implemented that into my existing class (removed the static-keyword and put the body of the Init method into my method), compiled it and it worked. 我在现有的类中实现了这一点(删除了静态关键字,并将Init方法的主体放入了我的方法中),对其进行了编译并开始工作。

Thanks for your help guys. 感谢您的帮助。

okay problem solved. 好的问题解决了。 Here is the solution: http://ayende.com/blog/1376/solving-the-assembly-load-context-problem 解决方案如下: http : //ayende.com/blog/1376/solving-the-assembly-load-context-problem

I implemented that into my existing class (removed the static-keyword and put the body of the Init method into my method), compiled it and it worked. 我在现有的类中实现了这一点(删除了静态关键字,并将Init方法的主体放入了我的方法中),对其进行了编译并开始工作。

Thanks for your help guys. 感谢您的帮助。

just in case the website will someday be unavailable, here is the sourcecode from ayende 以防万一有一天该网站不可用,这是ayende的源代码

static Dictionary<string, Assembly>assemblies;   

public static void Init()
{

    assemblies = new Dictionary<string, Assembly>();

    AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);

    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{

    Assembly assembly = null;

    assemblies.TryGetValue(args.Name, out assembly);

    return assembly;

} 

static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{

    Assembly assembly = args.LoadedAssembly;
    assemblies[assembly.FullName] = assembly;
}

I would recommend using Reflector to see which references you may not have loaded. 我建议使用Reflector来查看您可能尚未加载的参考。 For instance, you are only loading the referenced assemblies that the current assembly is looking at. 例如,您仅加载当前程序集正在查看的引用程序集。 Do you step down through each child to find their referenced assemblies as well? 您是否还下台了每个孩子以查找他们引用的程序集? The FileNotFound error is probably pointing you in the direction of a type that is declared in another assembly that isn't loaded. FileNotFound错误可能使您指向在另一个未加载的程序集中声明的类型的方向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM