How to know the property list contained an MSI file?
If we know the property name, we can get property value for a specific property. we can use the following codes:
WCHAR wzBuf[MAX_PATH+1]=L"";
DWORD dw=_countof(wzBuf);
fGoodPath = ( ERROR_SUCCESS == ::MsiGetPropertyW(hInstall, L"INSTALLLOCATION", wzBuf, &dw) );
Just wondering how can we know all the property names defined in MSI/MSP
files?
Github.com: VBScript sample from github.com: PullMSPOfficeUpdates.vbs which is recommended to check. Iterates patches. A "canned" github search.
Basic Sample: Here is a trimmed down sample which gets the Patch Code from an MSP. Sorry for no C++, but I am too rusty and not enough time (maybe add your own answer and set that accepted as C++ - hint: just edit your current one, it is more of a comment as it stands - prefer to edit your original answer or comment it - just the approach generally used here):
Const MSIOPENDATABASEMODE_PATCHFILE = 32
Const MSIPID_REVNUMBER = 7
Set installer = CreateObject("WindowsInstaller.Installer")
Set msp = installer.OpenDatabase("C:\MyPath.msp", MSIOPENDATABASEMODE_PATCHFILE)
Set summaryinfo = msp.SummaryInformation
MsgBox summaryinfo.Property(MSIPID_REVNUMBER)
UPDATE: I am not a C++ developer, but with some help from Installshield's Michael Urman, I think this C++ sample should work with Visual Studio 2017 at least. Please don't be too picky about the actual C++ constructs, use github.com to find more samples (canned search sample - just for others and myself in the future, I know you don't need it):
#include "pch.h"
#define WIN32_LEAN_AND_MEAN
#include <atlstr.h> // CString support from ATL
#include <Msiquery.h>
#pragma comment(lib, "msi.lib") // to allow linking
int main()
{
CString lpszFilename = L"C:\\YourPatchFile.msp";
PMSIHANDLE hSum;
DWORD dwErr = MsiGetSummaryInformation(0, lpszFilename, 0, &hSum);
if (ERROR_SUCCESS == dwErr)
{
UINT uiProperty = 7;
UINT uiDataType = 0;
INT iValue = 0;
FILETIME ftValue = { 0 };
CString sValue;
DWORD cchValue = MAX_PATH;
dwErr = MsiSummaryInfoGetProperty(hSum, uiProperty, &uiDataType, &iValue, &ftValue, (LPWSTR)sValue.GetString(), &cchValue);
MessageBox(NULL, sValue, L"Patch Code:", MB_OK);
}
MsiCloseHandle(hSum);
return 0;
}
Testing: 1)
Create new C++ console project in Visual Studio, 2)
Paste the above code to the new project's main "ConsoleApplicationX.cpp" file (where X is a number) - replacing whatever is there, 3)
Adjust the path to your MSP file (CString lpszFilename = L"C:\\YourPatchFile.msp";
), 4)
Say out loud: "fire in the hole" and hope for the best :-).
MSI API Documentation: Here are some links: