如何使用 wix 将多个元素添加到 XML 配置文件中?

2024-03-30

我正在尝试使用 Wix 编辑 XML 文件。我正在使用与 Wix 3.7 捆绑在一起的 WixUtilExtension。 xml 文件是在 Visual Studio 2010 中为 C# 应用程序创建的设置文件。在此文件中,我使用一个用于在数组中存储多个字符串值的元素。这是未更改的设置文件的内容:

<configuration>
    <applicationSettings>
        <AppName.Properties.Settings>
            <setting name="StringArray" serializeAs="Xml">
                <value>
                    <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                    </ArrayOfString>
                </value>
            </setting>
        </AppName.Properties.Settings>
    </applicationSettings>
</configuration>

我想添加<string>元素到<ArrayOfString>该文件中的元素。做到这一点的一种方法是使用<XmlConfig>来自 wix/UtilExtension 命名空间的元素。我已将此元素添加到保存配置文件的组件中,如下所示:

<Component Id="ProductComponent" Guid="$(var.ConfigGuid)">
    <File Source="SettingsFile.exe.config" KeyPath="yes" Id="FILE_config" />
    <util:XmlConfig
      Name="string"
      Value="My value"
      File="[INSTALLFOLDER]SettingsFile.exe.config"
      Id="String1"
      On="install"
      Action="create"
      Node="element"
      ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
      Sequence="100"
      />
</Component>

这导致添加一个<string>元素到<ArrayOfString>元素。添加另一个<string>元素添加到设置文件中,另一个 XmlConfig 元素必须添加到<Component>设置项目的元素具有不同的 Id 属性和较高的 Sequence 属性值,如下所示:

<util:XmlConfig
    Name="string"
    Value="My second value"
    File="[INSTALLFOLDER]SettingsFile.exe.config"
    Id="String2"
    On="install"
    Action="create"
    Node="element"
    ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
    Sequence="101"
/>

安装完msi后,<ArrayOfString>设置文件中的元素如下所示:

<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>My value</string><string>My second value</string></ArrayOfString>

我发现可以设置一个值的属性<XmlConfig>attribute 为属性的值,如下所示:

<Property Id="STRING1VALUE" Value="My value" />
<util:XmlConfig Value="[STRING1VALUE]" ... />

这很好。我希望用户能够在安装过程中动态添加多个值,以便可变数量的<string>元素可以添加到设置文件中。 我的第一个方法是使用<?foreach?>像这样的声明:

<?define values="My value;My second value"?>
<?foreach value in $(var.values)?>
    <util:XmlConfig
        Name="string"
        Value="$(var.value)"
        File="[INSTALLFOLDER]SettingsFile.exe.config"
        Id="String$(var.value)"
        On="install"
        Action="create"
        Node="element"
        ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
        Sequence="101"
    />
<?endforeach?>

这种方法存在一些问题:

  1. foreach 语句使用无法设置为属性值的预处理器变量。
  2. Sequence 属性的值保持不变。

我希望用户将字符串元素的值存储在属性中,该属性用分号分隔值,然后在 foreach 语句中解析它们,如下所示:

<Property Id="VALUES" Value="My value;My second value" />
<?foreach value in [VALUES]?>
    <util:XmlConfig
        Name="string"
        Value="$(var.value)"
        File="[INSTALLFOLDER]SettingsFile.exe.config"
        Id="String$(var.value)"
        On="install"
        Action="create"
        Node="element"
        ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
        Sequence="101"
    />
<?endforeach?>

这会引发以下错误:

The util:XmlConfig/@Id attribute's value, 'String[VALUES]', is not a legal identifier. 
Identifiers may contain ASCII characters A-Z, a-z, digits, underscores (_), or periods (.). 
Every identifier must begin with either a letter or an underscore.

有什么方法可以使用 XmlFile 或 XmlConfig 元素创建可变数量的元素吗? CustomAction 是解决此问题的唯一方法吗?


根据 Rob 的回答,这是我使用 Wix 将多个元素添加到 XML 配置文件的新方法。我不想编写 C++ 代码,这就是我使用的原因DTF http://robmensching.com/blog/posts/2008/5/16/deployment-tools-foundation-joins-the-wix-toolset在我的自定义操作中。

我将描述如何使用分隔符将包含多个元素的字符串转换为多个 XML 元素。

首先,安装文件中需要有一个包含分隔字符串的属性。

<Property Id="STRINGARRAY" Value="string1;string2;string3" />

当然,该属性可以由用户在对话框中填充。

接下来,必须编写 CustomAction。要使用 DTF,必须将对 Microsoft.Deployment.WindowsInstaller.dll 的引用添加到 C# CustomAction 项目中。命名空间 Microsoft.Deployment.WindowsInstaller 应包含在该项目中的 using 指令中。我的自定义操作如下所示:

[CustomAction]
public static ActionResult Insert(Session session)
{
    string strings = session["STRINGARRAY"];
    string[] stringArray = strings.Split(';');
    Database db = session.Database;
    View view = db.OpenView("select * from `XmlConfig`");
    string xpath = "/configuration/applicationSettings/AppName.Properties.Settings/setting[\\[]@name='StringArray'[\\]]/value/ArrayOfString";
    for (int i = 0; i < stringArray.Length; i++)
    {
        string id = String.Format("String{0}", i);
        int sequence = 100 + i;
        string value = stringArray[i].Trim();
        Record rec = new Record(
            id,
            "[INSTALLFOLDER]SettingsFile.exe.config",
            xpath,
            null,
            "string",
            value,
            273,
            "ProductComponent",
            sequence);
        view.InsertTemporary(rec);
    }
    db.Close();
    return ActionResult.Success;
}

这里,首先将 Property StringArray 读入局部变量,然后将其转换为字符串数组。以下行建立与安装程序使用的当前数据库的连接。将创建表 XmlConfig 的句柄,该表是添加 XML 元素的表。要将正确的值插入到该表中,最好创建一个包含此类表的安装程序文件,然后在 orca 或 InstEd 等编辑器中查看该表。

在 xpath 中,必须使用双反斜杠转义反斜杠。 id 变量保存临时记录的名称,使用简单的字符串和数字可以完美地工作。每个元素的序列都必须递增。我找不到有关 flags 列的值的任何文档,但我发现对于创建的元素,其值设置为 273,对于删除的元素,其值设置为 289。

一旦记录填充了正确的值,就会使用视图对象的 InsertTemporary 方法将其添加到 XmlConfig 表中。这是针对分隔字符串中找到的每个元素执行的。

我遇到的一个问题是,如果 XmlConfig 表不存在,则此 CustomAction 会失败。为了解决这个问题,我在安装文件中添加了以下代码,该代码将一个元素添加到 XML 文件并立即删除该元素。我想可能有一种更清洁的解决方案,但这对我来说是最简单的。

<util:XmlConfig
    Name="string"
    Value="Dummy"
    File="[INSTALLFOLDER]SettingsFile.exe.config"
    Id="DummyEntry"
    On="install"
    Action="create"
    Node="element"
    ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
    Sequence="1" />
<util:XmlConfig
    On="install"
    Action="delete"
    Id="DeleteDummyEntry"
    Node="element"
    File="[INSTALLFOLDER]SettingsFile.exe.config"
    VerifyPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString/string"
    ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
    Sequence="2" />

最后,必须将 CustomAction 添加到安装项目中。通过在安装项目中添加对 CustomAction 项目的引用,可以像这样指定二进制文件的位置:

<Binary Id="XmlCustomActionDLL" SourceFile="$(var.XmlCustomAction.TargetDir)XmlCustomAction.CA.dll" />

CustomAction必须立即执行,否则将无法访问会话变量:

<CustomAction Id="CA_XmlCustomAction" BinaryKey="XmlCustomActionDLL" DllEntry="Insert" Execute="immediate" Return="check" />
<InstallExecuteSequence>
  <Custom Action="CA_XmlCustomAction" Before="RemoveRegistryValues" />
</InstallExecuteSequence>

为了确定 CustomAction 在安装顺序中的正确位置,我依靠本文 http://www.joyofsetup.com/2007/07/01/semi-custom-actions/作者:鲍勃·阿恩森。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 wix 将多个元素添加到 XML 配置文件中? 的相关文章

  • 尽管删除了 IIS,但仍然设置了 IISMAJORVERSION 和 IISMINORVERSION

    我正在创建一个依赖于正在安装的 IIS 的安装程序 为了进行测试 我使用运行 Windows Server 2008 R2 的虚拟机 该虚拟机安装了 Web 服务器角色 我的安装程序使用此条件检查是否安装了 IIS
  • Windows 服务中使用 App.Config 的 WCF 命名管道

    我烦了 好的 这是错误 net pipe localhost MyIpcAppToService 上没有侦听端点可以接受该消息 这通常是由不正确的地址或 SOAP 操作引起的 有关更多详细信息 请参阅 InnerException 如果存在
  • 在 WiX 中重新启动后继续安装

    我正在尝试使用 WixStandardBootstrapperApplication 创建引导应用程序 除了处理重启之外 它可以很好地完成我需要它做的所有事情 我需要安装一组EXE文件 只有第一个是 NET 4 5 需要重新启动 我会延迟重
  • 在多个环境中执行编码的 UI 测试

    现在 我的编码 UI 测试使用它们的 app config 来确定它们执行的域 该域与环境具有 1 1 关系 为了简化它 测试网 www UAT com www prod com 在 App config 中我有类似的内容
  • 从 WiX 提升的安装程序运行未提升的自定义操作

    我正在尝试弄清楚如何从提升的 WiX 安装设置程序运行自定义操作 WiX 生成的 msi 文件由 DotNetInstaller 执行 在 WiX 中 我有一个 Package 部分 其中 InstallScope 设置为 perMachi
  • 以提升用户身份在 wix 中运行 CustomAction

    据我所知 WiX 支持两种 CustomActions 延迟 运行此操作的用户 默认情况下 被提升 但它不是运行安装的用户 例如 LocalSystem 或类似的用户 立即 运行此操作的用户 默认情况下 未提升 这是首先运行安装程序的用户
  • .NET 配置节设计器 - 我的集合在哪里?

    我正在使用配置部分设计器 http csd codeplex com 为 NET构建一个简单的ConfigurationElementCollection It appears一切都构建得很好 并且代码是自动生成的 因为子元素通过 Inte
  • 从流而不是文件加载配置文件

    我使用 OpenMappedExeConfiguration 和 ExeConfigurationFileMap 来加载配置文件 它们的重载表明它们只适用于文件名 有没有办法从流加载配置文件 背景 我想加载存储为嵌入式资源的配置文件 没有文
  • Jquery Draggables:删除元素会更改其他删除元素的位置

    当放置 放置元素 通过从一个 DIV 拖动到另一个 DIV 然后删除放置的 DIV 中的一个元素时 其中一些元素会更改位置 这是一个测试场景 http jsfiddle net TcYHW 8 http jsfiddle net TcYHW
  • 当自动为 WIX 安装程序收集文件时,我的目录结构有多灵活?

    请原谅我的无知 我一直在阅读一些书 但还没有准备好尝试任何东西 目前 我们有一个 wxs 文件 该文件无法轻松维护 每当从 SVN 提交 删除新文件时 都会手动添加 删除所有文件 由于在创建新文件和更新 wxs 安装文件之间发生了失误 我们
  • 两个列表中的公共元素

    我有两个ArrayList每个对象都有三个整数 我想找到一种方法来返回两个列表的共同元素 有人知道我该如何实现这一目标吗 Use Collection retainAll https docs oracle com en java java
  • 每个配置文件中的部分只能出现一次!为什么?

    我收到以下异常 每个配置文件中的部分只能出现一次 有关例外情况 请参阅帮助主题 我的配置文件看起来像这样
  • 从通过单元测试项目调用的类库访问 App.Config 设置

    我有以下设置 ASP net 3 5 网站项目 具有业务逻辑的 C 类库 用于单元测试的 C 类库 业务逻辑库完成所有数据库访问 它通过访问 System Configuration ConfigurationManager Connect
  • 使用帮助库管理器和 WiX 安装帮助

    我试图通过使用 WiX 运行 Sandcastle 帮助文件生成器在构建我的 Sandcastle 项目后创建的 HelpLibraryManagerLauncher 将我自己的帮助文件添加到 Visual Studio 2010 的帮助库
  • 与 WiX 3.0 一起安装 WiX 3.5

    是否可以同时安装 WiX 3 0 和 3 5 如果我在安装 3 0 后安装 3 5 它会删除 3 0 文件 如果我尝试在 3 5 之后安装 3 0 它会告诉我已经安装了较新的版本 我正在从 VS 2008 迁移到 VS 2010 因此我的应
  • 对其他元素值的 XSD 限制

    是否可以在 XSD 文档中对其他元素值进行限制 例如 我有国家和州元素 如果国家 地区等于美国 那么我需要限制指定枚举的状态元素值 否则状态可以只是固定长度的字符串 当前 XSD 的示例 始终将状态限制为枚举
  • c# 错误:无法识别的配置部分 userSettings - 停止程序读取 user.config?

    在我的 C 表单应用程序 在 VS2010 中使用 NET 4 0 创建 中 我使用应用程序设置来存储输出路径 以前此设置是使用用户范围配置的 但我必须将其范围更改为应用程序 执行此操作后 我现在在表单启动时收到无法识别的配置部分 user
  • 在wix中添加文件夹到安装程序而不是文件?

    我的安装程序必须将文件复制到 installdir 我的应用程序有大约 2000 个文件 我不可能编写脚本将每个文件添加到安装程序中 wix中是否有任何选项可以让我一次添加所有文件或包含文件的整个文件夹 我是 wix 新手 我在任何教程中都
  • 使用 元素通过 Wix 运行 SQL 脚本文件

    我是 Wix 安装程序的新手 我有一个要求 必须提供 SQL Server 登录凭据并从特定路径运行脚本 我不明白出了什么问题 项目已成功构建并创建了 msi 运行后我收到以下错误 错误26204 错误 2147217900 无法执行SQL
  • WiX - 通过检查修订来防止降级

    我正在寻找一种方法来防止我的应用程序降级 但 问题 是 我必须检查修订号 例如 安装 1 0 0 1 时应该可以安装 1 0 0 2 但安装 1 0 0 2 时不应该安装 1 0 0 1 我知道 Element MajorUpgrade 仅

随机推荐