Jak zapełnić ComboBox w czasie instalacji w WiX?

Edytuj: Zaktualizowałem poniższy kod, dzięki czemu teraz działa, dzięki odpowiedzi Roba.

Znalazłem kilka stron, które pokazują, jak to zrobić (http://www.cmcrossroads.com/content/view/13160/120/, http://www.mail-archive.com/[email protected]/msg05103.html) i przejrzał kod źródłowy WAI (http://wai.codeplex.com/), ale nie mogę sprawić, by działało to w moim instalatorze bez względu na to, co spróbuję. Jeśli ktoś zauważy, co robię źle, byłbym bardzo wdzięczny. Mój fragment WiX dla dialogu wygląda następująco:

<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>

Mój niestandardowy kod akcji to:

[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;
}

Były dwa problemy:

1) Powyższy kod nie powiódł się podczas uruchamiania akcji niestandardowej za pomocą „Funkcja nie powiodła się podczas wykonywania. Baza danych: Aktualizacja tabeli (-ów) nie powiodła się”. - To z powodu problemu z indeksowaniem powodującego, że kod próbuje napisać łańcuch do kolumny int.

2) Jeśli zmienię linię

lRecord.SetString(2, lWebsiteName);

do

lRecord.SetString(2, lEntry.Name);

potem patrząc na ślad akcja wydaje się udana, ale gdy instalator uruchomi combobox, nie ma żadnych wpisów do wyboru.

Jeśli zmienię combobox tak, aby miał zakodowane wartości, wszystko działa dobrze, nawet jeśli hardcode jest odpowiednikiem lWebsiteName.

questionAnswers(2)

yourAnswerToTheQuestion