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

.NET Fetch all exception in 3rd party app

我们通过提供可以导入的文件与第 3 方应用程序集成。该文件包含许多属性(+100),并非所有属性都是必需的,我们只需要几个。但是,应用程序在 'object not set to a reference ...' 没有堆栈跟踪的情况下不断崩溃(轻轻地,由于大尝试捕获而发出警报)。所以在某些地方,第 3 方应用程序没有验证导致崩溃的空值的一些可选参数。搜什么属性就是大海捞针

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

第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-wide)

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

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

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

现在,按照我的建议,您可以编写一个小型控制台 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 处理程序