c++ole-automation

How to get full path of active word document by using Ole automation


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

Solution

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