Jump to content

Read MSI data programatically with AutoIT


Go to solution Solved by JLogan3o13,

Recommended Posts

  • Moderators
  • Solution

Try something like this. It returns all properties, but you could easily have it check only for the ones you want:

$sMSI = FileOpenDialog("MSI Properties", @ScriptDir, "Windows Installer Files (*.msi)")

$oInstaller = ObjCreate("WindowsInstaller.Installer")
$oDB = $oInstaller.OpenDataBase($sMSI, 0)
$oView = $oDB.OpenView("SELECT Property,Value FROM Property")

$oView.Execute()

$oCount = 0


While @error = 0
    $oRecords = $oView.Fetch
    $oPropValue = $oRecords.StringData(2)
    $oPropName = $oRecords.StringData(1)

    If $oPropName <> "" Then
        $oCount += 1
        ConsoleWrite($oPropName & " = " & $oPropValue & @CRLF)
    EndIf
WEnd

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

Nice stuff... much simplier than I would have guessed.

I made some modifications that might be useful to others for getting a specific MSI Property.

$sMSI = FileOpenDialog("MSI Properties", @ScriptDir, "Windows Installer Files (*.msi)")

MsgBox(0,0,'ProductName: ' & Execute_MSI_Query($sMSI,'ProductName'))
MsgBox(0,0,'Manufacturer: ' & Execute_MSI_Query($sMSI,'Manufacturer'))
MsgBox(0,0,'ProductVersion: ' & Execute_MSI_Query($sMSI,'ProductVersion'))


Func Execute_MSI_Query($MSIPath, $PropertyName)
    If FileExists($MSIPath) And $PropertyName <> '' Then


        Local $Query = "SELECT Value FROM Property WHERE Property = '" & $PropertyName & "'"

        $oInstaller = ObjCreate("WindowsInstaller.Installer")
        $oDB = $oInstaller.OpenDataBase($MSIPath, 0)
        $oView = $oDB.OpenView($Query)

        $oView.Execute()

        $oRecords = $oView.Fetch
        $oPropValue = $oRecords.StringData(1)

        If $oPropValue <> "" Then
            Return $oPropValue
        EndIf

    EndIf

    Return ""
EndFunc
Edited by super1337
Link to comment
Share on other sites

  • 2 years later...
On 1/3/2015 at 2:58 AM, JLogan3o13 said:

Try something like this. It returns all properties, but you could easily have it check only for the ones you want:

$sMSI = FileOpenDialog("MSI Properties", @ScriptDir, "Windows Installer Files (*.msi)")

$oInstaller = ObjCreate("WindowsInstaller.Installer")
$oDB = $oInstaller.OpenDataBase($sMSI, 0)
$oView = $oDB.OpenView("SELECT Property,Value FROM Property")

$oView.Execute()

$oCount = 0


While @error = 0
    $oRecords = $oView.Fetch
    $oPropValue = $oRecords.StringData(2)
    $oPropName = $oRecords.StringData(1)

    If $oPropName <> "" Then
        $oCount += 1
        ConsoleWrite($oPropName & " = " & $oPropValue & @CRLF)
    EndIf
WEnd

I am getting error as below, when I execute this code for last record.

"C:\Users\ukreddy\Desktop\test.au3" (19) : ==> The requested action with this object has failed.:
$oPropValue = $oRecords.StringData(2)
$oPropValue = $oRecords^ ERROR
->14:59:31 AutoIt3.exe ended.rc:1
+>14:59:31 AutoIt3Wrapper Finished.

But the @error is 0 for it.

Link to comment
Share on other sites

  • Moderators

@ur Is it failing on a particular property? Have you tried it on multiple MSIs to ensure it is not something specific to the Property table of the one file?

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

  • Moderators

Perhaps not, it has been a long time since I posted that. I will take a look when I get a few moments to see what may have changed.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

  • Moderators

I am looking for a graceful "end of table" marker. But as a workaround you could just check to see if the object exists:

$sMSI = FileOpenDialog("MSI Properties", @ScriptDir, "Windows Installer Files (*.msi)")

$oInstaller = ObjCreate("WindowsInstaller.Installer")
$oDB = $oInstaller.OpenDataBase($sMSI, 0)
$oView = $oDB.OpenView("SELECT Property,Value FROM Property")

$oView.Execute()

$oCount = 0


While @error = 0
    $oRecords = $oView.Fetch
        If Not (IsObj($oRecords)) Then ExitLoop ;<======

    $oPropValue = $oRecords.StringData(2)
    $oPropName = $oRecords.StringData(1)

    If $oPropName <> "" Then
        $oCount += 1
        ConsoleWrite($oPropName & " = " & $oPropValue & @CRLF)
    EndIf
WEnd

 

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

  • Moderators

In fact, since I am playing around with it (I had completely forgotten doing this one), I would probably do something like this, rather than a ConsoleWrite. Hindsight :)

#include <Array.au3>

Local $aProperties[1][2] = [["Name", "Value"]]
Local $oRecords, $oPropName, $oPropValue, $iCount = 0
Local $sMSI = FileOpenDialog("MSI Properties", @ScriptDir, "Windows Installer Files (*.msi)")
Local $oInstaller = ObjCreate("WindowsInstaller.Installer")
Local $oDB = $oInstaller.OpenDataBase($sMSI, 0)
Local $oView = $oDB.OpenView("SELECT * FROM Property")

$oView.Execute()

While @error = 0
    $oRecords = $oView.Fetch
        If Not (IsObj($oRecords)) Then ExitLoop

    $oPropName = $oRecords.StringData(1)
    $oPropValue = $oRecords.StringData(2)

    If $oPropName <> "" Then
        $iCount += 1
        _ArrayAdd($aProperties, $oPropName & "|" & $oPropValue)
    EndIf
WEnd

    _ArraySort($aProperties, 0, 1)
    _ArrayDisplay($aProperties)

 

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

 Hi @JLogan3o13

The program is not executing when the below query is executed.

Any idea?

$fname = "Complete"
    Local $oView = $oDB.OpenView("SELECT Component_,Directory FROM FeatureComponents,Component where FeatureComponents.Component_=Component.Component AND Feature_ = '"&$fname&"'")
    $oView.Execute()

 

Edited by ur
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...