我正在尝试更新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,必须从批处理文件中运行)。
答案 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();
}
}