0

I've succeeded in obtaining the file name of the currently active word document using Ole automation. By the way, how do I get the full file path for this document?

I only get the name of the document currently open in fileName from the code below, but I want to know the full file path. What should I do?

CLSID clsid;
IDispatch* wordApp = NULL;
COleDispatchDriver driver;

CoInitialize(NULL);
HRESULT m_hr = CLSIDFromProgID(L"Word.Application", &clsid);
if (FAILED(m_hr))
{
    return false;
}

IUnknown* pUnk;
HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
if (FAILED(hr))
{
    return false;
}

IDispatch* pDisp;
hr = pUnk->QueryInterface(IID_IDispatch, (void**)&pDisp);
if (FAILED(hr))
{
    return false;
}
pUnk->Release();

driver.AttachDispatch(pDisp);
if (driver.m_lpDispatch == NULL)
{
    driver.CreateDispatch(clsid);
}

CString fileName;
driver.InvokeHelper(0x3, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&fileName, NULL);
secuman
  • 539
  • 4
  • 12
  • How can I do this with Excel and Powerpoint? – secuman May 05 '23 at 03:24
  • Where did you get the info that `0x3` is the `dwDispID` (parameter of `InvokeHelper`) for the file name ? I assume it is application specific anyway, but the same source might have listed some other values as well. – wohlstad May 05 '23 at 03:56
  • I get it from MSWORD.OLB in Office 2019's installed folder. – secuman May 05 '23 at 04:10
  • And there are no other relevant values there ? BTW - isn't is a binary file ? How did you determine `0x3` is a relevant value ? – wohlstad May 05 '23 at 04:12

1 Answers1

0

I found the following function to work

OLECHAR* GetActiveDocPath()
{
    VARIANT result;
    VariantInit(&result);

    m_hr = OLEMethod(DISPATCH_PROPERTYGET, &result, m_pActiveDocument, (LPOLESTR)L"Path", 0);

    if (FAILED(m_hr))
        return nullptr;

    BSTR docPath = result.bstrVal;

    // Check if the path is a local file path
    if (docPath)
    {
        wchar_t fullPath[MAX_PATH];
        DWORD dwAttrib = GetFileAttributes(docPath);

        // Check if the file exists and is not a directory
        if (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY))
        {
            // Convert the path to a full local path
            DWORD dwSize = GetFullPathName(docPath, MAX_PATH, fullPath, nullptr);

            // Check if the conversion succeeded
            if (dwSize > 0 && dwSize < MAX_PATH)
            {
                // Convert the full path to BSTR
                BSTR resultPath = SysAllocString(fullPath);

                return resultPath;
            }
        }
    }

    return docPath;
}

I use it as part of my own class, so you will have to define

IDispatch *m_pActiveDocument;
Michael Haephrati
  • 3,660
  • 1
  • 33
  • 56