Reputation: 23
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?
Upvotes: 2
Views: 2269
Reputation: 42126
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:
Upvotes: 2
Reputation: 42126
SDK Documentation: I would try these documented ones from the MSI SDK first.
SDK Sources: There is also the msi.h
header file from the SDK. Seeing as you have Visual Studio installed, just right-click the include entry and go "Open Document <msi.h>"
. You can also find it on github.com (here and there). Try searching for "INSTALLPROPERTY_PACKAGECODE"
or some other documented property in msi.h
:
Sample:
#define INSTALLPROPERTY_PACKAGECODE __TEXT("PackageCode")
#define INSTALLPROPERTY_VERSION __TEXT("Version")
#if (_WIN32_MSI >= 110)
#define INSTALLPROPERTY_PRODUCTICON __TEXT("ProductIcon")
...
Etc... Not sure if this is what you asked for exactly?
Links:
VBScript, built-in MSI properties: from this old answer, a list of VBScript accessible properties:
ProductCode
, Language
, ProductName
, PackageCode
, Transforms
, AssignmentType
, PackageName
, InstalledProductName
, VersionString
, RegCompany
, RegOwner
, ProductID
, ProductIcon
, InstallLocation
, InstallSource
, InstallDate
, Publisher
, LocalPackage
, HelpLink
, HelpTelephone
, URLInfoAbout
, URLUpdateInfo
Upvotes: 1