本文介绍: 1、最low方式强制结束进程这种方式简单粗暴,但会存在进程安全问题,及可能引起数据丢失慎用!!!!2、释放顺序问题与Execl相关变量关闭和释放的时候顺序必须正确比如,要先使用Close(),后使用ReleaseDispatch顺序尽量做到先 Save—>Colse—>Release;在Release时,我们尽量做到由内到外,Rang—>Sheet—>Sheets—>Book—>Books—>App

先说处理方式

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

//打开进程得到进程句柄
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。

	//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接口后,如果不释放,会出现进程无法退出情况,如下使用后,可能会存在进程无法退出问题

sheets.get_Item(_variant_t(1));

解决方案

//方案一、先赋值给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)));

对于方案一,需要注意的是,如果lpSheets变量AttachDispatch给其他变量,那要注意释放位置,否则会导致后续使用报错如下代码中会在range.AttachDispatch(sheet.get_UsedRange());报错原因就是前面释放位置不对。

LPDISPATCH lpSheets = sheets.get_Item(_variant_t(1));
sheet.AttachDispatch(lpSheets);
lpSheets->Release();
range.AttachDispatch(sheet.get_UsedRange());

在这里插入图片描述
那有人就会说了,既然都AttachDispatch了,就不需要再释放了,但实际情况是,在某些使用场景中,无法立马AttachDispatch,这时就需要手动Release了,如需要获取对象后,立马新建一个sheet:

LPDISPATCH lpSheets = sheets.get_Item(_variant_t(1));
sheet = sheets.Add(covOptional, _variant_t(lpSheets), _variant_t(1), covOptional);
//sheet.AttachDispatch(lpSheets);
lpSheets->Release();

range.AttachDispatch(sheet.get_UsedRange());

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

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

range.get_Item(_variant_t(1));

解决方案

//方案一、先赋值给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知道这个接口内会自动释放。

void AttachDispatch(LPDISPATCH lpDispatch, BOOL bAutoRelease = TRUE);

原文地址:https://blog.csdn.net/y601500359/article/details/134648335

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_40350.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注