如何通过OLE自动化获取活动Word文档的完整路径
获取活动Word文档的完整路径(OLE自动化)
你的代码当前直接调用Word.Application对象的属性(DISPID 0x3,对应Name),只能拿到文档文件名,要获取完整路径,需要先拿到ActiveDocument对象,再读取它的FullName属性。
修改步骤及代码示例
1. 先获取ActiveDocument对象
Word.Application的ActiveDocument属性对应当前打开的活动文档,先获取这个对象的Dispatch接口:
// 原代码获取driver之后,添加以下代码 COleDispatchDriver docDriver; HRESULT hr; // 获取ActiveDocument属性(DISPID对应0x1000003) hr = driver.InvokeHelper(0x1000003, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&docDriver.m_lpDispatch, NULL); if (FAILED(hr)) { // 处理错误:比如无打开的活动文档 driver.ReleaseDispatch(); return false; }
2. 读取ActiveDocument的FullName属性
FullName属性会返回文档的完整路径(包含文件名),对应的DISPID是0x7:
CString fullPath; hr = docDriver.InvokeHelper(0x7, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&fullPath, NULL); if (SUCCEEDED(hr)) { // fullPath即为所需的完整路径 } // 释放资源 docDriver.ReleaseDispatch(); driver.ReleaseDispatch();
更可靠的方式:避免硬编码DISPID
硬编码DISPID可能在不同Word版本中存在兼容性问题,推荐使用GetIDsOfNames根据属性名动态获取DISPID:
// 获取ActiveDocument的DISPID LPOLESTR activeDocName = L"ActiveDocument"; DISPID dispidActiveDoc; hr = driver.m_lpDispatch->GetIDsOfNames(IID_NULL, &activeDocName, 1, LOCALE_USER_DEFAULT, &dispidActiveDoc); if (FAILED(hr)) { driver.ReleaseDispatch(); return false; } // 获取ActiveDocument对象 IDispatch* pDocDisp = nullptr; VARIANT varDoc; VariantInit(&varDoc); hr = driver.m_lpDispatch->Invoke(dispidActiveDoc, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, nullptr, &varDoc, nullptr, nullptr); if (FAILED(hr) || varDoc.vt != VT_DISPATCH) { VariantClear(&varDoc); driver.ReleaseDispatch(); return false; } COleDispatchDriver docDriver; docDriver.AttachDispatch(varDoc.pdispVal); VariantClear(&varDoc); // 获取FullName的DISPID LPOLESTR fullName = L"FullName"; DISPID dispidFullName; hr = docDriver.m_lpDispatch->GetIDsOfNames(IID_NULL, &fullName, 1, LOCALE_USER_DEFAULT, &dispidFullName); if (FAILED(hr)) { docDriver.ReleaseDispatch(); driver.ReleaseDispatch(); return false; } // 获取完整路径 CString fullPath; VARIANT varPath; VariantInit(&varPath); hr = docDriver.m_lpDispatch->Invoke(dispidFullName, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, nullptr, &varPath, nullptr, nullptr); if (SUCCEEDED(hr) && varPath.vt == VT_BSTR) { fullPath = varPath.bstrVal; } // 释放所有资源 VariantClear(&varPath); docDriver.ReleaseDispatch(); driver.ReleaseDispatch();
关键说明
- 原代码错误地直接操作Word.Application对象,文档的路径属性属于
ActiveDocument对象 Name属性仅返回文档文件名,FullName属性返回包含路径的完整名称- 使用
GetIDsOfNames动态获取DISPID可提升代码在不同Office版本中的兼容性
内容的提问来源于stack exchange,提问作者secuman
相关产品推荐
相关产品推荐

