我的任务:在dll或exe文件中查找所有表单(WindowsForm或WPF,无关紧要)并返回该列表。从理论上说是有效的(意思是:如果我有一个带有WPF或WindowsForm的程序集,我的代码会设法获取所有表单,文本框,标签等)。当谈到“真正的”组件时,它会失败。我为每个“自定义”程序集调用GetExportedTypes()时得到FileNotFound异常(找到.NET程序集,没有问题)。我已经使用GetReferencedAssemblies()来加载引用的程序集(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 Hans Passant的提示,但你的意思是“用这样的代码”是什么意思?
好吧我使用了fuslogvw.exe,我对“selectedAssembly”引用的每个dll都有两个例外。 第一个说的是 “绑定从LoadFrom-context开始 在LoadFrom-Context“
中不搜索系统拥有的图像另一个logentry说找不到selectedAssembly引用的dll,它试图从应用程序的基本路径和下面的所有目录下载它...但不是从它的实际位置...所以,关键问题:如何将Load-context更改为LoadFrom?为什么.NET如此顽固?我的意思是程序集在AppDomain中加载,它不应该关心程序集的实际位置。
我将它实现到我现有的类中(删除了static-keyword并将Init方法的主体放入我的方法中),编译它并且它有效。
感谢您的帮助。
答案 0 :(得分:4)
我将它实现到我现有的类中(删除了static-keyword并将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;
}
答案 1 :(得分:2)
我建议使用Reflector查看您可能没有加载的引用。例如,您只加载当前程序集正在查看的引用程序集。您是否逐步通过每个孩子来找到他们引用的组件? FileNotFound错误可能指向您在另一个未加载的程序集中声明的类型的方向。