速发国际365的最新网站-百特365平台可靠吗-日博365投注网

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

先说处理方式 1、最low的方式:强制结束进程 //打开进程得到进程句柄 HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,Pid); if(hProcess!=NULL) { //结束进程 if

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

先说处理方式

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)));

//or 更换获取方式

LPDISPATCH lpRang = sheet.get_Range(_variant_t(1), _variant_t(1));

range.AttachDispatch(lpDisp);

range.get_Value2();

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

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

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

← 上一篇: 会籍的解釋
下一篇: 那些年的那个“没有眉毛的大恶人”你还能分得清吗? →

相关推荐

网站系统开发需要掌握的技术有哪些

网站系统开发需要掌握的技术有哪些

大家好,又见面了,我是你们的朋友全栈君。 1、JDBC 技术 在Java Web应用开发中,数据库管理系统(RDBMS)的使用是不可缺少的。JDBC(Java Database Con

【2023年10月】电信99元套餐怎么样?性价比高吗?

【2023年10月】电信99元套餐怎么样?性价比高吗?

电信99元套餐是电信推出的一款主打性价比的套餐,提供300分钟国内通话+20GB全国流量,月租费仅99元。那么,这款套餐到底怎么样?性价比高吗

Windows 中所謂的「睡眠」、「休眠」有什麼區別?

Windows 中所謂的「睡眠」、「休眠」有什麼區別?

為了讓電腦能夠在不使用時節約電力,微軟在 Windows 中提供多種選項,其中包含了睡眠、休眠和比較沒人知道的交互式睡眠。特別對於筆電用戶

11月28日世界杯赛事分析:巴西VS瑞士,葡萄牙VS乌拉圭(内含比分)

11月28日世界杯赛事分析:巴西VS瑞士,葡萄牙VS乌拉圭(内含比分)

世界杯:巴西VS瑞士 巴西阵容残缺较重 巴西效力在热刺的前锋理查利森首轮便是梅开二度帮助球队2-0击败塞尔维亚,此役大概率会继续首发登场

为什么lol越来越卡(揭秘英雄联盟越来越卡的原因及解决方案)

为什么lol越来越卡(揭秘英雄联盟越来越卡的原因及解决方案)

温馨提示:这篇文章已超过42天没有更新,请注意相关的内容是否还可用! 《英雄联盟》(League of Legends,简称LOL)作为一款全球知名的游戏,

猫真的会被打服吗?

猫真的会被打服吗?

怎么正确“打猫” 很多人,都没有正确把握“打猫”这个教育方法,要么打的太重,给猫咪留下心理阴影,以后和你保持一米开外的距离,要么