在InstallScript中更新.config XML

时间:2011-09-01 11:10:12

标签: xml installshield installscript basic-msi

我正在尝试编写一个简短的安装脚本来更新XML文件中的值(myplatforinfo.config)。

我可耻地偷了[这篇关于类似任务的帖子]的代码{http://stackoverflow.com/questions/4129633/how-to-update-attributes-in-an-xml-file-with-installscript} ,但是已经根据我的需要进行了黑客攻击。

/// <summary>
/// This function reads in the fddId.config and alters the number associated
/// with the serial number fo the installed package.
/// <summary>
function UpdateDeviceFirmwareVersion(hMSI)
    OBJECT oDoc;       
    STRING sConfigFilePath;   
    BOOL successfulLoad;
    NUMBER retVal;
begin   
    sConfigFilePath = "C:\\myplatforinfo.config"; 
    retVal = 0;

    if (Is(FILE_EXISTS, sConfigFilePath)) = FALSE then
        MessageBox("Could not find fddId file.", 0);
        retVal = -1;
    endif;

    // get values from public properties
    set oDoc = CreateObject("Msxml2.DOMDocument.4.0");  
    if (!IsObject(oDoc)) then
        MessageBox("Could not create XML Document", 0);
        retVal = -1;
    endif;     

    oDoc.async = FALSE;  
    oDoc.setProperty("SelectionLanguage", "XPath");

    successfulLoad = oDoc.load(sConfigFilePath);
    if (successfulLoad < 0) then
        MessageBox("Could not load the fddId as an xml file", SEVERE);
        retVal = -1;                
    endif;

    if (retVal = -1) then
        return retVal;
        abort;
    endif;

    ReplaceValueOf(oDoc, "//platformID/SerialNumber/version", "1");

    oDoc.save(sConfigFilePath);
    set oDoc = NOTHING;
end;   


function ReplaceValueOf(oDoc, xPath, valueToPutIn)
    OBJECT oNode;
begin
    set oNode = oDoc.selectNodes(xPath)(0);
    try
        oNode.attributes.getNamedItem("value").value = valueToPutIn;
    catch 
        MessageBox("Could not set '" + xPath + "' with '" + valueToPutIn + "'", SEVERE);
    endcatch;  
end;  

然而,在负载方法上,需要帮助!:

successfulLoad = oDoc.load(sConfigFilePath);
if (successfulLoad < 0) then
MessageBox("Could not load the fddId as an xml file", SEVERE);
retVal = -1;                
endif;

我不确定为什么。此文件是一个有效的XML文件,它由使用它的.Net代码处理。下面我已经包含了XML配置文件的简化版本。只是标题和使用的标签,但结构是相同的。它有注释,这会影响InstallShield解析器吗?

<?xml version="1.0" encoding="utf-8"?>
<platformIDxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <type>35</type>
  <manufacturer>14</manufacturer>
  <SerialNumber>
    <version>2</version>
  </SerialNumber>
</platformID>

我只是在短时间内与InstallShield 2011作斗争,但我正在快速学会喜欢它的强大功能,并且讨厌它的开发支持和缺乏清晰的用户界面。欢迎任何帮助:)。

编辑:正如Michael Urman已经指出我没有正确处理XML文档加载中的布尔返回。我做了这个编辑,我的脚本现在已经到了'getNamedItem'并设置了值。

这可能是因为我想设置的字段不是命名的“value”属性吗?我的元素没有任何属性,但我怀疑元素的值是一个名为'value'的属性,lol。我猜错了吗?

进一步编辑!!不,它不是上面的那个...我已经尝试了node.Value和命名元素路由,两种方式调试器都在'setter'行崩溃了新值。想想我可能只需要使用内置函数。

2 个答案:

答案 0 :(得分:2)

我认为您的负载检查不正确。 DOMDocument.load方法的返回值是boolean,而不是hresult。因此,不是负值是失败,只有零值是失败。如果您将突出显示的代码摘录与您引用的问题上的代码进行比较,则会看到其他代码使用if !successfulLoad代替。

但是我们也要澄清一些事情。当你从CreateObject调用对一个对象进行操作时,你真的要用COM而不是InstallScript,除非它是阻止你做某事的语言方。

其次,如果单个ReplaceValueOf调用是您需要对此文件进行的唯一更改,并且您知道该文件的位置(或将是),则使用内置XML文件更改可能会更容易支持。通过创建具有这些名称的三个层次结构元素来设置其XPath以引用//platformID/SerialNumber/version,并将version元素的节点文本设置为1

最新版本的InstallShield可以很好地处理这方面的小改动,只是在订购方面遇到问题,而且批量更改也类似。如果缩进和其他此类更改导致问题,您也可以禁用它。

答案 1 :(得分:0)

如果我更改了将功能ReplaceValueOf中的xml元素文本设置为oNode.text = valueToPutIn;的代码,则以上代码对我有用

我还需要将创建对象更改为使用6.0版本: CreateObject("Msxml2.DOMDocument.6.0");