Introduction
There are many tools, such as Orca, for tampering with the Microsoft Installer Database .msi files. This sample shows how to build a MSI database file reader. Though it does not allow to modify it, it will be helpful to those who want to get some insights in to the structure of an MSI.
Using the code
Create the project
- File -> New -> New project
Create a new MsiDbReader Visual Basic Windows Application.
Add the Windows components
-
Click View -> Toolbox (Ctrl+Alt+X).
-
Drag an OpenFileDialog
, an ImageList
, and a MainMenu
into the form.
-
Right click the OpenFileDialog1
in the form designer -> Properties. Set the Filter property
to "Microsoft Installer DB (*.msi)|*.msi|All files (*.*)|*.*".
-
Right click the ImageList1
in the form designer -> Properties.
-
Click the button next to the Image Collection property. Add an icon image.
-
Right click MainMenu1
-> Edit menu. Type &Open.
-
From the Toolbox, drag a ListView
into the form.
-
Right click the ListView1
-> Properties. Set the Dock
property to Left
. Set SmallImageList
and StateImageList
properties to ImageList1
. Set MultiSelect
property to False
. Set View
property to SmallIcon
.
-
From the Toolbox, drag a Splitter
into the form.
-
From the Toolbox, drag a DataGrid
into the form.
-
From the Toolbox Data tab, drag a DataView
into the form.
-
Right click DataGrid1
-> Properties. Set Dock
property to Fill
. Set DataSource
property to DataView1
.
Add the code:
Right click Form1 -> View Code. Add the following variable declarations to the Form1
class:
Dim Installer
Dim Database
Dim View
Dim Record
Add the following MenuItem1_Click
event method:
Private Sub MenuItem1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MenuItem1.Click
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
ListView1.Clear()
Installer = CreateObject("WindowsInstaller.Installer")
Database = Installer.OpenDatabase(OpenFileDialog1.FileName, 0)
View = Database.OpenView("SELECT 'Name' FROM '_Tables'")
View.Execute(Record)
Record = View.Fetch()
While Not Record Is Nothing
ListView1.Items.Add(Record.StringData(1), 0)
Record = View.Fetch()
End While
End If
End Sub
Add the following ListView1_SelectedIndexChanged
event method:s
Private Sub ListView1_SelectedIndexChanged(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles ListView1.SelectedIndexChanged
If ListView1.SelectedItems.Count = 0 Then
Exit Sub
End If
Installer = CreateObject("WindowsInstaller.Installer")
View = Database.OpenView("SELECT 'Name' FROM '_Columns'" & _
" WHERE 'Table' = '" & _
ListView1.SelectedItems(0).Text & "' ")
View.Execute(Record)
Dim DbColumns As String = ""
Record = View.Fetch()
While Not Record Is Nothing
DbColumns = DbColumns & "'" & Record.StringData(1) & "'"
Record = View.Fetch()
If Not Record Is Nothing Then
DbColumns = DbColumns & ", "
End If
End While
View = Database.OpenView("SELECT " & DbColumns & _
" FROM '" & ListView1.SelectedItems(0).Text & "' ")
View.Execute(Record)
Dim ColumnsAR() As String = Split(DbColumns, "', '")
ColumnsAR(0) = ColumnsAR(0).TrimStart("'")
ColumnsAR(ColumnsAR.Length - 1) = _
ColumnsAR((ColumnsAR.Length - 1)).TrimEnd("'"c)
DataView1.Table = New DataTable(ListView1.SelectedItems(0).Text)
For Each TableColumn As String In ColumnsAR
DataView1.Table.Columns.Add(TableColumn, _
Type.GetType("System.String"))
Next TableColumn
Dim NewRow As DataRow
Record = View.Fetch()
While Not Record Is Nothing
NewRow = DataView1.Table.NewRow()
For I As Integer = 0 To ColumnsAR.Length - 1
Try
NewRow(ColumnsAR(I)) = Record.StringData(I + 1)
Catch ex As Exception
NewRow(ColumnsAR(I)) = "(Binary)"
End Try
Next
DataView1.Table.Rows.Add(NewRow)
Record = View.Fetch()
End While
End Sub
Build and run the application.
History
- 21 Nov. 2006 - Intial release.
Rodolfo Ortega is a Cuban Computer Scientist. He works as IT Auditor for the CIMEX S.A. subsidiary in Holguin, Cuba. He lives and works in Holguin, in the eastern part of the island of Cuba.
You can contact him at rodolfom[]cimex.com.cu for any personal message: Ideas on new articles, bibliography about new APIs, questions, are wellcome.
Submit questions related with current article to the article forum.