¿Cómo relleno un ComboBox en el momento de la instalación en WiX?

Edit: He actualizado el código a continuación para que ahora funcione, gracias a la respuesta de Rob.

He encontrado un par de páginas que muestran cómo hacer esto (http://www.cmcrossroads.com/content/view/13160/120/, http://www.mail-archive.com/[email protected]/msg05103.html) y miró a través del código fuente de WAI (http://wai.codeplex.com/), pero parece que no puedo hacer que funcione en mi instalador, no importa lo que intente. Si alguien puede ver lo que estoy haciendo mal, estaría muy agradecido. Mi fragmento de WiX para el diálogo se ve así:

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

Mi código de acción personalizado es:

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

Solía ​​haber dos problemas:

1) El código anterior falló durante la ejecución de la acción personalizada con "Falló la función durante la ejecución. Base de datos: Actualización de la tabla (s)". - Esto se debió a un problema de indexación que hizo que el código intentara escribir una cadena en una columna int.

2) Si cambio la linea

lRecord.SetString(2, lWebsiteName);

a

lRecord.SetString(2, lEntry.Name);

luego, al observar el rastreo, la acción parece tener éxito, pero cuando el instalador ejecuta el cuadro combinado no tiene entradas para elegir.

Si cambio el cuadro combinado para que tenga valores codificados, todo funciona bien, incluso si codifico el equivalente a lWebsiteName.

Respuestas a la pregunta(2)

Su respuesta a la pregunta