How to list all the files in an MSI Installer using VBSciript
Just a quickie today, someone wanted me to give them a list of all the files that were inside an Windows Installer (MSI) and I remembered that MSI's were databases (Access?) so:
Option Explicit
Const msiOpenDatabaseModeReadOnly = 0
Dim installer : Set installer = Nothing
Dim WshShell : Set WshShell = CreateObject("Wscript.Shell")
Dim szMSI : szMSI = WScript.Arguments.Item(0)
Dim folder : folder = WshShell.CurrentDirectory
Set installer = Wscript.CreateObject("WindowsInstaller.Installer")
Dim database : Set database = installer.OpenDatabase(szMSI, msiOpenDatabaseModeReadOnly)
Dim View, Record
Set View = database.OpenView("SELECT FileName FROM File") 'could include FileSize, etc
View.Execute
Do
Set Record = View.Fetch
If Record Is Nothing Then Exit Do
Wscript.Echo Record.StringData(1)
Loop
Set View = Nothing
Wscript.Quit(0)
You call it like this: cscript WhateverFileName.vbs YourInstallerDatabase.msi
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
Comments are closed.
I ran this on one of my MSI files and noticed that the output contains both short and long file names.
I extended the code to allow the caller to manage how the value is output.
The default is to display the long file name.
Sample calls:
'Output long file names
cscript ListMsiFiles.vbs YourInstallerDatabase.msi
'Output short file names implicitly
cscript ListMsiFiles.vbs YourInstallerDatabase.msi 0
'Output long file names explicitly
cscript ListMsiFiles.vbs YourInstallerDatabase.msi 1
'Output unprocessed filenames
cscript ListMsiFiles.vbs YourInstallerDatabase.msi 2
ListMsiFiles.vbs
================
Option Explicit
Const msiOpenDatabaseModeReadOnly = 0
' Filename may contain both short and long filenames
' These constants enable us to specify which form we want
Const fileNameTypeShort = 0
Const fileNameTypeLong = 1
Const fileNameTypeBoth = 2
Dim installer : Set installer = Nothing
Dim WshShell : Set WshShell = CreateObject("Wscript.Shell")
Dim szMSI : szMSI = WScript.Arguments.Item(0)
Dim fileNameType : fileNameType = fileNameTypeLong
If WScript.Arguments.Count > 1 Then
fileNameType = WScript.Arguments.Item(1)
End If
Dim folder : folder = WshShell.CurrentDirectory
Set installer = Wscript.CreateObject("WindowsInstaller.Installer")
Dim database : Set database = installer.OpenDatabase(szMSI, msiOpenDatabaseModeReadOnly)
Dim View, Record
Set View = database.OpenView("SELECT FileName FROM File") 'could include FileSize, etc
View.Execute
Dim fileNameString 'As String
Dim fileNameParts 'As String()
Dim isSplitRequired : isSplitRequired = False
Do
Set Record = View.Fetch
If Record Is Nothing Then Exit Do
fileNameString = Record.StringData(1)
If fileNameType = fileNameTypeBoth Then
isSplitRequired = False
Else
If Instr(fileNameString, "|") > -1 Then
isSplitRequired = True
End if
End If
If isSplitRequired Then
fileNameParts = Split(fileNameString, "|")
Wscript.Echo fileNameParts(fileNameType)
Else
Wscript.Echo fileNameString
End if
Loop
Set View = Nothing
Wscript.Quit(0)