0

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

我可耻地从 [this post on a similar task]{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 斗争了很短的时间,但我很快就学会了喜欢它的功能,讨厌它的开发支持和缺乏清晰的 UI。欢迎任何帮助:)。

编辑:正如 Michael Urman 所指出的那样,我没有正确处理来自我的 XML 文档加载的布尔返回。我已经进行了这个编辑,我的脚本现在已经到了“getNamedItem”并设置了值。

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

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

4

2 回答 2

2

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

但让我们也澄清一些事情。当您通过 CreateObject 调用对对象进行操作时,您实际上是在使用 COM 而不是 InstallScript,除非是语言方面阻止您做某事。

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

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

于 2011-09-01T12:23:00.453 回答
0

如果我更改代码以将函数中的 xml 元素文本设置ReplaceValueOfoNode.text = valueToPutIn;

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

于 2020-10-21T10:04:06.137 回答