mst + .msi table information.

I created following function to read msi Tables

// This method returns all rows and columns of a Table specified by Name
    public DataTable ReadMsiTableByName(string msiFile, string tableName)
    {
        DataTable msiTable = new DataTable(tableName);
        Database database = null;
        View view = null;

        try
        {
            using (database = new Database(msiFile, DatabaseOpenMode.ReadOnly))
            {
                string sqlQuery = String.Format("SELECT * FROM {0}", tableName);

                view = database.OpenView(sqlQuery);
                view.Execute(null);
                Record record = view.Fetch();

                ColumnCollection columnCollection = view.Columns;

                for (int i = 0; i < columnCollection.Count; i++)
                {
                    string columnName = columnCollection[i].Name.ToString();
                    System.Type columnType = columnCollection[i].Type;

                    msiTable.Columns.Add(columnName, columnType.UnderlyingSystemType);
                }

                while (record != null)
                {
                    DataRow row = msiTable.NewRow();
                    for (int i = 0; i < columnCollection.Count; i++)
                    {
                        string type = columnCollection[i].Type.ToString();

                        if (type == "System.String")
                        {
                            row[columnCollection[i].Name.ToString()] = record.GetString(columnCollection[i].Name.ToString());
                        }
                        else if (type == "System.Int16")
                        {
                            row[columnCollection[i].Name.ToString()] = record.GetInteger(columnCollection[i].Name.ToString());
                        }
                        else if (type == "System.Int32")
                        {
                            row[columnCollection[i].Name.ToString()] = record.GetInteger(columnCollection[i].Name.ToString());
                        }
                        else if (type == "System.IO.Stream")
                        {
                            System.IO.Stream stream;
                            stream = record.GetStream(columnCollection[i].Name.ToString());
                            row[columnCollection[i].Name.ToString()] = stream;
                        }
                    }
                    msiTable.Rows.Add(row);
                    record = view.Fetch();
                }
            }
        }

        catch (Exception ex)
        {
            CommonFn.CreateLog(ex.ToString());
        }

        finally
        {
            if (database != null)
                database.Close();

            if (view != null)
                view.Close();
        }
        return msiTable;
    }

However I am unable to read .mst with this function. I read that you need to use msi transform for it, But I don't want to change the content of msi or mst, I just need to read all the tables. Please point me in right direction. Thanks in Advance :)

有帮助吗?

解决方案

An MST is by definition a transform. It only contains the deltas of a base MSI.

The database class has a method called ViewTransform. If the MST is compatible with the MSI it'll succeed and the changes appear in the _TransformView table.

Alternatively if you don't want to see whats changed but you want to see the final state, you could copy the MSI to a temporary MSI and use the ApplyTransform method to apply the transform and then commit it. Now you could query it using the code you already have.

其他提示

Works for me:

msiDatabase = new Database(@"Foo.msi", DatabaseOpenMode.ReadOnly);
msiDatabase.ApplyTransform(@"Foo.mst");
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top