【转】CLR20R3 程序终止的几种解决方案

    xiaoxiao2025-07-08  5

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

     

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

     

    2. 在应用程序配置文件中,添加如下内容: <configuration>   <startup>     <supportedRuntime version="v1.1.4322"/>   </startup> </configuration>

     

    3. 使用Application.ThreadException事件在异常导致程序退出前截获异常。示例如下: [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)] public static void Main(string[] args) {     Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Application.Run(new ErrorHandlerForm()); }

     

    // 在主线程中产生异常 private void button1_Click(object sender, System.EventArgs e) {     throw new ArgumentException("The parameter was invalid"); }

     

    // 创建产生异常的线程 private void button2_Click(object sender, System.EventArgs e) {     ThreadStart newThreadStart = new ThreadStart(newThread_Execute);     newThread = new Thread(newThreadStart);     newThread.Start(); }

     

    // 产生异常的方法 void newThread_Execute() {     throw new Exception("The method or operation is not implemented."); }

     

    private static void Form1_UIThreadException(object sender, ThreadExceptionEventArgs t) {     DialogResult result = DialogResult.Cancel;     try     {         result = ShowThreadExceptionDialog("Windows Forms Error", t.Exception);     }     catch     {         try         {             MessageBox.Show("Fatal Windows Forms Error",                 "Fatal Windows Forms Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);         }         finally         {             Application.Exit();         }     }

        if (result == DialogResult.Abort)         Application.Exit(); }

     

    // 由于 UnhandledException 无法阻止应用程序终止,因而此示例只是在终止前将错误记录在应用程序事件日志中。 private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {     try     {         Exception ex = (Exception)e.ExceptionObject;         string errorMsg = "An application error occurred. Please contact the adminstrator " +             "with the following information:/n/n";

            if (!EventLog.SourceExists("ThreadException"))         {             EventLog.CreateEventSource("ThreadException", "Application");         }

            EventLog myLog = new EventLog();         myLog.Source = "ThreadException";         myLog.WriteEntry(errorMsg + ex.Message + "/n/nStack Trace:/n" + ex.StackTrace);     }     catch (Exception exc)     {         try         {             MessageBox.Show("Fatal Non-UI Error",                 "Fatal Non-UI Error. Could not write the error to the event log. Reason: "                 + exc.Message, MessageBoxButtons.OK, MessageBoxIcon.Stop);         }         finally         {             Application.Exit();         }     } }

     

    private static DialogResult ShowThreadExceptionDialog(string title, Exception e) {     string errorMsg = "An application error occurred. Please contact the adminstrator " +         "with the following information:/n/n";     errorMsg = errorMsg + e.Message + "/n/nStack Trace:/n" + e.StackTrace;     return MessageBox.Show(errorMsg, title, MessageBoxButtons.AbortRetryIgnore,         MessageBoxIcon.Stop); }

     

    二、B/S 解决方案(以下任何一种方法) 1. 在IE目录(C:/Program Files/Internet Explorer)下建立iexplore.exe.config文件,内容如下: <?xml version="1.0"?>  <configuration>   <runtime>     <legacyUnhandledExceptionPolicy enabled="true" />   </runtime>  </configuration>

     

    2. 不建议使用此方法,这将导致使用 framework 1.1 以后版本的程序在IE中报错。 建立同上的配置文件,但内容如下: <?xml version="1.0"?>  <configuration>   <startup>     <supportedRuntime version="v1.1.4322"/>   </startup> </configuration>

     

    3. 这个比较繁琐,分为三步: ⑴. 将下面的代码保存成文件,文件名为UnhandledExceptionModule.cs,路径是C:/Program Files/Microsoft Visual Studio 8/VC/ using System; using System.Diagnostics; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Web;   namespace WebMonitor {     public class UnhandledExceptionModule: IHttpModule {

            static int _unhandledExceptionCount = 0;

            static string _sourceName = null;         static object _initLock = new object();         static bool _initialized = false;

            public void Init(HttpApplication app) {

                // Do this one time for each AppDomain.             if (!_initialized) {                 lock (_initLock) {                     if (!_initialized) {                          string webenginePath = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "webengine.dll");

                            if (!File.Exists(webenginePath)) {                             throw new Exception(String.Format(CultureInfo.InvariantCulture,                                                               "Failed to locate webengine.dll at '{0}'.  This module requires .NET Framework 2.0.",                                                                webenginePath));                         }

                            FileVersionInfo ver = FileVersionInfo.GetVersionInfo(webenginePath);                         _sourceName = string.Format(CultureInfo.InvariantCulture, "ASP.NET {0}.{1}.{2}.0",                                                     ver.FileMajorPart, ver.FileMinorPart, ver.FileBuildPart);

                            if (!EventLog.SourceExists(_sourceName)) {                             throw new Exception(String.Format(CultureInfo.InvariantCulture,                                                               "There is no EventLog source named '{0}'. This module requires .NET Framework 2.0.",                                                                _sourceName));                         }                           AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);                           _initialized = true;                     }                 }             }         }

            public void Dispose() {         }

            void OnUnhandledException(object o, UnhandledExceptionEventArgs e) {             // Let this occur one time for each AppDomain.             if (Interlocked.Exchange(ref _unhandledExceptionCount, 1) != 0)                 return;

                StringBuilder message = new StringBuilder("/r/n/r/nUnhandledException logged by UnhandledExceptionModule.dll:/r/n/r/nappId=");

                string appId = (string) AppDomain.CurrentDomain.GetData(".appId");             if (appId != null) {                 message.Append(appId);             }                          Exception currentException = null;             for (currentException = (Exception)e.ExceptionObject; currentException != null; currentException = currentException.InnerException) {                 message.AppendFormat("/r/n/r/ntype={0}/r/n/r/nmessage={1}/r/n/r/nstack=/r/n{2}/r/n/r/n",                                      currentException.GetType().FullName,                                       currentException.Message,                                      currentException.StackTrace);             }          

                EventLog Log = new EventLog();             Log.Source = _sourceName;             Log.WriteEntry(message.ToString(), EventLogEntryType.Error);         }     } }

     

    ⑵. 打开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) 里挂了。唉,都是宿主惹的祸。

    http://blog.csdn.net/fxfeixue/article/details/4466899

    原文:

    转载请注明原文地址: https://ju.6miu.com/read-1300473.html
    最新回复(0)