5

I want to modify xml file in Inno Setup - but installer crashes. I tried different things, and as result got sample code with problem

procedure testXml();
var
  xmlDocLocal, nodeLocal: Variant;
begin
try
   xmlDocLocal := CreateOleObject('MSXML2.DOMDocument');
   xmlDocLocal.async := False;
   xmlDocLocal.resolveExternals := False;
   xmlDocLocal.loadXML('<root></root>');
   nodeLocal := xmlDocLocal.CreateElement('element1');
   xmlDocLocal.documentElement.appendChild(nodeLocal);
except
end;

end;

During second call, installer crashes on the appendChild method. What am I doing wrong ?

user474554
  • 71
  • 4
  • You're doing it right! That's strange, really, really strange and quite serious issue... Your code should work properly. Even Microsoft shows a similar example on MSDN. I can't trace what's wrong and I wasn't able to reproduce this in Delphi, so it might be somehow related to Pascal Script itself, but hard to say. However, as a workaround you can use the [`createNode`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms757901(v=vs.85).aspx) method [`this way`](http://pastebin.com/1B92FVzu). That worked fine for me, but that's all I can tell about it. – TLama Jul 29 '13 at 18:11
  • Some notes on the MSXML crashes, which may be relevant. http://stackoverflow.com/a/42869405/572002 – Nicholi Mar 18 '17 at 01:23

2 Answers2

2

Three ideas: first, we're using InnoSetup, but for us the OleObject needs to be created with another string ending with the specific version 6.0:

try
    XMLDoc := CreateOleObject('MSXML2.DOMDocument.6.0');
except
    RaiseException('Please install MSXML first.'#13#13'(Error ''' + GetExceptionMessage + ''' occurred)');
end;

Second idea: try adding an xml header to the XML string you have in your code. Like this:

xmlDocLocal.loadXML('<?xml version="1.0" encoding="UTF-8" ?><root></root>');

Third idea: try checking for errors (as I already showed in the first snippet). That might give you a pretty good idea what goes wrong. This is how we do it (and it works):

XMLDoc.load(XMLFileName);
if XMLDoc.parseError.errorCode <> 0 then
  XMLDoc.load(XMLFileName2);
if XMLDoc.parseError.errorCode <> 0 then
  RaiseException('Error on line ' + IntToStr(XMLDoc.parseError.line) + ', position ' + IntToStr(XMLDoc.parseError.linepos) + ': ' + XMLDoc.parseError.reason);

Hope this helps you. Hard to solve an unknown issue ;-)

Akku
  • 4,373
  • 4
  • 48
  • 67
  • 1) I've tried that. The same problem remains. 2) That's valuable point! Haven't tried... 2) There was no parsing error when I've tried; moreover, the `documentElement` and `nodeLocal` variables are not `NULL`. And, the most weird, it happens on the second call. I've tried also explicitly release the interface references by setting the variables to `Unassigned`, but it also didn't help... [+1 for good points, anyway!] – TLama Aug 01 '13 at 08:58
0

Though this is an old issue, I would like to bring it up once more. I am using InnoSetup 6 and have spent two days working on this until I found this stackoverflow issue. For me it seems that the problem is still there. My installer keeps crashing with an Access Violation and I boilt it down to a very similar example like the one above. It makes no difference if I use createElement or createNode.

xmlDocument := CreateOleObject('MSXML2.DOMDocument.6.0');
xmlDocument.async := false;
xmlDocument.resolveExternals := false;
xmlDocument.loadXML('<broker><web bind="http://localhost:8161"></web></broker>');
//xmlDocument.setProperty('SelectionLanguage', 'XPath');
// Select the <web> node
node := xmlDocument.selectSingleNode('/broker/web');
// save attribute value into variable
bind := node.getAttribute('bind');
// remove legacy attribute
node.removeAttribute('bind');
// add new <binding> element as first child of <web>
//newNode := xmlDocument.createNode(1, 'binding', '');
newNode := xmlDocument.createElement('binding');
newNode.setAttribute('uri', bind);
Log(Format('### Appending %s as first child of %s', [newNode.xml, node.xml]));
node.appendChild(newNode);
Log(Format('### Inserted %s as first child of %s', [newNode.xml, node.xml]));
xmlDocument.Save(bootConfig);

All I see when running the code above is this:

enter image description here

The difference with createElement and createNode is, that createElement creates the exception message above and createNode simply kills the installer silently.

The last I see in the logs is this line:

2022-04-25 13:44:47.597   ### Appending <binding uri="http://localhost:8161"/> as first child of <web></web>
2022-04-25 13:44:47.597   CurStepChanged raised an exception.
2022-04-25 13:44:47.597   Exception message:
2022-04-25 13:44:47.597   Message box (OK):
                          Runtime error (at 211:2827):
                          
                          Access violation at address 03CC8380. Execution of address 03CC8380.

Has this been addressed in some way? I cannot see from Russel Jordan's site that there has been any bugfix for this.

Sebastian Götz
  • 459
  • 7
  • 15