WPF 程序启动崩溃:如何调试?

发布于 2024-12-11 03:17:13 字数 732 浏览 0 评论 0原文

我有一个 WPF 程序,在开发 PC 和客户端 PC 1 上运行良好。但在客户端 PC 2 上,它在启动时立即崩溃,并显示“向 Microsoft 发送报告”窗口。我希望得到一些关于如何追踪错误的建议。这是我尝试过的:

  1. 在我的主窗口类中插入了 try-catch:

    公共MainWindow()
    {
      尝试
      {
         MessageBox.Show("InitComp() 之前");
         初始化组件();
         MessageBox.Show("Sub1() 之前");
         子程序1();
         MessageBox.Show("Sub2() 之前");
         子程序2();
         ... ETC ...
      }
      catch(异常前)
      { ...此处 MessageBox 显示错误的代码 ... }
    }
    

这个想法是尝试隔离启动序列的哪一部分正在崩溃,但是第一条调试消息“Before InitComp()”甚至没有显示。所以看起来应用程序甚至在启动我的代码之前就崩溃了。

  1. 一种可能性是在客户端 PC 2 中安装整个 VS2008,加载源代码并使用 IDE 调试器来跟踪问题。这可能是发现问题最有效的方法。但我不想这样做,因为 a) 客户端 PC 2 不属于我,b) 它无法扩展:我必须对客户端 PC 3/4/5/... 做同样的事情,c) 它违反了我的要求公司的 VS2008 许可证。

我应该如何调试这个问题?

I have a WPF program that runs fine on the development PC and on the client PC 1. But on client PC 2, it crashes immediately on startup with the Send Report to Microsoft window. I would appreciate some advice on how to trace what is wrong. Here's what I have tried:

  1. Inserted try-catch in my main window class:

    public MainWindow()
    {
      try
      {
         MessageBox.Show("Before InitComp()");
         InitializeComponent();
         MessageBox.Show("Before Sub1()");
         Subroutine1();
         MessageBox.Show("Before Sub2()");
         Subroutine2();
         ... etc ...
      }
      catch (Exception ex)
      {  ... code for MessageBox display error here ... }
    }
    

The idea is to try to isolate which part of the startup sequence is crashing, but the first debug message "Before InitComp()" does not even show up. So it seems the app is crashing even before starting my code.

  1. One possibility is to install the entire VS2008 in the client PC 2, load in the source and use the IDE Debugger to trace the problem. This is likely the most effective in finding the problem. But I do not want to do this because a) the client PC 2 does not belong to me, b) it does not scale: I must do likewise for client PC 3/4/5/... and c) it violates my firm's VS2008 license.

How should I go about debugging this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一梦浮鱼 2024-12-18 03:17:13

在您的 App.xaml 标头中,添加:

<Application DispatcherUnhandledException="App_DispatcherUnhandledException" />

在您的 App.xaml.cs 中,添加如下内容:

    void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs args)
    {
        log.Fatal("An unexpected application exception occurred", args.Exception);

        MessageBox.Show("An unexpected exception has occurred. Shutting down the application. Please check the log file for more details.");

        // Prevent default unhandled exception processing
        args.Handled = true;

        Environment.Exit(0);
    }

In your App.xaml header, add:

<Application DispatcherUnhandledException="App_DispatcherUnhandledException" />

and in your App.xaml.cs, add something like:

    void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs args)
    {
        log.Fatal("An unexpected application exception occurred", args.Exception);

        MessageBox.Show("An unexpected exception has occurred. Shutting down the application. Please check the log file for more details.");

        // Prevent default unhandled exception processing
        args.Handled = true;

        Environment.Exit(0);
    }
请帮我爱他 2024-12-18 03:17:13

老派方法:像这样的严重崩溃可能会通过 Windows 中的事件查看器看到。你检查过那里了吗?很多时候,这会告诉我答案,而不会带来任何额外的麻烦。

Old school approach: A hard crash like that is probably bubbling out to something you can see via Event Viewer in Windows. Have you checked there yet? A lot of times this tells me the answer without any extra trouble.

有深☉意 2024-12-18 03:17:13

下载ProcDump。运行 procdump -t -w app.exe ... 或可能 procdump -e -w app.exe ...。也探索其他标志。然后在您最喜欢的调试器 (Visual Studio/WinDbg) 中打开转储文件并查看堆栈跟踪。

Download ProcDump. Run procdump -t -w app.exe ... or possibly procdump -e -w app.exe .... Explore other flags as well. Then open the dump file in your favorite debugger (Visual Studio/WinDbg) and look at stack trace.

红衣飘飘貌似仙 2024-12-18 03:17:13

跟踪/记录非常强大,尤其是当问题发生在客户身上时。您无法始终进行调试,并且转储可能无法提供导致该情况的完整视图。它绝对是对转储或调试的补充。

您还可以打开和关闭它,甚至切换级别。

DebugView 是一个捕获跟踪的好程序:

http://technet.microsoft.com/en- us/sysinternals/bb896647

跟踪:

http://msdn.microsoft.com/en-us/library/3at424ac.aspx

例如,以下是具有可切换级别的示例跟踪类:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.Threading;

namespace Sample
{
    public class Tracer
    {
        //
        // supports holding many trace switches.
        //
        static Dictionary<string, TraceSwitch> s_switches = new Dictionary<string, TraceSwitch>();
        static TraceSwitch s_switch = new TraceSwitch("trace", "Default tracing switch");
        static object s_locker = new object();

        private static TraceSwitch GetSwitch (string category)
        {
            // only pay the lock penalty if it doesn't exist
            if (!s_switches.ContainsKey (category))
            {
                lock (s_locker)
                {
                    if (!s_switches.ContainsKey (category))
                    {
                        TraceSwitch traceSwitch = new TraceSwitch(category,
                                    String.Format("Tracing switch for category '{0}'", category));
                        s_switches.Add (category, traceSwitch);
                    }
                }
            }

            return s_switches[category];
        }

        //
        // No level overloads
        //
        public static void Output(string message)
        {
            WriteLine("None", TraceLevel.Info, message);
        }

        public static void OutputIf(bool condition, string message)
        {
            if (condition)
            {
                Output(message);
            }
        }

        public static void Output(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Output(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void OutputIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Output(format, args);
            }
        }

        //
        // Error level overloads
        //
        public static void Error(string message)
        {
            if (s_switch.TraceError)
            {
                WriteLine(String.Empty, TraceLevel.Error, message);
            }
        }

        public static void Error(string category, string message)
        {
            if (GetSwitch(category).TraceError)
            {
                WriteLine(category, TraceLevel.Error, message);
            }
        }

        public static void ErrorIf(bool condition, string message)
        {
            if (condition)
            {
                Error(message);
            }
        }

        public static void ErrorIf(string category, bool condition, string message)
        {
            if (condition)
            {
                Error(category, message);
            }
        }

        public static void Error(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Error(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void Error(string category, string format, params object[] args)
        {
            Debug.Assert(format != null);
            Error(category, string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void ErrorIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Error(format, args);
            }
        }

        public static void ErrorIf(string category,
                                   bool condition,
                                   string format,
                                   params object[] args)
        {
            if (condition)
            {
                Error(category, format, args);
            }
        }

        //
        // Warning level overloads
        //
        public static void Warning(string message)
        {
            if (s_switch.TraceWarning)
            {
                WriteLine(String.Empty, TraceLevel.Warning, message);
            }
        }

        public static void Warning(string category, string message)
        {
            if (GetSwitch(category).TraceWarning)
            {
                WriteLine(category, TraceLevel.Warning, message);
            }
        }

        public static void WarningIf(bool condition, string message)
        {
            if (condition)
            {
                Warning(message);
            }
        }

        public static void WarningIf(string category, bool condition, string message)
        {
            if (condition)
            {
                Warning(category, message);
            }
        }

        public static void Warning(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Warning(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void Warning(string category, string format, params object[] args)
        {
            Debug.Assert(format != null);
            Warning(category, string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void WarningIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Warning(format, args);
            }
        }

        public static void WarningIf(string category,
                                     bool condition,
                                     string format,
                                     params object[] args)
        {
            if (condition)
            {
                Warning(category, format, args);
            }
        }

        //
        // Info level overloads
        //
        public static void Info(string message)
        {
            if (s_switch.TraceInfo)
            {
                WriteLine(String.Empty, TraceLevel.Info, message);
            }
        }

        public static void Info(string category, string message)
        {
            if (GetSwitch(category).TraceInfo)
            {
                WriteLine(category, TraceLevel.Info, message);
            }
        }

        public static void InfoIf(bool condition, string message)
        {
            if (condition)
            {
                Info(message);
            }
        }

        public static void InfoIf(string category, bool condition, string message)
        {
            if (condition)
            {
                Info(category, message);
            }
        }

        public static void Info(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Info(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void Info(string category, string format, params object[] args)
        {
            Debug.Assert(format != null);
            Info(category, string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void InfoIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Info(format, args);
            }
        }

        public static void InfoIf(string category,
                                  bool condition,
                                  string format,
                                  params object[] args)
        {
            if (condition)
            {
                Info(category, format, args);
            }
        }

        //
        // Verbose level overloads
        //
        public static void Verbose(string message)
        {
            try
            {
                if (s_switch.TraceVerbose)
                {
                    WriteLine(String.Empty, TraceLevel.Verbose, message);
                }
            }catch{}
        }

        public static void Verbose(string category, string message)
        {
            if (GetSwitch(category).TraceVerbose)
            {
                WriteLine(category, TraceLevel.Verbose, message);
            }
        }

        public static void VerboseIf(bool condition, string message)
        {
            if (condition)
            {
                Verbose(message);
            }
        }

        public static void VerboseIf(string category, bool condition, string message)
        {
            if (condition)
            {
                Verbose(category, message);
            }
        }

        public static void Verbose(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Verbose(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void Verbose(string category, string format, params object[] args)
        {
            Debug.Assert(format != null);
            Verbose(category, string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void VerboseIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Verbose(format, args);
            }
        }

        public static void VerboseIf(string category,
                                     bool condition,
                                     string format,
                                     params object[] args)
        {
            if (condition)
            {
                Verbose(category, format, args);
            }
        }

        //
        // Trace Output Format:
        // [category:level]PID|ThreadID|08:16:15.134| message.
        //
        private static void WriteLine(string category,
                                      System.Diagnostics.TraceLevel level,
                                      string message)
        {
            Debug.Assert(message != null);

            string traceLine = string.Format(
                CultureInfo.InvariantCulture,
                "[{0}:{1}]{2}|{3}|{4:HH}:{4:mm}:{4:ss}.{4:fff}|{5}",
                category,
                level.ToString(),
                Process.GetCurrentProcess().Id,
                Thread.CurrentThread.ManagedThreadId,
                DateTime.Now,
                message);

            Trace.WriteLine(traceLine);
        }
    }
}

Tracing/Logging is very powerful especially when the problem is happening with a customer. You can't always debug and a dump may not provide the full view to what led up to that point. It definately compliments a dump or debugging.

You can also turn it on and off and even switch levels.

DebugView is a good program to capture traces:

http://technet.microsoft.com/en-us/sysinternals/bb896647

Tracing:

http://msdn.microsoft.com/en-us/library/3at424ac.aspx

For example, here's a sample trace class with switchable levels:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.Threading;

namespace Sample
{
    public class Tracer
    {
        //
        // supports holding many trace switches.
        //
        static Dictionary<string, TraceSwitch> s_switches = new Dictionary<string, TraceSwitch>();
        static TraceSwitch s_switch = new TraceSwitch("trace", "Default tracing switch");
        static object s_locker = new object();

        private static TraceSwitch GetSwitch (string category)
        {
            // only pay the lock penalty if it doesn't exist
            if (!s_switches.ContainsKey (category))
            {
                lock (s_locker)
                {
                    if (!s_switches.ContainsKey (category))
                    {
                        TraceSwitch traceSwitch = new TraceSwitch(category,
                                    String.Format("Tracing switch for category '{0}'", category));
                        s_switches.Add (category, traceSwitch);
                    }
                }
            }

            return s_switches[category];
        }

        //
        // No level overloads
        //
        public static void Output(string message)
        {
            WriteLine("None", TraceLevel.Info, message);
        }

        public static void OutputIf(bool condition, string message)
        {
            if (condition)
            {
                Output(message);
            }
        }

        public static void Output(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Output(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void OutputIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Output(format, args);
            }
        }

        //
        // Error level overloads
        //
        public static void Error(string message)
        {
            if (s_switch.TraceError)
            {
                WriteLine(String.Empty, TraceLevel.Error, message);
            }
        }

        public static void Error(string category, string message)
        {
            if (GetSwitch(category).TraceError)
            {
                WriteLine(category, TraceLevel.Error, message);
            }
        }

        public static void ErrorIf(bool condition, string message)
        {
            if (condition)
            {
                Error(message);
            }
        }

        public static void ErrorIf(string category, bool condition, string message)
        {
            if (condition)
            {
                Error(category, message);
            }
        }

        public static void Error(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Error(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void Error(string category, string format, params object[] args)
        {
            Debug.Assert(format != null);
            Error(category, string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void ErrorIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Error(format, args);
            }
        }

        public static void ErrorIf(string category,
                                   bool condition,
                                   string format,
                                   params object[] args)
        {
            if (condition)
            {
                Error(category, format, args);
            }
        }

        //
        // Warning level overloads
        //
        public static void Warning(string message)
        {
            if (s_switch.TraceWarning)
            {
                WriteLine(String.Empty, TraceLevel.Warning, message);
            }
        }

        public static void Warning(string category, string message)
        {
            if (GetSwitch(category).TraceWarning)
            {
                WriteLine(category, TraceLevel.Warning, message);
            }
        }

        public static void WarningIf(bool condition, string message)
        {
            if (condition)
            {
                Warning(message);
            }
        }

        public static void WarningIf(string category, bool condition, string message)
        {
            if (condition)
            {
                Warning(category, message);
            }
        }

        public static void Warning(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Warning(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void Warning(string category, string format, params object[] args)
        {
            Debug.Assert(format != null);
            Warning(category, string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void WarningIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Warning(format, args);
            }
        }

        public static void WarningIf(string category,
                                     bool condition,
                                     string format,
                                     params object[] args)
        {
            if (condition)
            {
                Warning(category, format, args);
            }
        }

        //
        // Info level overloads
        //
        public static void Info(string message)
        {
            if (s_switch.TraceInfo)
            {
                WriteLine(String.Empty, TraceLevel.Info, message);
            }
        }

        public static void Info(string category, string message)
        {
            if (GetSwitch(category).TraceInfo)
            {
                WriteLine(category, TraceLevel.Info, message);
            }
        }

        public static void InfoIf(bool condition, string message)
        {
            if (condition)
            {
                Info(message);
            }
        }

        public static void InfoIf(string category, bool condition, string message)
        {
            if (condition)
            {
                Info(category, message);
            }
        }

        public static void Info(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Info(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void Info(string category, string format, params object[] args)
        {
            Debug.Assert(format != null);
            Info(category, string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void InfoIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Info(format, args);
            }
        }

        public static void InfoIf(string category,
                                  bool condition,
                                  string format,
                                  params object[] args)
        {
            if (condition)
            {
                Info(category, format, args);
            }
        }

        //
        // Verbose level overloads
        //
        public static void Verbose(string message)
        {
            try
            {
                if (s_switch.TraceVerbose)
                {
                    WriteLine(String.Empty, TraceLevel.Verbose, message);
                }
            }catch{}
        }

        public static void Verbose(string category, string message)
        {
            if (GetSwitch(category).TraceVerbose)
            {
                WriteLine(category, TraceLevel.Verbose, message);
            }
        }

        public static void VerboseIf(bool condition, string message)
        {
            if (condition)
            {
                Verbose(message);
            }
        }

        public static void VerboseIf(string category, bool condition, string message)
        {
            if (condition)
            {
                Verbose(category, message);
            }
        }

        public static void Verbose(string format, params object[] args)
        {
            Debug.Assert(format != null);
            Verbose(string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void Verbose(string category, string format, params object[] args)
        {
            Debug.Assert(format != null);
            Verbose(category, string.Format(CultureInfo.InvariantCulture, format, args));
        }

        public static void VerboseIf(bool condition, string format, params object[] args)
        {
            if (condition)
            {
                Verbose(format, args);
            }
        }

        public static void VerboseIf(string category,
                                     bool condition,
                                     string format,
                                     params object[] args)
        {
            if (condition)
            {
                Verbose(category, format, args);
            }
        }

        //
        // Trace Output Format:
        // [category:level]PID|ThreadID|08:16:15.134| message.
        //
        private static void WriteLine(string category,
                                      System.Diagnostics.TraceLevel level,
                                      string message)
        {
            Debug.Assert(message != null);

            string traceLine = string.Format(
                CultureInfo.InvariantCulture,
                "[{0}:{1}]{2}|{3}|{4:HH}:{4:mm}:{4:ss}.{4:fff}|{5}",
                category,
                level.ToString(),
                Process.GetCurrentProcess().Id,
                Thread.CurrentThread.ManagedThreadId,
                DateTime.Now,
                message);

            Trace.WriteLine(traceLine);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文