[C#] 如何调用Windows系统发送错误API
在Windows XP 系统里面 对于程序的错误调试是用到 Dr.Watson.
可以通过下面的步骤进行配置:
- 点开始,运行Run
- 输入drwtsn32,然后确定。
但是drwatson.exe 只是存在早期版本的windows系统里面。
具体可参考微软的官方解释(http://support.microsoft.com/kb/308538)
——————————————————————————————
对于较新版本的操作系统(Vista、Windows 7、Windows server 2008),微软用到了一个新的技术-Windows Error Reporting(WER)。
WER 我们可以从控制面板的活动中心找到。可以对WER进行关闭和配置。
下面是查看WER的记录。
1.
2.
3.
双击可以查看具体的错误信息。
对于WER微软的官方功能文档可以参考(http://msdn.microsoft.com/en-us/library/windows/desktop/bb513635(v=vs.85).aspx)
下图的运行结果,是WER一个简单的例子,最后将错误结果发送给微软。
View Code
using System; using System.Runtime.InteropServices; namespace WatsonTest { class Program { static bool Failed(int result) { return (result < 0); } private static void Main(string[] args) { var t = AppDomain.CurrentDomain; t.UnhandledException += (s, e) => { var bucket = GetWatsonBuckets(); var zero = IntPtr.Zero; Console.Write(bucket); Console.Read(); }; throw new NullReferenceException(); } private static WatsonBuckets GetWatsonBuckets() { var pParams = new WatsonBuckets(); IClrRuntimeHost host = null; host = Activator.CreateInstance(Type.GetTypeFromCLSID(ClrGuids.ClsIdClrRuntimeHost)) as IClrRuntimeHost; if (host != null) { var clrControl = host.GetCLRControl(); if (clrControl == null) { return pParams; } var clrErrorReportingManager = clrControl.GetCLRManager(ref ClrGuids.IClrErrorReportingManager) as IClrErrorReportingManager; if (clrErrorReportingManager == null) { return pParams; } clrErrorReportingManager.GetBucketParametersForCurrentException(out pParams); } return pParams; } } // BucketParameters Structure to get watson buckets back from CLR //http://msdn.microsoft.com/en-us/library/ms404466(v=VS.100).aspx [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] internal struct WatsonBuckets { internal int fInited; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string pszEventTypeName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param0; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param1; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param2; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param3; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param4; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param5; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param6; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param7; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param8; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xff)] internal string param9; } internal static class ClrGuids { internal static readonly Guid ClsIdClrRuntimeHost = new Guid("90F1A06E-7712-4762-86B5-7A5EBA6BDB02"); internal static Guid IClrErrorReportingManager = new Guid("980D2F1A-BF79-4c08-812A-BB9778928F78"); internal static readonly Guid IClrRuntimeHost = new Guid("90F1A06C-7712-4762-86B5-7A5EBA6BDB02"); } [Guid("90F1A06C-7712-4762-86B5-7A5EBA6BDB02"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IClrRuntimeHost { void Start(); void Stop(); void SetHostControl(IntPtr pHostControl); IClrControl GetCLRControl(); void UnloadAppDomain(int dwAppDomainId, bool fWaitUntilDone); void ExecuteInAppDomain(int dwAppDomainId, IntPtr pCallback, IntPtr cookie); int GetCurrentAppDomainId(); int ExecuteApplication(string pwzAppFullName, int dwManifestPaths, string[] ppwzManifestPaths, int dwActivationData, string[] ppwzActivationData); int ExecuteInDefaultAppDomain(string pwzAssemblyPath, string pwzTypeName, string pwzMethodName, string pwzArgument); } [Guid("9065597E-D1A1-4fb2-B6BA-7E1FCE230F61"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IClrControl { [return: MarshalAs(UnmanagedType.IUnknown)] object GetCLRManager([In] ref Guid riid); void SetAppDomainManagerType(string pwzAppDomainManagerAssembly, string pwzAppDomainManagerType); } // IClrErrorReportingManager to get watson bukets back from CLR //http://msdn.microsoft.com/en-us/library/ms164367(v=VS.100).aspx [Guid("980D2F1A-BF79-4c08-812A-BB9778928F78"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IClrErrorReportingManager { [PreserveSig] int GetBucketParametersForCurrentException(out WatsonBuckets pParams); } internal enum WER_CONSENT { WerConsentAlwaysPrompt = 4, WerConsentApproved = 2, WerConsentDenied = 3, WerConsentMax = 5, WerConsentNotAsked = 1 } internal enum WER_DUMP_TYPE { WerDumpTypeHeapDump = 3, WerDumpTypeMax = 4, WerDumpTypeMicroDump = 1, WerDumpTypeMiniDump = 2 } internal enum WER_REPORT_TYPE { WerReportNonCritical, WerReportCritical, WerReportApplicationCrash, WerReportApplicationHange, WerReportKernel, WerReportInvalid } internal static class Unmanaged { [DllImport("wer.dll", CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int WerReportAddDump(IntPtr hReportHandle, IntPtr hProcess, IntPtr hThread, WER_DUMP_TYPE dumpType, IntPtr pExceptionParam, IntPtr pDumpCustomOptions, int dwFlags); [DllImport("wer.dll", CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int WerReportCreate(string pwzEventType, WER_REPORT_TYPE repType, IntPtr pReportInformation, ref IntPtr phReportHandle); [DllImport("wer.dll", CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int WerReportSetParameter(IntPtr hReportHandle, int dwparamID, string pwzName, string pwzValue); [DllImport("wer.dll", CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int WerReportSubmit(IntPtr hReportHandle, WER_CONSENT consent, int dwFlags, ref IntPtr pSubmitResult); } }