更新MSI文件中的表

时间:2014-12-22 14:38:46

标签: c# sql vbscript windows-installer

我正在尝试更新MSI中的Media表,以便将#附加到Cabinet字段中的任何内容的开头。

我跑了:

Cscript WiRunSQL.vbs %CopiedFile% "UPDATE `Media` SET `Media`.`Cabinet`='%CabUpdate%' WHERE `Media`.`DiskId`=1"

但是这会引发Msi API错误80004005:OpenDatabase,DatabasePath,OpenMode

然后我创建了一个测试c#应用程序,用值替换Cabinet字段中的任何内容。但是它只是将Cabinet字段更新为空字符串。

        var db = new Database(@"C:\Users\Me\test.msi", DatabaseOpenMode.Direct);

        var query = db.ExecuteQuery("Select Cabinet from Media"); // gets: blah.cab

        string oldCab = query[0].ToString(); // this is 'blah.cab'

        string newCab = "#" + oldCab; //this is then '#blah.cab'


        string updateString = "UPDATE `Media` SET `Media`.`Cabinet` = '" + newCab + "'
        WHERE DiskId = 1";

        try
        {
            db.Execute(updateString);
        }
        catch(Exception ex)
        {

        }

有什么明显的东西我不见了吗?或者是否有另一种实现方法(不使用Orca,必须从批处理文件中运行)。

2 个答案:

答案 0 :(得分:0)

添加#仅表示使用嵌入式媒体。我假设您正在压缩cab并将它们放入_Streams并处理所有File表序列ID。

要仅更新您想要执行类似操作的字段:

首先,查询表格并获取媒体密钥和文件柜名称的字典。然后,遍历此集合并:

 using (View view = _database.OpenView( "SELECT * FROM `Media` WHERE `Media`.`DiskId` = '{0}'", mediaKey))
            {
                view.Execute();
                using (Record record = view.Fetch())
                {
                    record.SetString("Cabinet", "#" + cabinetName);
                    view.Update(record);
                }
            }

我从其他表的类似代码中修改了这个代码(但没有编译或测试)。我做了很多这方面的工作,而且最初看到的内容通常要多得多。

答案 1 :(得分:0)

我知道它有点晚了,但如果这有帮助:

        using (Database database = new Database(@"msi_path", DatabaseOpenMode.Transact))
            {
                using (var view = database.OpenView(database.Tables["Media"].SqlSelectString))
                {
                    view.Execute();
                    Record record = view.Fetch();
                    while (record != null)
                    {
                        if (record.GetString(4) != "") // replace the empty string with ur value
                        {
                            record.SetString("Cabinet", "#" + record.GetString(4));
                            view.Modify(ViewModifyMode.Assign, record);
                            database.Commit();
                        }
                        record = view.Fetch();
                    }
}