首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用MSI编程API更新MSI表

使用MSI编程API更新MSI表
EN

Stack Overflow用户
提问于 2010-06-18 21:43:46
回答 2查看 1.4K关注 0票数 1

我需要更新MSI文件中的属性列。不幸的是,我找不到任何文档(特别是用于C++)。

下面是我正在尝试做的代码片段:

代码语言:javascript
复制
DatabasePtr db = /* opening db succeeds*/
ViewPtr view = db->OpenView(_bstr_t("SELECT Attributes FROM Component"));
view->Execute(NULL);
RecordPtr record=view->Fetch();

record->PutIntegerData(2, record->GetIntegerData(1)|2048);

// I do not exactly understand the next 2 lines
// Should I really call Execute before Modify?
record->Execute(record);
record->Modify(msiViewModifyUpdate, record); //throws a _com_error

如记录->修改(...)所述抛出一个错误,声明: IDispatch _com_error #1000?这是什么意思。我可以在哪里找到这些错误代码?这些不是HRESULT。

但更重要的问题是如何正确地更新记录?如何遍历所有选定的记录?执行新的fetch并将记录与NULL进行比较会导致无限循环。

谢谢你的帮助

Ovanes

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-06-18 22:26:36

好了,找到问题了:(

我在只读模式中打开了数据库。

以下是工作的代码片段:

代码语言:javascript
复制
InstallerPtr installer(TEXT("WindowsInstaller.Installer"));
VARIANT open_flag;
VariantInit(&open_flag);
open_flag.vt = VT_I4;
open_flag.lVal = msiOpenDatabaseModeTransact;

DatabasePtr db = installer->OpenDatabase(msi_path, open_flag);
{
  ViewPtr view = db->OpenView(_bstr_t("SELECT Attributes FROM Component"));
  view->Execute(NULL);
  RecordPtr record=view->Fetch();

  if(!record) ... //error handling

  while(record)
  {
    record->PutIntegerData(1, record->GetIntegerData(1)|2048);

    record->Modify(msiViewModifyUpdate, record);
    record=view->Fetch();
  }
} //view->Close() is called implicitly
db->Commit();

希望这对某些人有帮助。

Ovanes

票数 0
EN

Stack Overflow用户

发布于 2014-08-24 15:10:57

使用C++来解决这个问题有点言过其实了。请阅读DTF:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3070114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档