>我有一个名为App.xml的文件,它包含在我的安装程序(将安装在客户端计算机上(中,我想从中加载数据并将其显示给用户,以便他可以操作将要安装的内容/如何使用系统。
我尝试使用Xml Files扩展名/自定义操作,在线检查,找不到加载安装程序中嵌入的源文件的方法。
我的文件是:<App> <Text>bla bla</text></App>
我希望安装程序显示"bla bla"文本,用户可以更改它,以后可以像往常一样通过扩展程序保存。
谢谢!
我遇到了类似的问题。在安装文件之前,挖掘允许您在安装UISequence期间使用XML文件的解决方案,看起来您需要将自定义表添加到WiX定义中,如此处所述。
基本上,您在 .wxs 文件中创建一个 CustomTable 元素,例如:
<CustomTable Id="App">
<Text>bla bla</Text>
</CustomTable>
然后,可以通过创建 View 查询来查找所需属性,从而在 c# 自定义操作中读取它:
using (View view = session.Database.OpenView("SELECT 'Text' FROM 'App'"))
{
view.Execute();
// access view properties and turn them into some object you want to manipulate
}
我承认对该视图对象将具有什么有些无知,但我知道您可以遍历其记录或抓取单个列,在属性中四处寻找最终应该会找到您想要的值。 下一步是用值填充组合框元素
<Control Id="DropdownSelectLabel" Type="Text" X="50" Y="65" Width="200" Height="15" TabSkip="no" Text="&Select a value:">
</Control>
<Control Id="DropdownSelect" Type="ComboBox" Height="16" Width="200" X="60" Y="80" Property="MY_PROPERTY_KEY" ComboList="yes">
<ComboBox Property="MY_PROPERTY_KEY">
<!-- Optional prepopulate value-->
<ListItem Text="[dummy_text]" Value="[dummy_value]" />
</ComboBox>
</Control>
我正在使用在安装UISequence期间运行的自定义c#操作填充它,该操作是通过Visual Studio构建
的<!-- Custom action for populating the combobox -->
<CustomAction Id="CA_PopulateComboBox" BinaryKey="BIN_CustomActions" DllEntry="PopulateComboBox" Execute="firstSequence" />
<!-- Binaries for the custom action -->
<Binary Id="BIN_CustomActions" SourceFile="..PATH-TO-YOUR-CUSTOM-ACTION-BIN-RELEASE.CA.dll" />
<!-- Schedule the custom action -->
<InstallUISequence>
<Custom Action="CA_PopulateComboBox" Before="LaunchConditions" />
</InstallUISequence>
自定义操作如下所示:
public class CustomActions
{
/// <summary>
/// Populates the ComboBox UI Element.
/// </summary>
/// <param name="session">The session.</param>
[CustomAction]
public static void PopulateComboBox(Session session)
{
session.Log("Populating the combobox with certificates");
// Clear the combobox (unecessary if it starting empty)
View view = session.Database.OpenView("DELETE FROM ComboBox WHERE ComboBox.Property='MY_PROPERTY_KEY'");
view.Execute();
view = session.Database.OpenView("SELECT * FROM ComboBox");
view.Execute();
List<ComboBoxRecordWrapper> valuesToAdd = PopulateValuesObjects(session); // Add the logic to read your xml values from the session object here
var index = 1;
foreach (ComboBoxRecordWrapper valueObject in valuesToAdd)
{
session.Log($"Adding value to the combobox: {valueObject.Text} - {valueObject.Value} {Environment.NewLine}Order: {valueObject.Order}");
view.Modify(ViewModifyMode.InsertTemporary, recordWrapper.ToRecord());
view.Execute();
index++;
}
view.Close();
}
}
/// <summary>
/// Class ComboBoxRecordWrapper. Wraps objects that should be represented in a combobox element in the installer
/// </summary>
public class ComboBoxRecordWrapper
{
/// <summary>
/// Gets or sets the property that this element's value will be stored as if the element is selected
/// </summary>
/// <value>The property.</value>
public string Property { get; set; }
/// <summary>
/// Gets or sets the order that this element appears in the combobox
/// </summary>
/// <value>The order.</value>
public int Order { get; set; }
/// <summary>
/// Gets or sets the value of the combobox option. This is what will be available to the UI element as a returned value
/// </summary>
/// <value>The value.</value>
public string Value { get; set; }
/// <summary>
/// Gets or sets the text that will be displayed for this element
/// </summary>
/// <value>The text.</value>
public string Text { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ComboBoxRecordWrapper"/> class.
/// </summary>
/// <param name="property">The property.</param>
/// <param name="order">The order.</param>
/// <param name="value">The value.</param>
/// <param name="text">The text.</param>
public ComboBoxRecordWrapper(string property, int order, string value, string text)
{
this.Property = property;
this.Order = order;
this.Value = value;
this.Text = string.IsNullOrEmpty(text) ? value : text;
}
/// <summary>
/// Converts to a record to add to the MSI database.
/// </summary>
/// <returns>Record.</returns>
public Record ToRecord()
{
var record = new Record(4);
record.SetString(1, this.Property);
record.SetInteger(2, this.Order);
record.SetString(3, this.Value);
record.SetString(4, this.Text);
return record;
}
}
这将是您必须通过自定义操作提供的自定义功能。从高级设计中,我看到您在命令行上传入 xml 文件的路径。在运行时,自定义操作将读取文件中的节点,并设置文本框正在使用的相应属性。