Monday, December 22, 2014

Mini-Orca: Getting Product Name and Code from an MSI

Was poking around the script source for the DSC package resource and found this nice way to get the product name and code for an MSI.  Before this I’d been using Orca to load the file and look at its properties.  This way looks much nicer.

$sig = @'

[DllImport("msi.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)]

private static extern UInt32 MsiOpenPackageW(string szPackagePath, out IntPtr hProduct);

 

[DllImport("msi.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)]

private static extern uint MsiCloseHandle(IntPtr hAny);

 

[DllImport("msi.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)]

private static extern uint MsiGetPropertyW(IntPtr hAny, string name, StringBuilder buffer, ref int bufferLength);

 

private static string GetPackageProperty(string msi, string property)

{

    IntPtr MsiHandle = IntPtr.Zero;

    try

    {

        var res = MsiOpenPackageW(msi, out MsiHandle);

        if (res != 0)

        {

            return null;

        }

           

        int length = 256;

        var buffer = new StringBuilder(length);

        res = MsiGetPropertyW(MsiHandle, property, buffer, ref length);

        return buffer.ToString();

    }

    finally

    {

        if (MsiHandle != IntPtr.Zero)

        {

            MsiCloseHandle(MsiHandle);

        }

    }

}

public static string GetProductCode(string msi)

{

    return GetPackageProperty(msi, "ProductCode");

}

   

public static string GetProductName(string msi)

{

    return GetPackageProperty(msi, "ProductName");

}

'@

$MsiTools = Add-Type -PassThru -Namespace Microsoft.Windows.DesiredStateConfiguration.PackageResource `

    -Name MsiTools -Using System.Text -MemberDefinition $sig

 

$MsiTools::GetProductName("C:\SharePointPreReqs\sqlncli.msi")

### Result: Microsoft SQL Server 2012 Native Client

 

$MsiTools::GetProductCode("C:\SharePointPreReqs\sqlncli.msi")

### Result: {49D665A2-4C2A-476E-9AB8-FCC425F526FC} 

 

No comments: