开发环境
操作系统:windows 10
编译器:Visual Studio 2010、2015、2017、2022
office 2016、2019、2021
wps 2019、2024
问题描述
通过C++操作excel,保存后,excel会自动生成备份文件。
void CExcelDemoDlg::OnBnClickedButton1()
{
CApplication app; //Excel应用程序接口
CWorkbooks books; //工作薄集合
CWorkbook book; //工作薄
CWorksheets sheets; //工作表集合
CWorksheet sheet; //工作表
CRange range; //Excel中针对单元格的操作都应先获取其对应的Range对象
CFont0 font;
CRange cols;
CRange iCell;
LPDISPATCH lpDisp;
COleVariant vResult;
COleVariant covTrue((short)TRUE);
COleVariant covFalse((short)FALSE);
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//初始化
if (!app.CreateDispatch("Excel.Application"))
{
this->MessageBox("无法创建Excel应用!");
return;
}
app.put_Visible(FALSE); //可见
app.put_UserControl(TRUE); //用户可控制
//打开XLS文件
books.AttachDispatch(app.get_Workbooks());
lpDisp = books.Open("C:\\test\\excel\\test.xlsx",
covOptional, covOptional, covOptional, covOptional, covOptional,
covOptional, covOptional, covOptional, covOptional, covOptional,
covOptional, covOptional, covOptional, covOptional);
book.AttachDispatch(lpDisp);
sheets.AttachDispatch(book.get_Worksheets());
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());
sheet.get_Cells();
range.get_Cells();
VARIANT var = range.get_Item(_variant_t(1), _variant_t(1));
VariantClear(&var);
//book.Save();
book.SaveAs(_variant_t("C:\\test\\excel\\test.xlsx"), vtMissing, vtMissing, vtMissing, vtMissing,
_variant_t(FALSE), 0, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing);
book.Close(covOptional, COleVariant("C:\\test\\excel\\test.xlsx"), covOptional);
books.Close();
//释放对象(相当重要!)
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
//App一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错
app.Quit();
app.ReleaseDispatch();
AfxMessageBox("It's test mode2 End!!");
}
问题分析
1、起因是原本是正常的,之前测试人员也遇到过,但当时定位是excel另存为自动备份的原因。
2、我重装系统后,安装了office2016、wps 2019,然后无意间发现我也会自动备份了
于是开始着重分析,同样的安装包,同样的操作系统,重装系统居然就会自动备份了,很奇怪,于是,经过如下分析测试:
1、升级office 2016到office 2019,问题依然存在,再升级到office 2021,问题被解决(说明office版本可能有影响)
2、回退office版本到2016,然后卸载wps 2019,问题解决((说明WPS有影响))
3、在office版本为2016的前提下,升级wps 2019至当前最新版本,问题依然存在
4、在office版本为2016,并安装了WPS的前提下,打开wps安装目录,发现安装目录下有两个dll(wpsapi.dll及wpsapiex.dll)名字看着比较有影响,于是依次删除两个dll,发现wpsapiex.dll是有影响的,删除后,调用app.CreateDispatch("Excel.Application")
会返回错误。
5、这就说明注册表出问题了,于是怀疑安装wps后,也可能很鸡贼的注册了一个名叫“Excel.Application”的注册表,于是准备去注册表搜搜
6、win+R打开运行窗口后,输入regedit,点确定
7、在HKEY_CLASSES_ROOT处右键-查找,在查找目标处输入“Excel.Application”,然后点查找下一个
8、其中分别在HKEY_CLASSES_ROOT和HKEY_CURRENT_USER里都找到一个“Excel.Application”
9、展开Excel.Application,点击CLSID,然后双击右侧内容,弹出窗口后,复制数据
10、在HKEY_CLASSES_ROOT处右键-查找,在查找目标处输入上一步复制的字符“{00024500-0000-0000-C000-000000000046}”,然后点“查找下一个”,在计算机\HKEY_CLASSES_ROOT\CLSID\
下找到如下图所示:
11、展开,然后点击“LocalServer32”,查看右侧内容,正常,无疑问。
12、按F3继续查找下一个,然后在计算机\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\
下也找到一个,展开,然后点击“LocalServer32”,查看右侧内容,发现疑问,居然路径被改成wps的启动路径了!!!!!
解决方案
直接右键-重命名“LocalServer32”:
后面再次操作会自动生成这个文件夹,并且会将值改为默认的excel路径。
备注:这里不能删除这个文件夹,我也没搞清楚,删除后,运行的时候就找不到了,但备份却能自动生成,而且重命名后,后面计算机\HKEY_CURRENT_USER
也会被自动修改,如下图。
总之就一句话:重命名就行,不用搞其他的,免得引起其他风险