ActiveX 封装 多文档(采用bcg中的Ribbon模式),程序关闭以后其中dll不能释放,造成进程关闭不了

lis2012 2014-09-30 06:38:24
最近花了几天时间使用将bcg中的Ribbon模式的多文档封装到ocx中,一切功能都很正常,现在出现的问题是程序退出的时候,ocx中的dll资源(加载的所有dll)不能正常释放:
正常的情况下如:
“dlgTest.exe”: 已卸载“F:\VCest\bin\BCGCBPRO1200ud90.dll”
“dlgTest.exe”: 已卸载“C:\Windows\SysWOW64\oleacc.dll”
“dlgTest.exe”: 已卸载“C:\Windows\SysWOW64\winmm.dll”
“dlgTest.exe”: 已卸载“C:\Windows\SysWOW64\odbc32.dll”
“dlgTest.exe”: 已卸载“C:\Windows\SysWOW64\comdlg32.dll”
“dlgTest.exe”: 已卸载“C:\Windows\SysWOW64\odbcint.dll”

现在的情况是:
Info: AfxDllCanUnloadNow returning S_OK
BCGCBPRO.DLL Terminating!
理论上 通过AfxDllCanUnloadNow 来卸载相关的dll

跟踪发现 在ocx的app中:
ExitInstance()函数 COleControlModule::ExitInstance()执行时会释放dll资源,

// terminate OLE last
_AFX_THREAD_STATE* pState = AfxGetThreadState();
// -1 is special case, so need to compare against TRUE
if (pState->m_bNeedTerm == TRUE)
{
CoFreeUnusedLibraries(); //这句执行异常(正常情况下会卸载所有dll资源), 直接跳回ExitInstance()函数重新执行
::OleUninitialize();
pState->m_bNeedTerm = FALSE;
}

不知道各位有没有人遇到过这种情况,或者相关的解决方法;
下边是封装后的ocx在对话框中的效果:
...全文
596 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
tysoft_rds 2015-10-21
  • 打赏
  • 举报
回复
遇到同样需求,想把一个多文档程序框架封装成OCX,求指教! 272430639@qq.com
冰点青蛙 2015-06-05
  • 打赏
  • 举报
回复
搞定了,修改app这段代码修改成这样:
	
      :: OleInitialize (NULL);      
	//// 初始化 OLE 库
	//if (!AfxOleInit())
	//{
	//	AfxMessageBox(IDP_OLE_INIT_FAILED);
	//	return FALSE;
	//}
冰点青蛙 2015-06-05
  • 打赏
  • 举报
回复
引用 12 楼 goodnew 的回复:
遇到同样的问题,有人知道咋搞定的不?
http://www.programdevelop.com/3667754/ 这个不知道是不是解决方法,看懂E文的解释一下
冰点青蛙 2015-06-05
  • 打赏
  • 举报
回复
遇到同样的问题,有人知道咋搞定的不?
SmallSmile 2015-04-02
  • 打赏
  • 举报
回复
APP的InitInstance() 里添加GDI+的初始化可解决,原因是CImage类只有Load及save时才会初始化GDI+,但销毁时确做了对GDI+的销毁。由于没有初始化GDI+,所以销毁时会卡住。 BOOL bInit = COleControlModule::InitInstance(); if (bInit) { // TODO: 在此添加您自己的模块初始化代码。 ULONG_PTR m_dwToken; Gdiplus::GdiplusStartupInput input; Gdiplus::GdiplusStartupOutput output; Gdiplus::Status status = Gdiplus::GdiplusStartup( &m_dwToken, &input, &output ); }
SmallSmile 2015-04-02
  • 打赏
  • 举报
回复
卡死在 inline void CImage::CInitGDIPlus::ReleaseGDIPlus() throw() { EnterCriticalSection(&m_sect); if( m_dwToken != 0 ) { Gdiplus::GdiplusShutdown( m_dwToken ); } m_dwToken = 0; LeaveCriticalSection(&m_sect); } Gdiplus::GdiplusShutdown( m_dwToken ); 死在这里 是gdi+的问题,可参见 http://support.microsoft.com/zh-cn/kb/322909#appliesto 不知怎么解决,我也遇到同样问题。
zhou_zlun 2014-11-22
  • 打赏
  • 举报
回复
邮箱 zzlzzz@163.com ,感谢!
zhou_zlun 2014-11-22
  • 打赏
  • 举报
回复
搞定了,如何实现的多文档封装到ActiveX 中的的。能指点一下吗?
阿呆_ 2014-10-05
  • 打赏
  • 举报
回复
引用 6 楼 lis2012 的回复:
[quote=引用 5 楼 Idle_ 的回复:] [quote=引用 4 楼 lis2012 的回复:] [quote=引用 2 楼 Idle_ 的回复:] 大杀器:退出前手工调用TerminateProcess(INVALID_HANDLE_VALUE,0);杀掉自己。因为你的问题很像ExitProcess时某个dll的PROCESS_DETATCH代码造成了死锁,那么反正进程已经要退出了,只要没有分配进程间共享的objects,干嘛还要给dll们执行释放代码造成死锁的机会?反正进程分配的objects会由系统自动回收。
如果最后没有解决办法可以考虑一下,现在主要是要找到问题,这里面可能有些复杂默认的ocx不支持多文档,现在人为改动中间涉及到的资源释放问题[/quote] 真的有必要调用CoFreeUnusedLibraries()吗? -- This function is provided for compatibility with 16-bit Windows. 直接::OleUninitialize();足够了。 有时候就是多做多错。[/quote] 这个函数不是我主动调用的,而是释放的时候系统会自动来调用,现在这个函数调用出现异常(直接跳回ExitInstance()),造成所有的dll未能释放,导致程序不能完全关闭(界面没有了,进程还存在)[/quote] 没可能在你的ExitInstance()中用try...catch把它包起来吗?
lis2012 2014-10-04
  • 打赏
  • 举报
回复
引用 5 楼 Idle_ 的回复:
[quote=引用 4 楼 lis2012 的回复:] [quote=引用 2 楼 Idle_ 的回复:] 大杀器:退出前手工调用TerminateProcess(INVALID_HANDLE_VALUE,0);杀掉自己。因为你的问题很像ExitProcess时某个dll的PROCESS_DETATCH代码造成了死锁,那么反正进程已经要退出了,只要没有分配进程间共享的objects,干嘛还要给dll们执行释放代码造成死锁的机会?反正进程分配的objects会由系统自动回收。
如果最后没有解决办法可以考虑一下,现在主要是要找到问题,这里面可能有些复杂默认的ocx不支持多文档,现在人为改动中间涉及到的资源释放问题[/quote] 真的有必要调用CoFreeUnusedLibraries()吗? -- This function is provided for compatibility with 16-bit Windows. 直接::OleUninitialize();足够了。 有时候就是多做多错。[/quote] 这个函数不是我主动调用的,而是释放的时候系统会自动来调用,现在这个函数调用出现异常(直接跳回ExitInstance()),造成所有的dll未能释放,导致程序不能完全关闭(界面没有了,进程还存在)
阿呆_ 2014-10-03
  • 打赏
  • 举报
回复
引用 4 楼 lis2012 的回复:
[quote=引用 2 楼 Idle_ 的回复:] 大杀器:退出前手工调用TerminateProcess(INVALID_HANDLE_VALUE,0);杀掉自己。因为你的问题很像ExitProcess时某个dll的PROCESS_DETATCH代码造成了死锁,那么反正进程已经要退出了,只要没有分配进程间共享的objects,干嘛还要给dll们执行释放代码造成死锁的机会?反正进程分配的objects会由系统自动回收。
如果最后没有解决办法可以考虑一下,现在主要是要找到问题,这里面可能有些复杂默认的ocx不支持多文档,现在人为改动中间涉及到的资源释放问题[/quote] 真的有必要调用CoFreeUnusedLibraries()吗? -- This function is provided for compatibility with 16-bit Windows. 直接::OleUninitialize();足够了。 有时候就是多做多错。
lis2012 2014-10-03
  • 打赏
  • 举报
回复
引用 2 楼 Idle_ 的回复:
大杀器:退出前手工调用TerminateProcess(INVALID_HANDLE_VALUE,0);杀掉自己。因为你的问题很像ExitProcess时某个dll的PROCESS_DETATCH代码造成了死锁,那么反正进程已经要退出了,只要没有分配进程间共享的objects,干嘛还要给dll们执行释放代码造成死锁的机会?反正进程分配的objects会由系统自动回收。
如果最后没有解决办法可以考虑一下,现在主要是要找到问题,这里面可能有些复杂默认的ocx不支持多文档,现在人为改动中间涉及到的资源释放问题
lis2012 2014-10-03
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
ReleaseDispatch CoUninitialize FreeLibrary
这个我知道,我测试使用其他插件没有问题,使用我的ocx最后就是释放不了
阿呆_ 2014-10-03
  • 打赏
  • 举报
回复
大杀器:退出前手工调用TerminateProcess(INVALID_HANDLE_VALUE,0);杀掉自己。因为你的问题很像ExitProcess时某个dll的PROCESS_DETATCH代码造成了死锁,那么反正进程已经要退出了,只要没有分配进程间共享的objects,干嘛还要给dll们执行释放代码造成死锁的机会?反正进程分配的objects会由系统自动回收。
赵4老师 2014-10-03
  • 打赏
  • 举报
回复
ReleaseDispatch CoUninitialize FreeLibrary

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧