我正在尝试更新MSI中Feature Table中的现有条目。更具体地说,是功能标识符本身(第一列-功能)。
String featureQuery = "SELECT * FROM `Feature`";
view = db.OpenView(featureQuery);
view.Execute();
rec = view.Fetch();
rec.SetString("Feature", "NewName"); <- error here "Function failed during execution"
view.Modify(ViewModifyMode.Update, rec);但是,当我做同样的事情,只是将"Feature“列改为" title”(在出错的行中)时,例如,MSI中的title列改为"NewName“。
所以,我的问题是--这是可能的吗,或者我在什么地方犯了错?如果以后,请告诉我在哪里,我将非常感激。无论如何,任何建议都非常感谢,谢谢!
发布于 2018-01-12 04:54:53
我的这个示例并不完全相同,因为它是我的哑巴DTF /Invoke测试,但它确实可以工作并更改DTF值,因此它是被API允许的,也许Feature.Feature包装类在缺省值等方面有一些需要更改的地方。明显的区别在于SetString/MsiRecordSetString代码,其中本机API需要一个字段号。很抱歉没有查看DTF,但是SetString可能会将"Feature“字符串映射到实际的字段编号,以更新记录的第一个字段。如果它有一个带字段号的重载,请尝试那个重载。我要补充的是,您实际上并没有选择一个特定的特性,因此您面临修改“第一个”特性的风险,因为select *将返回所有这些特性。
IntPtr hDb = IntPtr.Zero;
int res = MsiInvoke.MsiOpenDatabase("C:\\Phil\\MyDD\\Samples Setup\\InsertRTF\\setup.msi", MsiInvoke.MSIDBOPEN_TRANSACT, out hDb);
string qinsert = "SELECT * FROM `Feature`";
IntPtr hView =IntPtr.Zero;
res = MsiInvoke.MsiDatabaseOpenView(hDb, qinsert, out hView);
res = MsiInvoke.MsiViewExecute(hView, 0);
IntPtr hRec= IntPtr.Zero;
res = MsiInvoke.MsiViewFetch(hView, out hRec);
res = MsiInvoke.MsiRecordSetString(hRec, 1, "Whatever");
res = MsiInvoke.MsiViewModify(hView, 4, hRec); // 4 = msimodify_replace 3 = modify_assign
res = MsiInvoke.MsiViewClose(hView);
res = MsiInvoke.MsiDatabaseCommit(hDb);MsiInvoke只是我创建的一个愚蠢的P/invoke类,如下所示:
public class MsiInvoke
{
//Oops MSIHandles are not IntPtrs.
[DllImport("msi", CharSet = CharSet.Auto)]
public static extern int MsiOpenDatabase(string filename, int persist, out IntPtr dbhandle);
public const int MSIDBOPEN_DIRECT = 2;
public const int MSIDBOPEN_TRANSACT = 1;https://stackoverflow.com/questions/48196766
复制相似问题