我已使用了应用程序域,其中一个应用程序域有可能发生问题造成堆栈溢出(可能是webbrowser控件引起的),但堆栈溢出会造成整个进程终止,
MSDN说:您无法捕捉堆栈溢出异常,因为异常处理代码可能需要堆栈。当普通应用程序中发生堆栈溢出时,公共语言运行库 (CLR) 会终止进程。承载 CLR 的应用程序可以更改默认行为并指定 CLR 卸载发生异常的应用程序域,但允许进程继续进行。有关更多信息,请参见ICLRPolicyManager 接口和承载公共语言运行库。
我想更改为当某个应用程序域发生问题时,只卸载该应用程序域,如何做?需要自编宿主程序吗?
我现在的程序编译为exe程序?

解决方案 »

  1.   

    哦。贴个例子看看,还没实际的用过多appdomain的情况。不是有事件么,UnhandledException
      

  2.   

    当普通应用程序中发生堆栈溢出时,公共语言运行库 (CLR) 会终止进程。
      

  3.   

    CLR 寄宿的 api 真是一变再变啊,
    每个版本的 CLR 出来, 
    都要 deprecate 掉上一个版本的,
    不过并不妨碍继续使用早先版本的,CLR寄宿在 jeffery ritcher 的框架设计和  
    Steven Pratschner

    Customizing the Microsoft® .NET Framework Common Language Runtime
    有些涉及,后者算是这方面最深入的一本了,
    其他的都是只触及皮毛.要真做一个强大的, 定制能力强的 CLR 宿主是不容易的,
    简单的加载 clr , 并执行一个托管程序集是可以的.你的问题不用走到那个方向去的.
      

  4.   

    有这方面的例子吗,我从codeproject上下了一个执行.net dll的例子,但不知执行exe的如何做,而且那个例子是2001年的,不知是否有新的例子吗。
      

  5.   

    在寄宿层次 dll, exe 区分不明显了胡乱测试时搞的, 2.0的api#include "assert.h"
    #include <mscoree.h>
    #import <mscorlib.tlb> raw_interfaces_only rename("ReportEvent","ReportEventManaged") //high_property_prefixes("_get","_put","_putref")#import <C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.tlb> raw_interfaces_only
    using namespace mscorlib;int main()
    {
      HRESULT hr;
      wchar_t buffer[60];
      ICLRRuntimeHost *pHost = NULL;
      ::MessageBoxW(0, L"begin", L"begin", 0);
      hr = CorBindToRuntimeEx(L"v4.0.30319", L"wks",0//v2.0.50727",L"wks",0 //STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN | STARTUP_CONCURRENT_GC
            ,CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (void **)&pHost);
    //  hr = CorBindToRuntimeEx(L"v2.0.50727",L"wks",0 //STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN | STARTUP_CONCURRENT_GC
    //        ,CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void **)&pCorHost);
        
      if (SUCCEEDED(hr))
      {
        ::MessageBoxW(0, L"binded", L"yes", 0);
      }
      else
      {
        ::MessageBoxW(0, L"no bind", L"no", 0);
        return -1;
      }
      
      DWORD domainId;
      hr = pHost->GetCurrentAppDomainId(&domainId);
      _itow(domainId, buffer, 10);
      ::MessageBoxW(0, buffer, L"yes", 0);
      
      // (This is where you could get CLR managers)
      ICLRControl *pCLRControl;
      hr = pHost->GetCLRControl(&pCLRControl);
      assert(SUCCEEDED(hr));
      
      // must get this stuff before the CLR is started
      ICLRGCManager *pCLRGCManager;
      hr = pCLRControl->GetCLRManager(IID_ICLRGCManager,  (VOID **)&pCLRGCManager);
      //wprintf(L"\n%d\n",hr);
      assert(SUCCEEDED(hr));//  ICLRAssemblyIdentityManager* pCLRAssemblyIdentityManager;
    //  hr = pCLRControl->GetCLRManager(IID_ICLRAssemblyIdentityManager, (VOID **)&pCLRAssemblyIdentityManager);
    //  assert(SUCCEEDED(hr));
      //ClrCreateManagedInstance
      
      hr = pHost->Start();
      if (SUCCEEDED(hr))
        ::MessageBoxW(0, L"started", L"yes", 0);
      else
        ::MessageBoxW(0, L"no", L"no", 0);
      DWORD retVal;
    //  hr = pHost->ExecuteInDefaultAppDomain(L"D:\\testDll.dll", 
    //                                        L"testDll.Class1",
    //                                        L"showBox",
    //                                        L"hello world!",
    //                                        &retVal);
    //
    //  if (SUCCEEDED(hr))
    //    ::MessageBoxW(0, L"yew", L"yes", 0);
    //  else
    //    ::MessageBoxW(0, L"no", L"no", 0);  pHost->Stop();  exit(0);
    }
      

  6.   

    非常感谢Dobzhansky,我试了一下你给的代码,似乎启动CLR成功了,但我仍然没有成功装载我的程序,返回值不成功是一串数字:-2146233069,我不明白是什么意思。另外,似乎GetCurrentAppDomainId也不成功,返回值是E_UNEXPECTED。能帮我找找问题吗?