【问题标题】:How to read .mst(transform) Table along with .msi如何阅读 .mst(transform) Table 以及 .msi
【发布时间】:2013-05-27 10:09:58
【问题描述】:

mst + .msi 表信息。

我创建了以下函数来读取 msi 表

// 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;
    }

但是我无法使用此功能读取 .mst。我读到您需要对其使用 msi 转换,但我不想更改 msi 或 mst 的内容,我只需要阅读所有表格。请指出我正确的方向。提前致谢:)

【问题讨论】:

  • 顺便说一句,你没有处理你的一些课程。结帐:stackoverflow.com/questions/14020285/…
  • 感谢您指出 :) 将明确处理它们。 (我知道处理您使用的所有内容的好习惯,但它不会被 .net GC 自动处理吗?只是好奇。但再次感谢)
  • 最终。但是这些类有非托管(p/invoke)句柄,需要更及时地处理。

标签: c# wix windows-installer wix3.7 dtf


【解决方案1】:

根据定义,MST 是一种转换。它仅包含基本 MSI 的增量。

数据库类有一个名为 ViewTransform 的方法。如果 MST 与 MSI 兼容,它将成功并且更改将显示在 _TransformView 表中。

或者,如果您不想查看发生了什么变化但想查看最终状态,您可以将 MSI 复制到临时 MSI 并使用 ApplyTransform 方法应用转换然后提交。现在您可以使用已有的代码查询它了。

【讨论】:

  • 非常感谢@christopher,那么有没有办法在不创建临时文件的情况下查看合并的 mst+msi 表?
  • 您也许可以在内存中完成。我不能肯定地说,因为我从未尝试过。 MsiDatabaseApplyTransform (MSDN) doco 建议它可能会受到限制。见评论:msdn.microsoft.com/en-us/library/aa370074.aspx
  • 创建了一个临时 Msi,将其与 mst 合并并阅读 :) 非常感谢
【解决方案2】:

为我工作:

msiDatabase = new Database(@"Foo.msi", DatabaseOpenMode.ReadOnly);
msiDatabase.ApplyTransform(@"Foo.mst");

【讨论】:

    猜你喜欢
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    相关资源
    最近更新 更多