.NET在第三方应用程序中获取所有异常

时间:2015-03-21 06:53:59

标签: c# .net exception-handling

我们通过提供可导入的文件与第三方应用程序集成。该文件包含许多属性(+100),并非所有属性都是强制性的,我们只需要几个。但是,应用程序会在没有堆栈跟踪的情况下继续崩溃(轻轻地,由于大尝试捕获而发出警报)“对象未设置为引用...”。因此,在某些地方,第三方应用程序不会在导致崩溃的空值上验证一些可选参数。搜索什么属性正在大海捞针搜索。

是否有可能以某种方式监视我们没有源代码的应用程序的所有异常,即使它们被捕获了?这样我们就可以得到堆栈跟踪并检查Ilspy导致问题的属性。

第三方应用程序来自一家相对较大的公司。我们不能只与他们的开发人员沟通。

1 个答案:

答案 0 :(得分:3)

你可以尝试:

Assembly otherAssembly = typeof(/* a class of the other assembly */).Assembly;

AppDomain.CurrentDomain.FirstChanceException += (sender, fceea) =>
{
    AppDomain domain = (AppDomain)sender;

    var method = fceea.Exception.TargetSite;
    var declaringType = method.DeclaringType;
    var assembly = declaringType.Assembly;

    if (assembly == otherAssembly)
    {
        // Log the stacktrace of the Exception, or whatever 
        // you want
    }
};

这将让您看到所有Exception(甚至是那些被捕获的)。您必须将此代码放在程序启动的地方(或者甚至在其他地方它可以,但尝试不多次执行它,因为该事件是AppDomain范围的)

请注意,考虑如何处理异常中的堆栈跟踪,可能最好:

if (assembly == otherAssembly)
{
    // Log the stacktrace st of the Exception, or whatever 
    // you want
    string st = new StackTrace(1, true).ToString();
}

以便您可以看到完整的堆栈跟踪。

现在,正如我建议你的那样,你可以将一个小的Console app / Winforms应用程序Add Reference写入另一个exe(是的,你可以添加另一个.exe,如果是这样的话。 NET :-)),并在你的Main做类似的事情:

var otherAssembly = typeof(/* Some type from the other assembly */).Assembly;

// We look all the classes in an assembly for a static Main() that has
// the "right" signature
var main = (from x in otherAssembly.GetTypes()
            from y in x.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
            where y.Name == "Main" && (y.ReturnType == typeof(int) || y.ReturnType == typeof(void)) && y.GetGenericArguments().Length == 0
            let parameters = y.GetParameters()
            where parameters.Length == 0 || (parameters.Length == 1 && parameters[0].ParameterType == typeof(string[]))
            select y).Single();

if (main.GetParameters().Length == 0)
{
    // static Main()
    main.Invoke(null, null);
}
else
{
    // static Main(string[] args)

    // Note that new string[0] is the string[] args!
    // You can pass *your* string[] args :-)
    // Or build one however you want
    main.Invoke(null, new object[] { new string[0] });
}

调用其他Main()。显然,在执行此操作之前,您必须设置FirstChanceException处理程序