简单的崩溃报告?

7
我正在考虑在我的应用程序中实现一个简单的崩溃报告系统,该系统将询问用户是否愿意将崩溃日志发送给我们。
我以前从未做过崩溃报告,我习惯于在保存错误到日志文件时使用try/catch。
以下是我的最大疑问:
1. 实现崩溃报告系统的正确方法是什么? 2. 当应用程序崩溃时,如何触发崩溃报告并发送转储数据?
我不确定崩溃报告是否由try/catch与外部应用程序交互并在上述情况发生时触发,或者应该遵循哪种正确的方式。
我没有可用的SQL Server,所以我打算使用一个简单的上传脚本,该应用程序可以使用该脚本来报告转储数据。
请原谅我的无知,希望社区能帮助我更好地理解它。
我正在搜索有关崩溃报告的信息,并看到大多数内容都涉及Crystal Report、预先准备好的库等,但我想先从小处开始,以便在深入了解之前更好地理解它。
4个回答

5

您是否考虑过使用内置的Windows错误报告

您可以使用Winqual网站查看与您的组织相关的特定于驱动程序、应用程序或操作系统的错误。每个错误报告都提供与该存储区相关的详细信息,然后您可以请求相关数据的文件。

查看错误报告:

  1. 建立Winqual帐户。为了保护公司免受冒名顶替的影响,并确保错误报告发送到正确公司的代表,Winqual网站要求您的公司拥有有效的VeriSign ID。

• 与您的法律部门核实;您的公司可能已经拥有VeriSign ID(也称为Authenticode的软件发布者数字ID)。• 在Winqual上查看您的公司是否已经拥有帐户。

  1. 接受Windows错误报告协议。

  2. 登录Winqual网站。

  3. 单击Windows错误报告。

这篇旧文章可能会引起兴趣:WinForms中用于捕获未处理异常的简单类


1
Winqual很酷,但对于托管程序帮助不大,是吗?我记得它主要针对本机代码,而不是托管代码。 - Simon Mourier
关于“内置的Windows错误报告”这看起来很有趣,但它是个人应用程序而不是来自组织/公司,个人使用仍然可能吗? - Prix
关于第二个链接,它似乎就是我目前正在尝试做的事情,我会尝试一下,非常感谢。 - Prix
第二个链接似乎是一个不错的方法,但它总是打开 Windows 报告工具。 - Prix
Simon - WinQual用于托管应用程序。您可以获得至少托管调用堆栈和常见的一部分堆。您只需要使用SOS来挖掘转储文件即可。 - Robert Ellison

4

编写自己的异常处理程序。在您的 program.cs 类中使用以下代码。当异常发生时,它会自动发送邮件。

using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Mail;
using System.Threading; 

namespace ExceptionHandlerTest
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.ThreadException +=
                new ThreadExceptionEventHandler(Application_ThreadException);

            // Your designer generated commands.
        }

        static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) 
        {

            var fromAddress = new MailAddress("your Gmail address", "Your name");
            var toAddress = new MailAddress("email address where you want to receive reports", "Your name");
            const string fromPassword = "your password";
            const string subject = "exception report";
            Exception exception = e.Exception;
            string body = exception.Message + "\n" + exception.Data + "\n" + exception.StackTrace + "\n" + exception.Source;

            var smtp = new SmtpClient
            {
                Host = "smtp.gmail.com",
                Port = 587,
                EnableSsl = true,
                DeliveryMethod = SmtpDeliveryMethod.Network,
                UseDefaultCredentials = false,
                Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
            };
            using (var message = new MailMessage(fromAddress, toAddress)
            {
                Subject = subject,
                Body = body
            })
            {
                //You can also use SendAsync method instead of Send so your application begin invoking instead of waiting for send mail to complete. SendAsync(MailMessage, Object) :- Sends the specified e-mail message to an SMTP server for delivery. This method does not block the calling thread and allows the caller to pass an object to the method that is invoked when the operation completes. 
                smtp.Send(message);
            }
        }
    }
}

您可以通过获取基于此的崩溃报告库来节省时间,网址是:https://crashreporterdotnet.codeplex.com


4
很多事情取决于应用程序和(特别是)用户预计的隐私关注点。
假设这是在用户PC上运行的客户端应用程序,如果这是一个“内部网”内部应用程序,那么当应用程序退出时,将日志文件通过电子邮件发送给您应该很简单。
这可能非常有趣,因为有时您会在用户报告之前修复错误。
或者,如果您担心应用程序可能会崩溃,并且未处理的异常无法正确捕获,您可以:
1. 在启动时编写注册表条目(或虚拟文件条目等),标记“应用程序未正常终止” 2. 在干净退出时,清除注册表条目(或虚拟文件条目等) 3. 在启动时,检查注册表条目(等)是否存在。
如果存在标记,则知道应用程序以不干净的方式崩溃了,因此您可以提示用户使用文本,例如“上次运行此程序时,它似乎没有正常退出。您是否想向我们发送发生的任何问题的日志,以便我们尝试修复任何问题?”

我不想收集用户信息,只希望当程序崩溃时,它会向我发送一份报告,并在此之前询问用户是否要执行此操作。您的第二个观点似乎是目前适合我的一个想法。但是,如果程序因未处理的某个 N 原因而无法为用户启动,我需要崩溃报告来进行调查,这该怎么办? - Prix
Mitch的回答很好,但是Winqual对我不适用,第二个链接也从未起作用。除此之外,这个答案更适合我,因为我没有其他真正回答我的问题,所以我会将其选为我的答案。 - Prix
1
那种方法只能知道应用程序是否崩溃了,对吧?如果我也想发送异常呢?就像Firefox一样。 - Jack

1
尝试使用AppDomain.UnHandledException和/或AppDomain.ThreadException。

我会阅读更多关于它的内容,以了解它是如何工作的。谢谢回复。 - Prix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接