Domanda

I am attempting to write a short install script to update a value in an XML file (myplatforinfo.config).

I shamefully stole the code from [this post on a similar task]{http://stackoverflow.com/questions/4129633/how-to-update-attributes-in-an-xml-file-with-installscript}, but have hacked it for my needs.

/// <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;  

It is however falling over on the load method, need help!:

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

I am not sure why. This file is a valid XML file and it handled ok by the .Net code that uses it. Below I have included a simplified version of the XML config file. Just the header and the tags that are used, but the structure is identical. It has comments in it, could this effect the InstallShield parser?

<?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>

I have only been battling with InstallShield 2011 for a short time, but I am fast learning to love it's power and hate it's development support and lack of a clear UI. Any help welcome :) .

EDIT: As Michael Urman has kindly pointed out I wasn't correctly handling the boolean return from my XML Document load. I have made this edit and my script is now getting as far as the 'getNamedItem' and set the value.

Is this possibly because the field I wish to set is not the named "value" attribute? My elements don't have any attributes, but I suspected the value for the element was an attribute named 'value', lol. Have I presumed wrong?

Further EDIT!! Nope it's not the above then... I have tried the node.Value and the named element route, both ways the debugger crashes on the 'setter' line for the new value. Think I might just have to use the inbuilt function.

È stato utile?

Soluzione

I think your load check is incorrect. The return value of the DOMDocument.load method is boolean, not hresult. Thus instead of negative values being failures, only a zero value is a failure. If you compare your highlighted code excerpt with the code on the question you reference, you'll see the other code uses if !successfulLoad instead.

But let's also clarify a few things. When you go through operations on an object from a CreateObject call, you're really fighting with COM instead of InstallScript, unless it's the language side that's preventing you from doing something.

Secondly, if the single ReplaceValueOf call is the only change you need to make to this file, and you know where the file is (or will be), it would probably be much easier to use the built-in XML file changes support. Set up its XPath to refer to //platformID/SerialNumber/version by creating three hierarchical elements with those names, and set the version element's node text to 1.

Recent versions of InstallShield handle small changes like this pretty well, only having problems with ordering and similar on large wholesale changes. If indentation and other such changes are causing a problem, you can disable that as well.

Altri suggerimenti

Above code is working for me if I changed code to set xml element text in function ReplaceValueOf to oNode.text = valueToPutIn;

I needed also changed create object to use 6.0 version: CreateObject("Msxml2.DOMDocument.6.0");

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top