MFC、VC++操作excel后,excel程序进程无法正常退出的非暴力处理方法

先说处理方式

1、最low的方式:强制结束进程

cpp 复制代码
//打开进程得到进程句柄
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,Pid);
if(hProcess!=NULL)
{ 	
	//结束进程	
	if (TerminateProcess(hProcess,0))
	{
		printf("结束进程成功\n");
		return 0;
	}
}

这种方式简单粗暴,但会存在进程安全问题,及可能引起数据丢失,慎用!!!!

2、释放顺序问题

与Execl相关的变量在关闭和释放的时候顺序必须正确。比如,要先使用Close(),后使用ReleaseDispatch。

顺序尽量做到先 Save--->Colse--->Release;

在Release时,我们尽量做到由内到外,Rang--->Sheet--->Sheets--->Book--->Books--->App

注:在app退出时,一定要注意顺序,是先Quit退出,再Release,如果先Release,将无法退出,即Quit--->Release。

cpp 复制代码
	//Save--->Colse--->Release
	book.Save();
	book.Close(covOptional, COleVariant("C:\\test\\excel\\test.xlsx"), covOptional);
	books.Close();

	//释放对象(相当重要!)
	//由内到外,Rang--->Sheet--->Sheets--->Book--->Books--->App
	range.ReleaseDispatch();
	
	sheets.ReleaseDispatch();
	sheet.ReleaseDispatch();
	
	book.ReleaseDispatch();
	books.ReleaseDispatch();
	//App一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错
	//Quit--->Release
	app.Quit();
	app.ReleaseDispatch();

3、正确释放资源

当我们操作excel后,如果没有正确释放资源,导致进程被占用,那我们就无法退出进程。

下面我们就来讨论下,如何正确释放资源,使得进程最后正常释放退出。

注:与Execl相关的变量必须全部都要释放ReleaseDispatch。

哪些情况下资源需要释放,那又如何正确释放这些资源

在调用get_Item后,需要释放

1、CWorkbooks对象对get_Item调用后,无法释放

通过CWorkbooks对象调用get_Item接口后,如果不释放,会出现进程无法退出情况,如下使用后,可能会存在进程无法退出问题。

cpp 复制代码
sheets.get_Item(_variant_t(1));

解决方案:

cpp 复制代码
//方案一、先赋值给LPDISPATCH对象,然后通过release释放
LPDISPATCH lpSheets = sheets.get_Item(_variant_t(1));
lpSheets->Release();
//方案二,如果变量被AttachDispatch给其他对象则不需要手动释放,如
lpSheets = sheets.get_Item(_variant_t(1));
sheet.AttachDispatch(lpDisp);
//or
sheet.AttachDispatch(sheets.get_Item(_variant_t(1)));

对于方案一,需要注意的是,据我测试,在新版本office上这个bug应该是已经被微软优化,修复了,如果主动释放的话,会报错。

2、CRange对象对get_Item调用后,无法释放

通过CRange对象调用get_Item接口后,如果不释放,会出现进程无法退出情况,如下使用后,可能会存在进程无法退出问题。

cpp 复制代码
range.get_Item(_variant_t(1));

解决方案:

cpp 复制代码
//方案一、先赋值给VARIANT对象,然后通过VariantClear释放
VARIANT var = range.get_Item(_variant_t(1), _variant_t(1));
VariantClear(&var);
//方案二,如果变量被AttachDispatch给其他对象则不需要手动释放,如
LPDISPATCH lpRang = range.get_Item(_variant_t(1));
range.AttachDispatch(lpDisp);
//or
range.AttachDispatch(range.get_Item(_variant_t(1)));

为什么AttachDispatch后就不需要去手动释放了?

咱们先看AttachDispatch函数就可以知道,根据参数bAutoRelease知道,这个接口内会自动释放。

cpp 复制代码
void AttachDispatch(LPDISPATCH lpDispatch, BOOL bAutoRelease = TRUE);
相关推荐
rainbow_lucky01067 小时前
MFC UI控件CheckBox从专家到小白
mfc·checkbox
R-G-B16 小时前
【27】MFC入门到精通——MFC 修改用户界面登录IP IP Address Control
tcp/ip·ui·mfc·mfc 用户界面登录·mfc ip登录·mfc address登录
愿你天黑有灯下雨有伞16 小时前
Java使用FastExcel实现Excel文件导入
java·excel
爆爆凯16 小时前
Excel 导入导出工具类文档
java·excel
R-G-B19 小时前
【46】MFC入门到精通——MFC显示实时时间,获取系统当前时间GetCurrentTime()、获取本地时间GetLocalTime()
c++·mfc·mfc显示实时时间·mfc获取系统当前时间·getcurrenttime·getlocaltime
凌康ACG1 天前
springboot打包二次压缩Excel导致损坏
spring boot·后端·excel
诸葛大钢铁1 天前
Excel转PDF的三种方法
笔记·职场和发展·pdf·excel
小小薛定谔2 天前
java操作Excel两种方式EasyExcel 和POI
java·python·excel
CodeCraft Studio2 天前
DHTMLX Suite 9.2 重磅发布:支持历史记录、类Excel交互、剪贴板、拖放增强等多项升级
javascript·excel·交互·表格·dhtmlx·grid·网格
R-G-B2 天前
【28】MFC入门到精通——MFC串口 Combobox 控件实现串口号
c++·mfc·mfc串口控件·combobox 控件·mfc串口参数控件实现