2009-09-03 5 views
5

Edit: Ich habe den Code unten aktualisiert, so dass es jetzt funktioniert, dank Robs Antwort.Wie bearbeite ich eine ComboBox zur Installationszeit in WiX?

Ich habe ein paar Seiten gefunden, die zeigen, wie dies zu tun (http://www.cmcrossroads.com/content/view/13160/120/, http://www.mail-archive.com/[email protected]/msg05103.html) und sah durch den Quellcode für WAI (http://wai.codeplex.com/), aber ich kann nicht scheinen, um es in meinem Installateur zur Arbeit zu kommen egal was ich versuche. Wenn jemand herausfinden könnte, was ich falsch mache, wäre ich sehr dankbar. Mein WiX-Fragment für den Dialog sieht wie folgt 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 Code für benutzerdefinierte Aktion ist:

[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 sein:

1) Der obige Code während des Laufens ist fehlgeschlagen der benutzerdefinierten Aktion mit "Funktion während der Ausführung fehlgeschlagen. Datenbank: Tabelle (s) Aktualisierung fehlgeschlagen." - Dies geschah aufgrund des Indexierungsproblems, das den Code veranlasste, eine Zeichenfolge in eine int-Spalte zu schreiben.

2) Wenn ich die Zeile

lRecord.SetString(2, lWebsiteName); 

zu

lRecord.SetString(2, lEntry.Name); 

dann auf Spur sucht die Aktion scheint erfolgreich zu sein, aber, wenn das Installationsprogramm von der Combobox hat keine Einträge zu wählen.

Wenn ich die Combobox ändern, um fest codierte Werte zu haben, funktioniert alles gut, auch wenn ich das Äquivalent von lWebsiteName fest codiere.

+0

so muss das Installationsprogramm als Administrator ausgeführt werden?oder wie vermeide ich den Zugriff, der verweigert wird, wenn ich versuche, Liste der Web site zu erhalten? –

+0

Es muss als Administrator ausgeführt werden. Viel Spaß beim Lösen dieses Problems. – jcmcbeth

Antwort

3

Ich verwende nicht DTF (alle natürlichen C++ - CustomActions für mich), aber Record's sind 1 basiert. Haben Sie versucht, alle Ihre SetRecord() - Aufrufe um einen Index zu verschieben?

Darüber hinaus scheint der .wxs-Code oben darauf hinzuweisen, dass Sie "DUMMYPROPERTY" als Steuerelementeigenschaft für die ComboBox nicht "IIS_WEBSITENAME" verwenden, wie der .cs-Code verwendet.

+0

Danke, ich habe es irgendwann einmal versucht, aber ich habe so viele Dinge ausprobiert, die ich mit diesem Code vielleicht nicht gemacht habe! Ich werde es wieder versuchen. Ich benutze DUMMYPROPERTY im zweiten, versteckten Combo-Steuerelement, um sicherzustellen, dass die ComboBox-Tabelle erstellt wird, ich werde versuchen, es auf die gleiche Eigenschaft wie das echte Steuerelement zeigen und sehen, ob das irgendwas tut. – Dan

+0

Es war die Indizierung (die beide Probleme erklärte). Danke noch einmal. – Dan

0

Dieser ist ziemlich alt, aber ich hatte ähnliches Problem und möchte teilen, was ich gefunden habe, vielleicht spart dies jemand Zeit.

sicher ComboBox Tisch zu machen, ist die Verwendung EnsureTable erstellt, sicherzustellen, CA überschreibt nicht definierten Wert:

<EnsureTable Id="ComboBox"/> 
<Property Id="RS_INSTANCES" Secure="yes"/> 
<CustomAction Id="GetRSintances" BinaryKey="JSCommon" Return="ignore" 
       JScriptCall="GetRSintances" Execute="immediate" /> 

<InstallUISequence> 
    <Custom Action="GetRSintances" After="AppSearch"> 
    <![CDATA[NOT Installed AND NOT RS_INSTANCES]]> 
    </Custom> 
</InstallUISequence> 

<InstallExecuteSequence> 
    <Custom Action="GetRSintances" After="AppSearch"> 
    <![CDATA[NOT Installed AND NOT RS_INSTANCES]]> 
    </Custom> 
</InstallExecuteSequence> 

<!-- UI part --> 
<Control Id="ComboBox1" Type="ComboBox" X="20" Y="160" Width="100" Height="20" Property="RS_INSTANCES" Sorted="yes" > 
    <ComboBox Property="RS_INSTANCES"> 
     <!-- dynamicly filled during installation --> 
    </ComboBox> 
    </Control> 

Ich habe eine JavaScript-Funktion Listitem für die Befüllung: (ja, ich weiß, einige von Ihnen don‘ t wie JS für benutzerdefinierte Aktionen, aber es ist immer noch bequem genug)

// Add ListItem to ComboBox or ListView at install time 
function AddListItemToMSI(Property, Order, Value, Text, Table) { 
    try { 
    var controlView = Session.Database.OpenView("SELECT * FROM " + Table); 
    controlView.Execute(); 

    var record = Session.Installer.CreateRecord(4); 
    record.StringData(1) = Property; 
    record.IntegerData(2) = Order; 
    record.StringData(3) = Value; 
    record.StringData(4) = Text; 

    controlView.Modify(7, record); 
    controlView.Close(); 
    } 
    catch (err) { 
    ShowMessage('Couldn\'t add ListItem entry, error occured: ' + err.message, msiMessageTypeInfo); 
    } 

    return 1; 
} 

ich es von meiner anderen Funktion aufrufen (es als benutzerdefinierte Aktion) wie folgt aufgerufen wird:

var ComboBoxProperty = 'RS_INSTANCES'; 
var InstanceFullName; 
for (i = 0; i < Names.length; i++) { 
    InstanceFullName = GetInstanceName(Names[i]); //this function looks up full name in the registry 
    AddListItemToMSI(ComboBoxProperty, i, InstanceFullName, '', 'ComboBox'); 
    if (i == 0) { 
     Session.Property(ComboBoxProperty) = InstanceFullName; 
    } 
} 

HINWEIS: Ich entfernte nicht relevante Teile des Codes aus der letzten Funktion, um es lesbar zu machen. P.S. immer (ich meine IMMER) verwenden null, null Länge und Fehlerprüfung, versuchen/fangen und sicherstellen, dass die Anmeldung mit etwas wie folgt:

function ShowMessage(text, options) { 
    if (options == null) { 
     var options = msiMessageTypeUser; 
    } 
    var oRecord = Session.Installer.CreateRecord(1); 
    oRecord.StringData(1) = text; 
    var response = Session.Message(options, oRecord); 
    oRecord.ClearData(); 
    oRecord = null; 
    response = null; 
} 
Verwandte Themen