Apologies for making a "duplicate" post, but this forum seems to get a lot more eyeball traffic than the Scripting forum.

Does anyone happen to know of any scripts or tools to export/extract specific information from an MSI or MST?

I am definitely not a programmer type. I just use simple VBscript, Winbatch and/or Wisescript for most of the MSI custom actions I need, which is usually enough. However, I currently have a need for something more advanced that can extract and parse specific pieces of MSI/MST data and then pass this data as parameters to another script --or, alternatively-- pipe it into a text file.

kkaminsk located the following code for me:
Export File List to Excel From MSI Using VBScript
http://www.serverwatch.com/tutorials/article.php/1548261

This works, but unfortunately just exports the entire contents of whatever table you specify, including column headers. What I'm looking for is something that allows a lot more precision, specifically the ability to export just the data for a specific column from a table. Also having some ability to parse the data would be helpful too.

For example, I need to know the following:
1. How many shortcuts are in an MSI's shortcut table?
2. What are the long filenames for these shortcuts? ("Name" column value --minus the "SHORTC~1|" part)
3. Where are they being delivered? (what "Directory_" column value resolves to)

Perhaps there is no simple canned vbscript solution for this --I've searched and have yet to find one. Any donated code, or ideas/leads for further research would be greatly appreciated, thanks.
0 Comments   [ + ] Show Comments

Comments

Please log in to comment

Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.

Answers

0
Well I wanted to find some more info because I am pretty sure you can achieve what you need for the most part by talking transact SQL to the MSI via VBScript and then I Googled up this nugget.

http://www.installshield.com/news/newsletter/0302-articles/msiaccess.asp

I don't think you'll easily find code that does exactly what you are looking for but I believe that you can code it with VBS if you have the time to sort it out. Then again maybe there is somebody on this board that has written something that you can use off the shelf.
Answered 05/09/2006 by: kkaminsk
Ninth Degree Black Belt

Please log in to comment
0
Thanks again, kkaminsk.

This will at least give me something to experiment with for the next couple of days. If I can successfully adapt it to fit my needs, I'll post the code here.
Answered 05/09/2006 by: norexx
Orange Belt

Please log in to comment
0
(Very late) follow-up: I tried adapting that code to fit my specific needs (see original post); but, alas, I suck at VBscript and never got it to work very well. Time for me to enroll in a VBscript class!
Answered 11/08/2007 by: norexx
Orange Belt

Please log in to comment
0
Run this VBScript in a DOS prompt, ex. cscript C:\msiGetShortcutInfo.vbs C:\Package.msi


Dim MsiPath : MsiPath = WScript.Arguments(0)
Dim Session : Set Session = GetSession(MsiPath)
Dim Database : Set Database = OpenDatabase(MsiPath)
Dim TableView : Set TableView = GetTableView(Database, "SELECT * FROM `Shortcut`")
Dim Record : Set Record = TableView.Fetch()
Dim oShortcutInfo : Set oShortcutInfo = CreateObject("Scripting.Dictionary")
Dim sShortcutName
Do While Not (Record Is Nothing)
sShortcutName = Record.StringData(3)
If InStr(sShortcutName, "|") Then sShortcutName = Mid(sShortcutName, InStr(sShortcutName, "|")+1)
oShortcutInfo.Add Record.StringData(1), GetFormatRecord("[" & Record.StringData(2) & "]") & sShortcutName

Set Record = TableView.Fetch()
Loop
WScript.Echo "Shortcuts found: " & oShortcutInfo.Count & vbNewLine
If oShortcutInfo.Count > 0 Then
Dim cShortcuts : cShortcuts = oShortcutInfo.Keys
For Each sShortcut in cShortcuts
WScript.Echo oShortcutInfo.Item(sShortcut)
Next
End If
Function OpenDatabase(MsiPath)
Const msiOpenDatabaseModeReadOnly = 0

Set OpenDatabase = Nothing
Dim Installer : Set Installer = CreateObject("WindowsInstaller.Installer")
Set OpenDatabase = Installer.OpenDatabase(MsiPath, msiOpenDatabaseModeReadOnly)

Set Installer = Nothing
End Function
Function GetSession(msiPath)
Const msiOpenDatabaseModeReadOnly = 0
Const msiUILevelProgressOnly = 64

Dim oInstaller, oDatabase, oSession, oView, oRecord

Set oInstaller = CreateObject("WindowsInstaller.Installer")
oInstaller.UILevel = msiUILevelProgressOnly

Set oDatabase = oInstaller.OpenDatabase(msiPath, msiOpenDatabaseModeReadOnly)
Set oSession = oInstaller.OpenPackage(msiPath, msiOpenDatabaseModeReadOnly)

Set oView = oDatabase.OpenView("Select * From `InstallExecuteSequence` Order By `Sequence`")
oView.Execute

Set oRecord = oView.Fetch
Do While Not (oRecord Is Nothing)
oSession.DoAction oRecord.StringData(1)
If oRecord.StringData(1) = "CostFinalize" Then Exit Do

Set oRecord = oView.Fetch
Loop

Set GetSession = oSession

Set oRecord = Nothing
Set oView = Nothing
Set oSession = Nothing
Set oDatabase = Nothing
End Function
Function GetFormatRecord(sRecord)
Dim FormatRecord : Set FormatRecord = Session.Installer.CreateRecord(0)
FormatRecord.StringData(0) = sRecord

GetFormatRecord = Session.FormatRecord(FormatRecord)
Set FormatRecord = Nothing
End Function
Function GetTableView(Database, Query)
On Error Resume Next
Set GetTableView = Nothing

Dim View : Set View = Database.OpenView(Query)
View.Execute()

Set GetTableView = View
Set View = Nothing
End Function

Answered 11/09/2007 by: AngelD
Red Belt

Please log in to comment
0
What's wrong with WiLstPrd.vbs from the SDK? I adapted that script ages ago to add stuff I wanted (additional switches, export to CSV, etc) and it's served me well.
Answered 11/09/2007 by: VBScab
Red Belt

Please log in to comment
0
Ian,
Sure, I do agree that using a combination of the SDK provided scripts would be sufficient.
But as norexx had basic knowledge of scripting I just provided him with one that would do what he was asking for.

Please feel free to do the same if you have another solution.
Answered 11/09/2007 by: AngelD
Red Belt

Please log in to comment
0
Kim,
I wasn't having a go at you. I used the bottom-most 'Reply' box instead of the 'Reply' link in norexx's post. That of course meant the reply was to you, when it was intended for norexx. Even so, it reads badly and I apologise to all for what looks like a conciliatory tone. I am duly chastened :(
Answered 11/09/2007 by: VBScab
Red Belt

Please log in to comment
0
No offence taken, Cheers
Answered 11/09/2007 by: AngelD
Red Belt

Please log in to comment
Answer this question or Comment on this question for clarity