【问题标题】:How to optionally pass a public property to an MSI from a Bundle如何有选择地将公共属性从 Bundle 传递给 MSI
【发布时间】:2016-08-02 23:29:31
【问题描述】:

我需要选择性地将 Bundle 命令行参数传递给 MSI。也就是说,如果它在 Bundle 命令行中指定,则将值传递给 MSI,否则将其设置为默认的 DEFINED IN THE MSI。

为了将属性传递给 MSI,您需要使用:

<MsiProperty Name='PUBLICPROPERTY' Value='[BundleParameter]'/>

要声明一个捆绑变量,你需要这个:

<Variable Name="BundleParameter" bal:Overridable="yes" Type="string" Value="SomeValue"/>   

结果是 PUBLICPROPERTY 始终设置为一个值。 “SomeValue”的默认值或在捆绑命令行中传递的值。

如何有条件地通过 MsiProperty?

【问题讨论】:

    标签: wix burn


    【解决方案1】:

    我检查了 WiX Github,看起来今天不可能。在 BURN 中定义 MsiProperty 后,无论该值是否为空,都会设置该值并将其传递给 MSI。这是代码的快照:

    extern "C" HRESULT MsiEngineParsePropertiesFromXml(
        __in IXMLDOMNode* pixnPackage,
        __out BURN_MSIPROPERTY** prgProperties,
        __out DWORD* pcProperties
        )
    {
        HRESULT hr = S_OK;
        IXMLDOMNodeList* pixnNodes = NULL;
        IXMLDOMNode* pixnNode = NULL;
        DWORD cNodes = 0;
    
        BURN_MSIPROPERTY* pProperties = NULL;
    
        // select property nodes
        hr = XmlSelectNodes(pixnPackage, L"MsiProperty", &pixnNodes);
        ExitOnFailure(hr, "Failed to select property nodes.");
    
        // get property node count
        hr = pixnNodes->get_length((long*)&cNodes);
        ExitOnFailure(hr, "Failed to get property node count.");
    
        if (cNodes)
        {
            // allocate memory for properties
            pProperties = (BURN_MSIPROPERTY*)MemAlloc(sizeof(BURN_MSIPROPERTY) * cNodes, TRUE);
            ExitOnNull(pProperties, hr, E_OUTOFMEMORY, "Failed to allocate memory for MSI property structs.");
    
            // parse property elements
            for (DWORD i = 0; i < cNodes; ++i)
            {
                BURN_MSIPROPERTY* pProperty = &pProperties[i];
    
                hr = XmlNextElement(pixnNodes, &pixnNode, NULL);
                ExitOnFailure(hr, "Failed to get next node.");
    
                // @Id
                hr = XmlGetAttributeEx(pixnNode, L"Id", &pProperty->sczId);
                ExitOnFailure(hr, "Failed to get @Id.");
    
                // @Value
                hr = XmlGetAttributeEx(pixnNode, L"Value", &pProperty->sczValue);
                ExitOnFailure(hr, "Failed to get @Value.");
    
                // @RollbackValue
                hr = XmlGetAttributeEx(pixnNode, L"RollbackValue", &pProperty->sczRollbackValue);
                if (E_NOTFOUND != hr)
                {
                    ExitOnFailure(hr, "Failed to get @RollbackValue.");
                }
    
                // prepare next iteration
                ReleaseNullObject(pixnNode);
            }
        }
    

    看起来这将是 WiX4.0 中的一项新功能,正如 HERE 提到的那样

    话虽如此,如果您是该 MSI 的作者,那么您可以检查您的 MSI (.wxs) 文件中的属性值,如果它出现“空”,请使用 SetProperty 将其设置为不同的值.

    【讨论】:

      【解决方案2】:

      我不知道,如果有更好的选择,但你可以添加 2 个 MsiPackages 到链中,它们将安装相同的包,但一个带有 MsiProperty 和另一个没有定义 MsiProperty。这种方法的优点是您可以在 MsiPackage 上设置 InstallCondition,但不能在 MsiProperty 上设置。

      【讨论】:

        【解决方案3】:

        也许您可以在烧录包中为 MsiPackage 创建两个条目,每个条目具有相反的安装条件。 IE。如果属性填写,则运行一个,否则,运行另一个?有点hacky,但我不知道任何其他方式。不确定这将如何影响卸载部分。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-07
          • 2021-01-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-20
          • 2012-10-22
          • 2016-06-07
          相关资源
          最近更新 更多