I want to read MSI file(Windows Installer Package). I have written a function as below which takes two input parameters : msifileName and Table Name and returns a data table which is one of the MSI table.
public DataTable ReadMsiPropertyTable(string msiFile, string tableName)
{
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
WindowsInstaller.Installer installer = (WindowsInstaller.Installer)Activator.CreateInstance(installerType);
Database database = installer.OpenDatabase(msiFile, 0);
string sqlQuery = String.Format("SELECT * FROM {0}",tableName);
View view = database.OpenView(sqlQuery);
view.Execute(null);
Record record = view.Fetch();
DataTable msiPropertyTable = new DataTable();
msiPropertyTable.Columns.Add("Column1", typeof(string));
msiPropertyTable.Columns.Add("Column2", typeof(string));
msiPropertyTable.Columns.Add("Column3", typeof(string));
msiPropertyTable.Columns.Add("Column4", typeof(string));
while (record != null)
{
int fieldCount;
fieldCount = record.FieldCount;
msiPropertyTable.Rows.Add(record.get_StringData(0), record.get_StringData(1), record.get_StringData(2), record.get_StringData(3));
record = view.Fetch();
}
return msiPropertyTable;
}
Using above code snippet, the number of rows and columns of Record are not known. SO I am statically returning only four columns. I want to return all the rows and columns of MSI Table which are in record.
So Please let me know how can I convert output of view or record to Dataset and then bind to Datatable. Or is there any other way to return all the rows and columns. Thanks in advance.
I would suggest you using the Deployment Tools Foundation (the API library to work with MSI packages, comes together with WiX Toolset) for this task. The API is handy and straight-forward.
For instance, there's a class
Database
. You can create it by providing the path to the MSI package to the constructor:And it gives the any information about the MSI database. For instance,
db.Tables["TableName"]
returns an instance of theTableInfo
class, which in its turn contains the information about columns, rows, primary keys, etc.Download and install WiX Toolset, and get more info from
DTF.chm
help file.Here's similar logic using the interop types rather then the DTF types. As you can see it's a lot more work. It's also a lot more fragile since COM is involved instead of P/Invoke. Also, if you can eliminate the requirement to create an ADO.NET DataTable, DTF supports LINQ queries and databinding. In other words, I wrote this for fun only. I would NEVER use this method in real code.
Here's how you do it using DTF to create the types for your Database, View and Record objects. It would be similar using COM Interop but I have no desire to do things the hard way.