zim*_*nen 5 combobox windows-installer wix
在我的一个对话框中,我有以下控件:
<Control Id="EnvironmentComboBox" Type="ComboBox" Sorted="yes" ComboList="yes" Property="ENVIRONMENT" X="25" Y="110" Width="200" Height="15" />
Run Code Online (Sandbox Code Playgroud)
我在其他地方填写ComboBox如下:
<UI>
<ComboBox Property="ENVIRONMENT">
<ListItem Text="Development" Value="Development" />
<ListItem Text="SIT" Value="SIT" />
<ListItem Text="UAT" Value="UAT" />
<ListItem Text="Production" Value="Production" />
</ComboBox>
</UI>
Run Code Online (Sandbox Code Playgroud)
但是,如果我没有创建ComboBox位,MSI仍将构建,并且在安装期间它将失败(2205).因此,我想强制要求拥有一个名为ENVIRONMENT的属性.我试过在我的对话框中添加如下所示的PropertyRef:
<PropertyRef Id="ENVIRONMENT" />
Run Code Online (Sandbox Code Playgroud)
但是,这似乎没有好转<ComboBox Proeprty="ENVIRONMENT">.它将获取一个常规属性(<Property Id="ENVIRONMENT" Value="test" />),但这并没有多大帮助.
有没有办法要求ComboBox定义?
编辑: 为了澄清,我打算将ComboBox定义与Control定义分开,以便可以重用该对话框.
MSI 可以在没有为属性声明的 Combobox 项的情况下存在,并由元素引用(如果 ComboList='no',您可以在组合框文本字段中键入所需的任何文本)。
*该元素在 MSI 表中没有任何对应的对象*(只有它的子元素被写入 MSI 的 ComboBox 表)。所以我认为从 WIX 的角度来看这个元素是完全可选的。
您的错误 #2205 是由根本不存在“ComboBox”表引起的。我想你的安装程序中只有一个组合框。理论上,不可能在编译时将其检测为错误(也可以在自定义操作中创建表)。WIX 团队最多能做的就是生成警告。
为了避免此错误,我在可重用项目中声明了一个虚拟组合框元素:
<Fragment><!--This fragment is intended to fill MSI tables with dummy items so that these tables became created. Tables without items aren't created-->
<UI Id="Dummy">
<Dialog Id="DummyDlg" Width="370" Height="270" Title="Dummy" NoMinimize="yes">
<Control Id="DummyDlgComboBox" Type="ComboBox" Property="DummyComboboxProperty" Width="200" Height="17" X="100" Y="80">
<ComboBox Property="DummyComboboxProperty">
<ListItem Text="Dummy" Value="Dummy" />
</ComboBox>
</Control>
</Dialog>
</UI>
</Fragment>
Run Code Online (Sandbox Code Playgroud)
并从我常用的 UI 序列中引用了此 UI。
现在我不需要担心任何安装程序中是否存在组合框表。
至于解决您的问题的方法- 如何强制用户不要忘记声明列表项,我会做一个tepmlate wix 文件而不是 wixlib。像这样的东西:
<Control Id="EnvironmentComboBox" Type="ComboBox" Sorted="yes" ComboList="yes" Property="ENVIRONMENT" X="25" Y="110" Width="200" Height="15">
<ComboBox Property="ENVIRONMENT">
<Placeholder Id="EnvironmentComboBoxItems" />
</ComboBox>
</Combobox>
Run Code Online (Sandbox Code Playgroud)
并为用户提供使用您提供的模板转换工具重用此代码的唯一能力。它将验证所有模板占位符是否都提供了内容。
转换可能如下所示:
<TemplateSubstitutions>
<PlaceholderContent PlaceholderId='EnvironmentComboBoxItems'>
<ListItem Text="Development" Value="Development" />
<ListItem Text="SIT" Value="SIT" />
<ListItem Text="UAT" Value="UAT" />
<ListItem Text="Production" Value="Production" />
</PlaceholderContent>
</TemplateSubstitutions>
Run Code Online (Sandbox Code Playgroud)
合并它们的工具:
static void Main(string[] args)
{
var templatePath = args[0];
var templateTransformPath = args[1];
var resultPath = args[2];
var templateDoc = XDocument.Load(templatePath);
var transformationDoc = XDocument.Parse(templateTransformPath);
Dictionary<string, XElement> contents = transformationDoc.Element("TemplateSubstitutions").Elements("PlaceholderContent").ToDictionary(e => e.Attribute("PlaceholderId").Value, e => e);
var planceHolders = templateDoc.Descendants("Placeholder").ToArray();
foreach (var ph in planceHolders)
{
ph.ReplaceWith(new XElement(contents[ph.Attribute("Id").Value]).Nodes());
}
templateDoc.Save(resultPath);
}
Run Code Online (Sandbox Code Playgroud)
当然,这个工具尚未发布 - 您可能希望向您的客户端添加一些有意义的错误消息并验证所提供的转换。但为了避免代码复杂化,我没有实现它。
我在目前的几个安装程序项目中使用了这种方法。所有模板都存储在公共位置,客户端安装程序可以获取他们需要的任何文件并对其进行转换。
当然,我的发布工具更先进一些。它可以使用通配符替换属性中的值 - 我认为它在重用组件时非常有用。我使用这样的模板:
<Component Guid="{StrToGuid({ProductName}_7A51C3FD-CBE9-4EB1-8739-A8F45D46DCF5)}">
Run Code Online (Sandbox Code Playgroud)
用户应该在我的模板转换工具的命令行中提供所有模板属性(例如“ProductName”)。它确保组件在不同产品之间具有唯一的 GUID,因此它们在安装在同一台计算机上时不会发生冲突。
注意:请注意数字括号- 它们对于 WIX 和 MSI 有特殊含义:http://msdn.microsoft.com/library/aa368609.aspx。但对我来说还不够清楚,而且我不经常使用它们。但您可能需要另一个通配符前缀。
至于组织安装程序构建过程,您可以在项目的预构建中添加模板转换调用。但我决定使用单独的构建脚本而不是本机 Visual Studio 构建。它看起来更加简单和灵活。而且我不会遇到像“命令‘xxx’以代码 yyy 退出”这样令人讨厌的错误 - 我总是看到模板转换日志、错误消息等。
希望我对轮子的重新发明能帮助任何人 =)。
| 归档时间: |
|
| 查看次数: |
1110 次 |
| 最近记录: |