1

我正在开发一些软件,这些软件将为某些 dll 动态构建菜单项,以便我们可以根据用户机器上可用的 dll 动态加载组件。我要加载的任何 dll 都已在 AssemblyInfo.cs 文件中使用程序集属性进行标记,以及我如何确定是否要为该 dll 构建菜单项。到目前为止,这是我的方法:

private void GetReportModules() {
        foreach (string fileName in Directory.GetFiles(Directory.GetCurrentDirectory())) {
            if (Path.GetExtension(fileName) == ".dll" || Path.GetExtension(fileName) == ".exe") {
                System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(fileName);
                object[] attributes = assembly.GetCustomAttributes(typeof(ReportNameAttribute), false);
                if (attributes.Count() > 0) {
                    ReportNameAttribute reportNameAttribute = attributes[0] as ReportNameAttribute;
                    Type type = assembly.GetType(reportNameAttribute.BaseType);
                    MenuItem customReportsMenuItem = new MenuItem();
                    customReportsMenuItem.Header = reportNameAttribute.ReportName;
                    ReportsMenuItem.Items.Add(customReportsMenuItem);
                    customReportsMenuItem.Click += (s, ev) => {
                        var obj = Activator.CreateInstance(type);
                        type.InvokeMember("Show", System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.InvokeMethod, null, obj, null);
                    };
                }
            }
        }
    }

在大多数情况下,它工作正常,我得到了我期望的 dll,并且正在创建我的菜单项。问题是,为了检查属性,我首先需要使用反射加载程序集。当我尝试加载缺少依赖项的其他一些本地 dll 或者他的模块应该包含程序集清单时,它们会引发错误。有没有一种方法可以在我实际加载之前安全地检查是否可以加载程序集?(当我写出来时听起来很愚蠢)。关于我遇到的问题的任何想法或关于如何完成我在这里尝试的更好的建议?感觉有点在我头上。

4

3 回答 3

2

一种方法是使用 try catch 块。如果它抛出一个异常,你不感兴趣......

编辑:

MSDN 清楚地解释了 LoadFrom 可以抛出的异常类型。FileLoadException 在您的情况下看起来很可能。

我确信有代码在捕获后进行。例如日志框架。我不希望我的框架捕获异常并使我的可执行文件停止等,我希望它扼杀异常。我的应用程序不应该仅仅因为一行日志未命中而失败。

于 2012-09-25T18:23:03.407 回答
2

您可以创建一个单独的AppDomain,尝试在那里加载程序集,将结果发回,然后卸载 AppDomain。这样,您就不会使用任何已加载程序集的“垃圾”来更改当前的 AppDomain。

于 2012-09-25T18:59:00.363 回答
1

您可以尝试使用非托管元数据 API (http://msdn.microsoft.com/en-us/library/ms404384.aspx) 或通用编译器基础结构元数据 API (http://ccimetadata.codeplex.com/) 作为替代普通的反射。

于 2012-09-25T19:18:57.657 回答