https://www.likecs.com/show-307694293.html
程序异常崩溃前使用此类为进程创建DUMP文件,之后可以使用WinDbg等工具进行分析。
辅助类代码
using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices;namespace Infrastructure {public static class MiniDump{// Taken almost verbatim from http://blog.kalmbach-software.de/2008/12/13/writing-minidumps-in-c/[Flags]public enum Option : uint{// From dbghelp.h:Normal = 0x00000000,WithDataSegs = 0x00000001,WithFullMemory = 0x00000002,WithHandleData = 0x00000004,FilterMemory = 0x00000008,ScanMemory = 0x00000010,WithUnloadedModules = 0x00000020,WithIndirectlyReferencedMemory = 0x00000040,FilterModulePaths = 0x00000080,WithProcessThreadData = 0x00000100,WithPrivateReadWriteMemory = 0x00000200,WithoutOptionalData = 0x00000400,WithFullMemoryInfo = 0x00000800,WithThreadInfo = 0x00001000,WithCodeSegs = 0x00002000,WithoutAuxiliaryState = 0x00004000,WithFullAuxiliaryState = 0x00008000,WithPrivateWriteCopyMemory = 0x00010000,IgnoreInaccessibleMemory = 0x00020000,ValidTypeFlags = 0x0003ffff,}enum ExceptionInfo{None,Present}//typedef struct _MINIDUMP_EXCEPTION_INFORMATION {// DWORD ThreadId;// PEXCEPTION_POINTERS ExceptionPointers;// BOOL ClientPointers;//} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;[StructLayout(LayoutKind.Sequential, Pack = 4)] // Pack=4 is important! So it works also for x64!struct MiniDumpExceptionInformation{public uint ThreadId;public IntPtr ExceptionPointers;[MarshalAs(UnmanagedType.Bool)]public bool ClientPointers;}//BOOL//WINAPI//MiniDumpWriteDump(// __in HANDLE hProcess,// __in DWORD ProcessId,// __in HANDLE hFile,// __in MINIDUMP_TYPE DumpType,// __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,// __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,// __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam// );// Overload requiring MiniDumpExceptionInformation[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, ref MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam);// Overload supporting MiniDumpExceptionInformation == NULL[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam);[DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]static extern uint GetCurrentThreadId();static bool Write(SafeHandle fileHandle, Option options, ExceptionInfo exceptionInfo){Process currentProcess = Process.GetCurrentProcess();IntPtr currentProcessHandle = currentProcess.Handle;uint currentProcessId = (uint)currentProcess.Id;MiniDumpExceptionInformation exp;exp.ThreadId = GetCurrentThreadId();exp.ClientPointers = false;exp.ExceptionPointers = IntPtr.Zero;if (exceptionInfo == ExceptionInfo.Present){exp.ExceptionPointers = Marshal.GetExceptionPointers();}return exp.ExceptionPointers == IntPtr.Zero ? MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint)options, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) : MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint)options, ref exp, IntPtr.Zero, IntPtr.Zero);}static bool Write(SafeHandle fileHandle, Option dumpType){return Write(fileHandle, dumpType, ExceptionInfo.None);}public static Boolean TryDump(String dmpPath, Option dmpType=Option.Normal){var path = Path.Combine(Environment.CurrentDirectory, dmpPath);var dir = Path.GetDirectoryName(path);if (dir != null && !Directory.Exists(dir)){Directory.CreateDirectory(dir);}using (var fs = new FileStream(path, FileMode.Create)){return Write(fs.SafeFileHandle, dmpType);}}} }
提示
对于Windows Form程序,可以利用AppDomain的UnhandledException事件。以下示例:
namespace WindowsFormsApplication1 {static class Program{/// <summary>/// 应用程序的主入口点。/// </summary>[STAThread]static void Main(){AppDomain.CurrentDomain.UnhandledException +=new UnhandledExceptionEventHandler((obj,args)=> MiniDump.TryDump("error.dmp"));Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new Form1());}} }