[C#] 如何调用Windows系统发送错误API

在Windows XP 系统里面 对于程序的错误调试是用到 Dr.Watson.

可以通过下面的步骤进行配置:

  1. 开始,运行Run
  2. 输入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);
    }
}

 

 

 

posted @ 2012-10-17 15:52  NowhereMan  阅读(701)  评论(0编辑  收藏  举报