Click here to Skip to main content
15,887,676 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
When the active document is part of the OneDrive folder, the return value is a URL, even though the document is stored locally.
What I am looking for, is a solution to get the local path of the active document regardless of it being synced with OneDrive. So instead of getting

"https://d.docs.live.net/ea373ad9f9c16144/myfolder/myfile.docx"

I will get
"c:\users\my username\OneDrive\myfolder\myfile.docx"

What I have tried:

The method I use is

VARIANT result;
VariantInit(&result);

m_hr = OLEMethod(DISPATCH_PROPERTYGET, &result, m_pActiveDocument, (LPOLESTR)L"Path", 0);
Posted
Updated 27-Jun-23 8:53am

1 solution

Here is a quick and dirty solution.

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

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

	if (FAILED(m_hr))
		return nullptr;

	BSTR url = result.bstrVal;

	// Check if the URL contains "https://", indicating it's a OneDrive URL
	if (wcsstr(url, L"https://") != nullptr)
	{
		// Get the current user account name
		wchar_t userName[UNLEN + 1];
		DWORD userNameSize = UNLEN + 1;
		GetUserNameW(userName, &userNameSize);

		// Check if the URL is a subfolder under the root OneDrive folder
		const wchar_t* rootFolder = L"https://d.docs.live.net/";
		const size_t rootFolderLen = wcslen(rootFolder);
		if (wcsstr(url, rootFolder) == url)
		{
			// Find the position of the first slash after the root folder
			const wchar_t* slash = wcschr(url + rootFolderLen, L'/');
			if (slash != nullptr)
			{
				// Find the position of the last slash to determine the folder path
				const wchar_t* lastSlash = wcsrchr(slash, L'/');
				if (lastSlash != nullptr)
				{
					// Extract the folder path and calculate its length
					const wchar_t* folderPath = slash + 1;
					size_t folderPathLen = lastSlash - folderPath;

					// Calculate the required buffer size for the local path
					size_t localPathSize = MAX_PATH + wcslen(userName) + folderPathLen + 11; // 11 for "\\OneDrive\\"

					// Allocate memory for the local path
					wchar_t* localPath = new wchar_t[localPathSize];
					wcscpy(localPath, L"C:\\Users\\");
					wcscat(localPath, userName);
					wcscat(localPath, L"\\OneDrive\\");
					wcsncat(localPath, folderPath, folderPathLen);

					// Replace forward slashes with backslashes in the local path
					wchar_t* backslash = wcschr(localPath, L'/');
					while (backslash != nullptr)
					{
						*backslash = L'\\';
						backslash = wcschr(backslash + 1, L'/');
					}

					// Convert the local path to BSTR
					BSTR resultPath = SysAllocString(localPath);

					// Clean up memory
					delete[] localPath;

					return resultPath;
				}
			}
		}
	}

	return url;
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900