Как мне заполнить ComboBox во время установки в WiX?

Изменить: я обновил код ниже, чтобы он теперь работал, благодаря ответу Роба.

Я нашел пару страниц, которые показывают, как это сделать (http://www.cmcrossroads.com/content/view/13160/120/, http://www.mail-archive.com/[email protected]/msg05103.html) и просмотрел исходный код WAI (http://wai.codeplex.com/), но я не могу заставить его работать в моем установщике, что бы я ни пытался. Если кто-то может заметить, что я делаю неправильно, я был бы очень благодарен. Мой фрагмент WiX для диалога выглядит так:

<UI>
  <Dialog>

...snip...

    <Control Id="WebsiteName" Type="ComboBox" ComboList="yes" Sorted="yes" Property="IIS_WEBSITENAME" X="20" Y="73" Width="150" Height="17"/>

...snip...

    <!-- We want our custom action to fill in the WebsiteName ComboBox above
         however, if no ComboBox entries exist at compile time then the
         ComboBox table is not created in the MSI and we can't add to it in
         the custom action. So we have this hidden dummy list box to force
         the table to appear. -->
    <Control Id="DummyComboBox" Hidden="yes" Type="ComboBox" Sorted="yes" ComboList="yes" Property="DUMMYPROPERTY" X="65" Y="60" Width="150" Height="18">
      <ComboBox Property="DUMMYPROPERTY">
        <ListItem Text="Dummy" Value="Dummy"/>
      </ComboBox>
    </Control>
  </Dialog>
</UI>

<Property Id="DUMMYPROPERTY">Dummy</Property>
<Property Id="IIS_WEBSITENAME"/>
<CustomAction Id="FillWebsiteNameList" BinaryKey="WiXCustomAction.dll" DllEntry="FillWebsiteNameList" Execute="immediate" />
<InstallUISequence>
  <Custom Action="FillWebsiteNameList" After="CostFinalize"/>
</InstallUISequence>

Мой код пользовательского действия:

[CustomAction]
public static ActionResult FillWebsiteNameList(Session xiSession)
{
  xiSession.Log("Begin FillWebsiteNameList");

  xiSession.Log("Opening view");

  View lView = xiSession.Database.OpenView("SELECT * FROM ComboBox");
  lView.Execute();

  xiSession.Log("Creating directory entry");

  DirectoryEntry lIis = new DirectoryEntry("IIS://localhost/w3svc");

  xiSession.Log("Checking each child entry");

  int lIndex = 1;
  foreach (DirectoryEntry lEntry in lIis.Children)
  {
    if (lEntry.SchemaClassName == "IIsWebServer")
    {
      xiSession.Log("Found web server entry: " + lEntry.Name);

      string lWebsiteName = (string)lEntry.Properties["ServerComment"].Value;
      xiSession.Log("Website name: " + lWebsiteName);

      xiSession.Log("Creating record");
      Record lRecord = xiSession.Database.CreateRecord(4);

      xiSession.Log("Setting record details");
      lRecord.SetString(1, "IIS_WEBSITENAME");
      lRecord.SetInteger(2, lIndex);
      lRecord.SetString(3, lEntry.Name); // Use lWebsiteName only if you want to look up the site by name.
      lRecord.SetString(4, lWebsiteName);

      xiSession.Log("Adding record");
      lView.Modify(ViewModifyMode.InsertTemporary, lRecord);

      ++lIndex;
    }
  }

  xiSession.Log("Closing view");

  lView.Close();

  xiSession.Log("Return success");

  return ActionResult.Success;
}

Раньше было две проблемы:

1) Приведенный выше код завершился ошибкой во время выполнения пользовательского действия с «Функция завершилась ошибкой во время выполнения. База данных: обновление таблиц не выполнено». - Это произошло из-за проблемы с индексацией, из-за которой код пытался записать строку в столбец int.

2) Если я поменяю строку

lRecord.SetString(2, lWebsiteName);

в

lRecord.SetString(2, lEntry.Name);

затем, глядя на трассировку, действие кажется успешным, но при запуске установщика у выпадающего списка нет записей для выбора.

Если я изменю в выпадающем списке жестко закодированные значения, все будет хорошо, даже если я жестко закодировал эквивалент lWebsiteName.

Ответы на вопрос(2)

Ваш ответ на вопрос