seeker
seeker

Reputation: 23

How to get all properties in msi file

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

Answers (2)

Stein Åsmul
Stein Åsmul

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

Stein &#197;smul
Stein &#197;smul

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

Related Questions