Обновление таблицы MSI с использованием API программирования MSI - PullRequest
1 голос
/ 18 июня 2010

Мне нужно обновить столбец Атрибуты в файле MSI.К сожалению, я не могу найти никакой документации (особенно для C ++).

Вот фрагмент кода того, что я пытаюсь сделать:

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

Как указано в записи->Изменить (...) выбросить _com_error, заявив: IDispatch ошибка # 1000?Что это значит.Где я могу найти эти коды ошибок?Это не HRESULT ...

Но более важные вопросы - как правильно обновить запись?Как я могу перебрать все выбранные записи?Выполнение новой выборки и сравнение записи с NULL приводит к бесконечному циклу.

Спасибо за помощь,
Ovanes

Ответы [ 2 ]

0 голосов
/ 24 августа 2014

Использование C ++ для этого немного излишне.Прочитайте DTF:

0 голосов
/ 18 июня 2010

Хорошо, обнаружена проблема: (

Я открыл базу данных в режиме только для чтения .

Вот разрезанный, который работает:

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

Надеюсь, это кому-нибудь поможет.

Ованес

...