Example #1
0
        /// <summary>
        /// Submits a Dr. Watson (aka Windows Error Reporting / WER) crash report and then terminates the process.
        /// </summary>
        /// <param name="uncaughtException">Unhandled exception causing the crash</param>
        /// <exception cref="System.Runtime.InteropServices.COMException">
        /// Some failure HRESULTs map to well-defined exceptions, while others do not map
        /// to a defined exception. If the HRESULT maps to a defined exception, ThrowExceptionForHR
        /// creates an instance of the exception and throws it. Otherwise, it creates an instance 
        /// of System.Runtime.InteropServices.COMException, initializes the error code field with 
        /// the HRESULT, and throws that exception. When this method is invoked, it attempts to
        /// retrieve extra information regarding the error by using the unmanaged GetErrorInfo
        /// function.
        /// </exception>
        private static void SubmitReport(Exception uncaughtException)
        {
            lock (s_reportCreationLock)
            {
                if (uncaughtException == null)
                {
                    throw new ArgumentNullException("uncaughtException");
                }

                ReportInformation reportInformation = new ReportInformation();
                reportInformation.dwSize = Marshal.SizeOf(reportInformation);
                reportInformation.hProcess = s_hCurrentProcess;
                reportInformation.hwndParent = s_hwndMainWindow;
                reportInformation.wzApplicationName = s_applicationName;
                reportInformation.wzApplicationPath = s_applicationPath;
                reportInformation.wzConsentKey = null; // null = the name specified by the pwzEventType parameter of WerReportCreate.
                reportInformation.wzDescription = null; // we can't provide a description of the problem - this an uncaught = *unexpected* exception
                reportInformation.wzFriendlyEventName = null; // null = the name specified by pwzEventType parameter of WerReportCreate.

                ReportHandle reportHandle;
                HandleHResult(NativeMethods.WerReportCreate(
                    powerShellEventType,
                    ReportType.WerReportCritical,
                    reportInformation,
                    out reportHandle));

                using (reportHandle)
                {
                    SetBucketParameters(reportHandle, uncaughtException);

                    // http://msdn.microsoft.com/en-us/library/bb513622(VS.85).aspx says:
                    //     If the server asks for a mini dump and you specify WerDumpTypeHeapDump for the dumpType parameter, 
                    //     WER will not send the heap dump to the Watson server. However, if the server asks for a heap dump 
                    //     and the dumpType is WerDumpTypeMiniDump, WER will send the mini dump to the server. 
                    //     Thus, it is recommended that you set dumpType to WerDumpTypeMiniDump

                    HandleHResult(NativeMethods.WerReportAddDump(
                        reportHandle,
                        s_hCurrentProcess,
                        IntPtr.Zero, // thread id is only required for *micro* dumps
                        DumpType.MiniDump,
                        IntPtr.Zero, // exception details.
                        IntPtr.Zero, // dumpCustomOptions - if this parameter is NULL, the standard minidump information is collected.
                                     /*DumpFlags.NoHeap_OnQueue*/0)); // can't use NoHeap_OnQueue, because then we probably won't
                                                                      // be able to request full heap dumps via http://watson web UI

                    SubmitResult submitResult = SubmitResult.ReportFailed;
                    SubmitFlags submitFlags =
                        SubmitFlags.HonorRecovery |
                        SubmitFlags.HonorRestart |
                        SubmitFlags.OutOfProcess |
                        SubmitFlags.AddRegisteredData;
                    if (WindowsErrorReporting.s_unattendedServerMode)
                    {
                        submitFlags |= SubmitFlags.Queue;
                    }
                    HandleHResult(NativeMethods.WerReportSubmit(
                        reportHandle,
                        Consent.NotAsked,
                        submitFlags,
                        out submitResult));

                    // At this point we have submitted the Watson report and we want to terminate the process
                    // as quickly and painlessly as possible (and possibly without sending additional Watson reports
                    // via the default .NET or OS handler).  
                    // Alternatives: native TerminateProcess, managed Environment.Exit, managed Environment.FailFast
                    Environment.Exit((int)submitResult);
                }
            }
        }
Example #2
0
 private static void SubmitReport(Exception uncaughtException)
 {
     lock (reportCreationLock)
     {
         ReportInformation information = null;
         ReportHandle handle;
         if (uncaughtException == null)
         {
             throw new ArgumentNullException("uncaughtException");
         }
         information = new ReportInformation {
             dwSize = Marshal.SizeOf(information),
             hProcess = hCurrentProcess,
             hwndParent = hwndMainWindow,
             wzApplicationName = applicationName,
             wzApplicationPath = applicationPath,
             wzConsentKey = null,
             wzDescription = null,
             wzFriendlyEventName = null
         };
         HandleHResult(NativeMethods.WerReportCreate("PowerShell", ReportType.WerReportCritical, information, out handle));
         using (handle)
         {
             SetBucketParameters(handle, uncaughtException);
             HandleHResult(NativeMethods.WerReportAddDump(handle, hCurrentProcess, IntPtr.Zero, DumpType.MiniDump, IntPtr.Zero, IntPtr.Zero, 0));
             SubmitResult reportFailed = SubmitResult.ReportFailed;
             SubmitFlags flags = SubmitFlags.HonorRecovery | SubmitFlags.HonorRestart | SubmitFlags.AddRegisteredData | SubmitFlags.OutOfProcess;
             if (unattendedServerMode)
             {
                 flags |= SubmitFlags.Queue;
             }
             HandleHResult(NativeMethods.WerReportSubmit(handle, Consent.NotAsked, flags, out reportFailed));
             Environment.Exit((int) reportFailed);
         }
     }
 }
        /// <summary>
        /// Sends the error report email using the data stored in Session.
        /// </summary>
        /// <param name="errorReport">The error report.</param>
        /// <remarks>Documented by Dev09, 2009-07-16</remarks>
        private void SendEmail(ErrorReport errorReport)
        {
            try
            {
                MailMessage mail = new MailMessage(ConfigurationManager.AppSettings["ErrorReportDefaultSender"].ToString(),
                    ConfigurationManager.AppSettings["ErrorReportReceiver"].ToString());

                ReportInformation report = new ReportInformation(errorReport.FileName);
                mail.Subject = string.Format("MemoryLifter Version {0} Error Report", report.MLVersion);

                // message body containing the user's message and stack trace
                string separator = ConfigurationManager.AppSettings["EmailSeparator"].ToString();
                string reportDate = String.Format("\t\t<p>Report from {0} at {1}</p>\r\n\r\n", report.Date, report.Time);
                string usermail = String.Format("\t\t<p>User E-Mail:<br />\r\n{0}</p>\r\n\r\n", errorReport.Sender);
                string message = String.Format("\t\t<p>{0}<br />\r\nUser Message:<br />\r\n{1}<br />\r\n{2}</p>\r\n\r\n", separator, separator, errorReport.Message);
                string trace = String.Format("\t\t<p>{0}<br />\r\nStack Trace:<br />\r\n{1}<br />\r\n{2}</p>\r\n", separator, separator, errorReport.StackTrace.Replace(Environment.NewLine, "<br />\r\n"));
                string body = reportDate + usermail + message + trace;

                mail.Body = "<HTML>\r\n\t<HEAD>\r\n\t\t<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=utf-8'>\r\n\t</HEAD>\r\n\t<BODY>\r\n" + body + "\t</BODY>\r\n</HTML>";
                mail.IsBodyHtml = true;
                mail.BodyEncoding = System.Text.Encoding.UTF8;

                //include the users mail address as reply-to
                if (!String.IsNullOrEmpty(errorReport.Sender))
                {
                    //OMICRON spam filter kills the mail if the user address is the From-address
                    mail.Headers["Reply-To"] = errorReport.Sender;
                }

                // write the attachment to a MemoryStream then attach to email
                using (MemoryStream ms = new MemoryStream())
                {
                    foreach (byte[] dataChunk in errorReport.DataChunks)
                        ms.Write(dataChunk, 0, dataChunk.Length);

                    ms.Position = 0; // CRITICAL
                    mail.Attachments.Add(new Attachment(ms, errorReport.FileName, "application/zip"));

                    // send the email through the omicron smtp server
                    SmtpClient smtp = new SmtpClient(ConfigurationManager.AppSettings["MailServer"].ToString());
                    smtp.Send(mail);
                }
            }
            catch (Exception e)
            {
                Log("SendEmail exception: " + e.ToString());

                SmtpFailedRecipientsException smtpexp = e as SmtpFailedRecipientsException;
                if (smtpexp != null)
                {
                    foreach (SmtpFailedRecipientException recipient in smtpexp.InnerExceptions)
                        Log("FailedRecipient: " + recipient.FailedRecipient + " StatusCode: " + recipient.StatusCode.ToString());
                }

                throw;
            }
        }