tags:

views:

44

answers:

1

Hello *,

I need to update an Attributes column in an MSI file. Unfortunately, I am unable to find any documentation (esp. for C++).

Here is a code snippet of what I am trying to do:

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

As stated upon record->Modify(...) throw a _com_error stating: IDispatch error #1000? What does that mean. Where Can I look up these error codes? These are not HRESULTs...

But more important questions are how do I update the record properly? How can I iterate through all selected records? Doing a new fetch and comparing the record with NULL results in an infinite loop.

Thanks for help,
Ovanes

A: 

Ok, found the problem :(

I opened the database in the read-only mode.

Here is the snipped which works:

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

Hope that helps to someone.

Ovanes

ovanes

related questions