C# GetExportedTypes()FileNotFoundException:程序集无法';找不到

C# GetExportedTypes()FileNotFoundException:程序集无法';找不到,c#,filenotfoundexception,C#,Filenotfoundexception,我的任务:找到dll或exe文件中的所有表单(WindowsForm或WPF,无所谓),然后返回该列表。从理论上讲,这是可行的(意思是:如果我有一个带有WPF或WindowsForm的程序集,那么我的代码会设法获取所有表单、文本框、标签等)。当涉及到“真实”程序集时,它会失败。当为每个“自定义”程序集调用GetExportedTypes()时,我会遇到FileNotFound异常(.NET程序集已找到,没有问题)。我已经使用getReferenceAssemblys()加载引用的程序集(Refl

我的任务:找到dll或exe文件中的所有表单(WindowsForm或WPF,无所谓),然后返回该列表。从理论上讲,这是可行的(意思是:如果我有一个带有WPF或WindowsForm的程序集,那么我的代码会设法获取所有表单、文本框、标签等)。当涉及到“真实”程序集时,它会失败。当为每个“自定义”程序集调用GetExportedTypes()时,我会遇到FileNotFound异常(.NET程序集已找到,没有问题)。我已经使用getReferenceAssemblys()加载引用的程序集(Reflection.Assembly.LoadFrom),是的,它确实有效(找到所有程序集并将其加载到AppDomain中),但没有帮助

我检查了版本号(它们匹配),我将可执行文件和程序集复制到一个目录中,其中包含所有引用的程序集,但不起作用

这是我的代码,也许有人知道我(显然)做错了什么:

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();       
}
首先检查引用的dll是否存在于程序集所在的目录中,如果不存在,请检查它是否存在于C:\dll中,如果不存在,请尝试使用GAC。它确实可以工作,而且我没有任何错误,但是一旦我转到GetExportedTypes,它就会失败,在第一个自定义库中出现FileNotFound异常

*编辑1我所说的“真实程序集”是什么意思:我指的是更复杂且引用了非标准的.NET库/程序集的程序集


感谢您对fuslogvw.exe的提示,但您所说的“使用这样的代码”是什么意思


好的,我使用了fuslogvw.exe,并且“selectedAssembly”引用的每个dll都有两个异常。 第一个是这样说的 “绑定在LoadFrom上下文中启动 未在LoadFrom上下文中搜索系统拥有的映像”

另一个日志条目表示无法找到所选程序集引用的dll,它试图从应用程序的基本路径和下面的所有目录下载它…但不是从它的实际位置下载…因此,关键问题:如何将加载上下文更改为LoadFrom?为什么.NET在这个问题上如此顽固?我的意思是程序集加载在AppDomain中,它不应该关心程序集的实际位置



好的,问题解决了。以下是解决方案:

我在我现有的类中实现了它(删除了static关键字,并将Init方法的主体放入我的方法中),编译了它,它就工作了


谢谢你们的帮助。

我建议你们使用Reflector来查看你们可能没有加载的引用。例如,您只加载当前程序集正在查看的引用程序集。您是否也会逐级遍历每个子级以查找其引用的程序集?FileNotFound错误可能是指向在另一个未加载的程序集中声明的类型的方向。

好的,问题已解决。以下是解决方案:

我在我现有的类中实现了它(删除了static关键字,并将Init方法的主体放入我的方法中),编译了它,它就工作了

谢谢你们的帮助

为了防止有一天网站不可用,这里是来自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;
}
静态字典组合;
公共静态void Init()
{
assemblies=新字典();
AppDomain.CurrentDomain.AssemblyLoad+=新的AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);
AppDomain.CurrentDomain.AssemblyResolve+=新的ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
静态程序集CurrentDomain_AssemblyResolve(对象发送方,ResolveEventArgs args args)
{
Assembly=null;
assemblies.TryGetValue(args.Name,out assembly);
返回组件;
} 
静态无效CurrentDomain_AssemblyLoad(对象发送方、AssemblyLoadEventArgs args args)
{
组装=args.LoadedAssembly;
程序集[assembly.FullName]=程序集;
}

您所说的“真实程序集”是什么意思?请使用fuslogvw.exe对此进行故障排除。它向您显示哪些绑定失败,包括依赖程序集的绑定。像这样的代码的常见问题。嗯,谢谢。我将把foreach循环重建为递归循环。但这真的是问题所在吗?我的意思是程序集加载到AppDomain时没有错误,我只对所选程序集调用“GetExportedTypes”,而不是对所有其他程序集调用。对不起,不是这个问题。LoadContext是问题所在;)。