Wie fülle ich eine ComboBox zur Installationszeit in WiX auf?

Bearbeiten: Ich habe den folgenden Code aktualisiert, damit er jetzt funktioniert, dank Robs Antwort.

Ich habe ein paar Seiten gefunden, die zeigen, wie das geht (http://www.cmcrossroads.com/content/view/13160/120/, http://www.mail-archive.com/[email protected]/msg05103.html) und durchsuchte den Quellcode für WAI (http://wai.codeplex.com/), aber ich kann es scheinbar nicht in meinem Installer zum Laufen bringen, egal was ich versuche. Wenn jemand erkennen kann, was ich falsch mache, wäre ich sehr dankbar. Mein WiX-Fragment für den Dialog sieht folgendermaßen aus:

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

Mein benutzerdefinierter Aktionscode lautet:

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

Früher gab es zwei Probleme:

1) Der obige Code ist während der Ausführung der benutzerdefinierten Aktion mit "Funktion während der Ausführung fehlgeschlagen. Aktualisierung der Datenbank: Tabelle (n) fehlgeschlagen" fehlgeschlagen. - Dies lag an dem Indizierungsproblem, das den Code veranlasste, eine Zeichenfolge in eine int-Spalte zu schreiben.

2) Wenn ich die Leitung wechsle

lRecord.SetString(2, lWebsiteName);

zu

lRecord.SetString(2, lEntry.Name);

Wenn Sie dann auf trace schauen, scheint die Aktion erfolgreich zu sein, aber wenn das Installationsprogramm sie ausführt, hat die Combobox keine Einträge zur Auswahl.

Wenn ich das Kombinationsfeld so ändere, dass es fest codierte Werte enthält, funktioniert alles einwandfrei, auch wenn ich das Äquivalent von lWebsiteName fest codiere.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage