zoukankan      html  css  js  c++  java
  • C# CLR20R3 程序终止的几种解决方案

      这是因为.NET Framework 1.0 和 1.1 这两个版本对许多未处理异常(例如,线程池线程中的未处理异常)提供支撑,而 Framework 2.0 版中,公共语言运行库允许线程中的多数未处理异常自然继续。在多数情况下,这意味着未处理异常会导致应用程序终止。

    一、C/S 解决方案(以下任何一种方法)
    1. 在应用程序配置文件中,添加如下内容:

    1 <configuration>
    2   <runtime>
    3     <legacyUnhandledExceptionPolicy enabled="true" />
    4   </runtime> 
    5 </configuration>

    2. 在应用程序配置文件中,添加如下内容:

    1 <configuration>
    2   <startup>
    3     <supportedRuntime version="v1.1.4322"/>
    4   </startup>
    5 </configuration>

    3. 使用Application.ThreadException事件在异常导致程序退出前截获异常。示例如下:

    1 [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
    2 public static void Main(string[] args)
    3 {
    4     Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);
    5     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    6     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    7 
    8     Application.Run(new ErrorHandlerForm());
    9 }

    日志事件

     1 private static void Form1_UIThreadException(object sender, ThreadExceptionEventArgs t)
     2 {
     3     DialogResult result = DialogResult.Cancel;
     4     try
     5     {
     6         result = ShowThreadExceptionDialog("Windows Forms Error", t.Exception);
     7     }
     8     catch
     9     {
    10         try
    11         {
    12             MessageBox.Show("Fatal Windows Forms Error",
    13                 "Fatal Windows Forms Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
    14         }
    15         finally
    16         {
    17             Application.Exit();
    18         }
    19     }
    20 
    21     if (result == DialogResult.Abort)
    22         Application.Exit();
    23 }
    24 
    25 
    26 // 由于 UnhandledException 无法阻止应用程序终止,因而此示例只是在终止前将错误记录在应用程序事件日志中。
    27 private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    28 {
    29     try
    30     {
    31         Exception ex = (Exception)e.ExceptionObject;
    32         string errorMsg = "An application error occurred. Please contact the adminstrator " +
    33             "with the following information:/n/n";
    34 
    35         if (!EventLog.SourceExists("ThreadException"))
    36         {
    37             EventLog.CreateEventSource("ThreadException", "Application");
    38         }
    39 
    40         EventLog myLog = new EventLog();
    41         myLog.Source = "ThreadException";
    42         myLog.WriteEntry(errorMsg + ex.Message + "/n/nStack Trace:/n" + ex.StackTrace);
    43     }
    44     catch (Exception exc)
    45     {
    46         try
    47         {
    48             MessageBox.Show("Fatal Non-UI Error",
    49                 "Fatal Non-UI Error. Could not write the error to the event log. Reason: "
    50                 + exc.Message, MessageBoxButtons.OK, MessageBoxIcon.Stop);
    51         }
    52         finally
    53         {
    54             Application.Exit();
    55         }
    56     }
    57 }
    58 
    59 
    60 private static DialogResult ShowThreadExceptionDialog(string title, Exception e)
    61 {
    62     string errorMsg = "An application error occurred. Please contact the adminstrator " +
    63         "with the following information:/n/n";
    64     errorMsg = errorMsg + e.Message + "/n/nStack Trace:/n" + e.StackTrace;
    65     return MessageBox.Show(errorMsg, title, MessageBoxButtons.AbortRetryIgnore,
    66         MessageBoxIcon.Stop);
    67 }

    二、B/S 解决方案(以下任何一种方法)
    1. 在IE目录(C:/Program Files/Internet Explorer)下建立iexplore.exe.config文件,内容如下:

    1 <?xml version="1.0"?> 
    2 <configuration>
    3   <runtime>
    4     <legacyUnhandledExceptionPolicy enabled="true" />
    5   </runtime> 
    6 </configuration>

    2. 不建议使用此方法,这将导致使用 framework 1.1 以后版本的程序在IE中报错。
    建立同上的配置文件,但内容如下:

    1 <?xml version="1.0"?> 
    2 <configuration>
    3   <startup>
    4     <supportedRuntime version="v1.1.4322"/>
    5   </startup>
    6 </configuration>

    3. 这个比较繁琐,分为三步:
    ⑴. 将下面的代码保存成文件,文件名为UnhandledExceptionModule.cs,路径是C:/Program Files/Microsoft Visual Studio 14/

     1 using System;
     2 using System.Diagnostics;
     3 using System.Globalization;
     4 using System.IO;
     5 using System.Runtime.InteropServices;
     6 using System.Text;
     7 using System.Threading;
     8 using System.Web;
     9  
    10 namespace WebMonitor {
    11     public class UnhandledExceptionModule: IHttpModule {
    12 
    13         static int _unhandledExceptionCount = 0;
    14 
    15         static string _sourceName = null;
    16         static object _initLock = new object();
    17         static bool _initialized = false;
    18 
    19         public void Init(HttpApplication app) {
    20 
    21             // Do this one time for each AppDomain.
    22             if (!_initialized) {
    23                 lock (_initLock) {
    24                     if (!_initialized) { 
    25                         string webenginePath = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "webengine.dll");
    26 
    27                         if (!File.Exists(webenginePath)) {
    28                             throw new Exception(String.Format(CultureInfo.InvariantCulture,
    29                                                               "Failed to locate webengine.dll at '{0}'.  This module requires .NET Framework 2.0.", 
    30                                                               webenginePath));
    31                         }
    32 
    33                         FileVersionInfo ver = FileVersionInfo.GetVersionInfo(webenginePath);
    34                         _sourceName = string.Format(CultureInfo.InvariantCulture, "ASP.NET {0}.{1}.{2}.0",
    35                                                     ver.FileMajorPart, ver.FileMinorPart, ver.FileBuildPart);
    36 
    37                         if (!EventLog.SourceExists(_sourceName)) {
    38                             throw new Exception(String.Format(CultureInfo.InvariantCulture,
    39                                                               "There is no EventLog source named '{0}'. This module requires .NET Framework 2.0.", 
    40                                                               _sourceName));
    41                         }
    42  
    43                         AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
    44  
    45                         _initialized = true;
    46                     }
    47                 }
    48             }
    49         }
    50 
    51         public void Dispose() {
    52         }
    53 
    54         void OnUnhandledException(object o, UnhandledExceptionEventArgs e) {
    55             // Let this occur one time for each AppDomain.
    56             if (Interlocked.Exchange(ref _unhandledExceptionCount, 1) != 0)
    57                 return;
    58 
    59             StringBuilder message = new StringBuilder("/r/n/r/nUnhandledException logged by UnhandledExceptionModule.dll:/r/n/r/nappId=");
    60 
    61             string appId = (string) AppDomain.CurrentDomain.GetData(".appId");
    62             if (appId != null) {
    63                 message.Append(appId);
    64             }
    65             
    66             Exception currentException = null;
    67             for (currentException = (Exception)e.ExceptionObject; currentException != null; currentException = currentException.InnerException) {
    68                 message.AppendFormat("/r/n/r/ntype={0}/r/n/r/nmessage={1}/r/n/r/nstack=/r/n{2}/r/n/r/n",
    69                                      currentException.GetType().FullName, 
    70                                      currentException.Message,
    71                                      currentException.StackTrace);
    72             }          
    73 
    74             EventLog Log = new EventLog();
    75             Log.Source = _sourceName;
    76             Log.WriteEntry(message.ToString(), EventLogEntryType.Error);
    77         }
    78     }
    79 }

    ⑵. 打开Visual Studio 2005的命令提示行窗口 
    输入Type sn.exe -k key.snk后回车
    输入Type csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.cs后回车
    输入gacutil.exe /if UnhandledExceptionModule.dll后回车
    输入ngen install UnhandledExceptionModule.dll后回车 
    输入gacutil /l UnhandledExceptionModule后回车并将显示的”强名称”信息复制下来

    ⑶. 打开ASP.net应用程序的Web.config文件,将下面的XML加到里面。注意:不包括”[]”,①可能是添加到<httpModules></httpModules>之间。
    <add name="UnhandledExceptionModule" type="WebMonitor.UnhandledExceptionModule, [这里换为上面复制的强名称信息]" />

    三、微软并不建议的解决方案
        打开位于 %WINDIR%/Microsoft.NET/Framework/v2.0.50727 目录下的 Aspnet.config 文件,将属性 legacyUnhandledExceptionPolicy 的 enabled 设置为 true

    四、跳出三界外——ActiveX

      ActiveX 的特点决定了不可能去更改每个客户端的设置,采用 B/S 解决方案里的第 3 种方法也不行,至于行不通的原因,我想可能是因为 ActiveX 的子控件产生的异常直接
    被 CLR 截获了,并没有传到最外层的 ActiveX 控件,这只是个人猜测,如果有清楚的朋友,还望指正。
      最终,我也没找到在 ActiveX 情况的解决方法,但这却是我最需要的,无奈之下,重新检查代码,发现了其中的问题:在子线程中创建了控件,又将它添加到了主线程的 UI 上。
      以前遇到这种情况,系统就会报错了,这次居然可以蒙混过关,最搞不懂的是在 framework 2.0 的 C/S 结构下也没有报错,偏偏在 IE(ActiveX) 里挂了。唉,都是宿主惹的祸。

  • 相关阅读:
    IE的hasLayout
    《那些年啊,那些事——一个程序员的奋斗史》——101
    《那些年啊,那些事——一个程序员的奋斗史》——101
    《那些年啊,那些事——一个程序员的奋斗史》——101
    《那些年啊,那些事——一个程序员的奋斗史》——103
    《那些年啊,那些事——一个程序员的奋斗史》——102
    《那些年啊,那些事——一个程序员的奋斗史》——102
    《那些年啊,那些事——一个程序员的奋斗史》——103
    《那些年啊,那些事——一个程序员的奋斗史》——103
    《那些年啊,那些事——一个程序员的奋斗史》——102
  • 原文地址:https://www.cnblogs.com/xuliangxing/p/6839449.html
Copyright © 2011-2022 走看看