Редактировать: Я обновил код ниже, чтобы он теперь работал, благодаря ответу Роба.Как заполнить 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) Код выше не удалось во время бега пользовательского действия с «Функция не удалась во время выполнения. Database: Table (s) Update failed.» - Это из-за проблемы с индексацией, вызывающей код, чтобы попытаться написать строку в столбец int.
2) Если изменить линию
lRecord.SetString(2, lWebsiteName);
в
lRecord.SetString(2, lEntry.Name);
затем смотрит на след действие появляется, чтобы добиться успеха, но когда программа установки запустить выпадающий не имеет записей к выбрало от.
Если я изменил выпадающий список, чтобы иметь жестко заданные значения, все работает нормально, даже если я жестко задал эквивалент lWebsiteName.
так что установщик должен запускаться как администратор?или как избежать отказа в доступе при попытке получить список веб-сайтов? –
Он должен быть запущен как администратор. Наслаждайтесь решением этой проблемы. – jcmcbeth