Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用wix将多个元素添加到XML配置文件中?_Wix_App Config_Elements - Fatal编程技术网

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

如何使用wix将多个元素添加到XML配置文件中?,wix,app-config,elements,Wix,App Config,Elements,我正在尝试用Wix编辑一个XML文件。我正在使用WIX3.7附带的WixUtil扩展。xml文件是在Visual Studio 2010中为C应用程序创建的设置文件。在这个文件中,我使用了一个元素,用于在数组中存储多个字符串值。这是未更改设置文件的内容: <configuration> <applicationSettings> <AppName.Properties.Settings> <setting

我正在尝试用Wix编辑一个XML文件。我正在使用WIX3.7附带的WixUtil扩展。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>

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

是的,这是可能的,但如果您希望在安装时确定这一点,则预处理器不是一个选项。预处理器在构建过程中执行


要获得所需的内容,需要编写另一个自定义操作,该操作将获取任意长的用户数据集,并将临时行添加到XmlConfig表中。src\ca\wcautil\wcawrap.cpp中的WcaAddTempRecord函数可以完成这项工作。src\ca\wixca\dll\RemoveFoldersEx.cpp是使用WcaAddTempRecord向RemoveFile表添加行的一个很好的示例。您也可以这样做。

根据Rob的回答,下面是我使用Wix向XML配置文件添加多个元素的新方法。我不想写C++代码,这就是我在自定义中使用的原因。 我将描述如何使用分隔符将包含多个元素的字符串转换为多个XML元素

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

<Property Id="STRINGARRAY" Value="string1;string2;string3" />
当然,该属性可以由用户在对话框中填充

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

[海关行动] 公共静态ActionResult插入会话 { 字符串=会话[STRINGARRAY]; string[]stringArray=strings.Split';'; Database db=session.Database; View=db.OpenViewselect*from`XmlConfig`; 字符串xpath=/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\\]]/value/ArrayOfString; 对于int i=0;i 在xpath中,必须使用双反斜杠来转义反斜杠。id变量保存临时记录的名称,使用一个简单的字符串和一个数字可以完美地工作。对于每个元素,序列必须递增。我找不到任何关于flags列值的文档,但我发现它的值对于创建的元素设置为273,对于删除的元素设置为289

一旦记录中填充了正确的值,就可以使用view对象的InsertTemporary方法将其添加到XmlConfig表中。这是为在分隔字符串中找到的每个元素完成的

<Property Id="STRINGARRAY" Value="string1;string2;string3" />
我遇到的一个问题是,如果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项目的引用,可以如下指定二进制文件的位置:

<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>
<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"
/>
<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>
<Property Id="STRING1VALUE" Value="My value" />
<util:XmlConfig Value="[STRING1VALUE]" ... />
<?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?>
<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?>
<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在安装序列中的正确位置,我依赖于Bob Arnson。

我建议不要使用整个虚拟的XmlConfig条目,而只使用可确保的条目XML,这样可以确保XmlConfig表包含在输出MSI中,即使它是空的。