How does Directory Opus extract the “Product Version” from .msi files?

How does Directory Opus extract the Product Version out of .msi files? I am trying to help David Carpenter, the creator of the Everything Search Engine, figure out how to enable Everything to extract Product Version numbers.

I noticed that when you look at an .msi file's Properties > Details page, there is not an actual human readable number shown. There is, however, a Revision number, followed by a series of characters, for example, {AEF703DD-B958-4B33-804B-7B0685DD0356} → Is this character string the Product Version, but encoded? Is there an API used to extract the Product Version? Thanks for your help.

MSI files have an internal database, and you can use the msiquery API to query it using SQL. Below is a version of the code we use:

bool GetMsiProperties(LPCWSTR pszFile, std::map<std::wstring, std::wstring>& mapProps)
{
	MSIHANDLE hMsi{};
	if (FAILED(MsiOpenDatabaseW(pszFile, MSIDBOPEN_READONLY, &hMsi)))
		return false;

	bool fGotOne{};
	for (auto& prop : mapProps)
	{
		MSIHANDLE hQuery;
		if (SUCCEEDED(MsiDatabaseOpenView(hMsi,
			(std::wstring(L"Select Value from Property where Property = '") + prop.first + L"'").c_str(), &hQuery)))
		{
			if (SUCCEEDED(MsiViewExecute(hQuery, 0)))
			{
				MSIHANDLE hRecord;
				if (SUCCEEDED(MsiViewFetch(hQuery, &hRecord)))
				{
					wchar_t wchBuf[512]{};
					DWORD dwLen = _countof(wchBuf);
					if (SUCCEEDED(MsiRecordGetString(hRecord, 1, wchBuf, &dwLen)))
					{
						prop.second = wchBuf;
						fGotOne = true;
					}
					MsiCloseHandle(hRecord);
				}
				MsiViewClose(hQuery);
			}
			MsiCloseHandle(hQuery);
		}
	}

	MsiCloseHandle(hMsi);
	return fGotOne;
}

// use the above function like this:
std::map<std::wstring, std::wstring> mapProps {
	{ L"ProductName", {} },
	{ L"ProductVersion", {} },
	{ L"Manufacturer", {} }
};

bool fGotProps = GetMsiProperties(lpSourcePath->GetString(), mapProps);
3 Likes

Thank you so much! I will pass this along to David (aka @void)

1 Like

Jon, David Carpenter, the creator of Everything, says Thank you for the source code snippet that allows Directory Opus to extract metadata from *.msi files. He says your code enabled him to add support for *.msi files in Everything. Thank you for sharing your code.

2 Likes