【问题标题】:Update MSI table using MSI programming API使用 MSI 编程 API 更新 MSI 表
【发布时间】:2014-08-24 15:12:42
【问题描述】:

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

这是我正在尝试做的代码 sn-p:

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

如记录所述->Modify(...) 抛出 _com_error 说明:IDispatch 错误 #1000?这意味着什么。我在哪里可以查看这些错误代码?这些不是 HRESULT...

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

感谢您的帮助,
风向标

【问题讨论】:

    标签: installation windows-installer record dtf


    【解决方案1】:

    为此使用 C++ 有点矫枉过正。阅读 DTF:

    【讨论】:

      【解决方案2】:

      好的,找到问题了:(

      我以只读模式打开数据库。

      这是有效的剪辑:

      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();
      

      希望对某人有所帮助。

      欧文

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-16
        • 1970-01-01
        • 2012-10-22
        • 2011-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多