cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
pmatlock
Level 6

take user input to dynamically update an xml file via InstallScript

I need to create a custom dialog, take the user input and update an xml file with those values. I need to know how to do this via InstallScript.

It seems I can't use the MSISet commands (those aren't supported with InstallScript)

I can't set the values in the XML File Changes Advanced Dialog, because I dont' know the values until runtime.

Any help would be greatly appreciated
Labels (1)
0 Kudos
(10) Replies
DebbieL
Level 17

For learning how to create a custom dialog in an InstallScript project, start with Creating New Custom Dialogs in InstallScript and InstallScript MSI Projects.

For information on how to configure information in XML files based on end-user input at run time, see Using InstallScript Text Substitution to Dynamically Modify XML Files.
0 Kudos
pmatlock
Level 6

I am still not successful in updating my xml file from an installscript or installscriptmsi project.
My .xml file is updated with something like this:
attribute="" --- literally...vs the value of my property.
I followed the steps on the helpnet link:

http://helpnet.flexerasoftware.com/Robo/BIN/Robo.dll?mgr=agm&tpc=%2Frobo%2Fprojects%2Finstallshield16helplib%2FXML-TextSubs.htm&wnd=InstallShieldLivingHelp%7CMain&agt=wsm&ctxid=showthread.php

Yet when I view my xml/config file that value is not there, just "". When I try and test through the XMLFiles\Test XML File Install Changes....my InstallShield blows up and closes.

I need a way to update XML/config files and test these changes.
0 Kudos
pmatlock
Level 6

I am still not able to successfully update my xml/config file.
I have followed the helpnet article on this, and my xml file gets updated as such:

MYPROPERTY
vs the actual value that is should have:

"abcValue"

When I try to test the xmlFile through InstallShield - XMLFIles - Test XML FIle...the InstallShield app blows up and closes.

Please help. I can not update my xml file with the correct value or TEST the xml file/changes
0 Kudos
DebbieL
Level 17

Sorry, I'm not able to reproduce a crash. Perhaps you can post a screen shot of what you have in the XML view, along with your InstallScript code that updates the InstallScript variable?

Please note that the steps for updating an XML file at run time are very different if you are using an InstallScript project vs. an InstallScript MSI project. If you are using the XML File Changes view in an InstallScript project, the InstallScript engine updates the XML file at run time; thus, you can use InstallScript text subs. However, if you are using the XML File Changes view in an InstallScript MSI project, the Windows Installer updates the XML file at run time; thus, you can would need to use Windows Installer properties. The following help topic has instructions for InstallScript MSI projects: Using Windows Installer Properties to Dynamically Modify XML Files

Note that if you try to test your XML file from within the XML File Changes view, any text substitution string variables that are used for XML data are not replaced with the appropriate values during testing. The only way to test the substitutions is to run the full installation.
0 Kudos
pmatlock
Level 6

That's all fine and good if I need to use an existing Windows Installer Property, yet, I need to set properties for Custom dialogs/custom properties, and be able to take those properties to update an xml file. Is there an example of that anywhere for an InstallScriptMSI project?
0 Kudos
pmatlock
Level 6

It looks like I will have to call the MsiSetProperty(hMsi, "MYPROPERTY", svValue)

How do get the hMsi value for the first param for the MsiSetProperty?

I am trying to do this through InstallScriptMSI.

Thanks!
0 Kudos
DebbieL
Level 17

About this:
That's all fine and good if I need to use an existing Windows Installer Property, yet, I need to set properties for Custom dialogs/custom properties, and be able to take those properties to update an xml file. Is there an example of that anywhere for an InstallScriptMSI project?

Yes, you can use your own Windows Installer properties. Just make sure that you use public properties (i.e., in all uppercase).

About this:
It looks like I will have to call the MsiSetProperty(hMsi, "MYPROPERTY", svValue)

How do get the hMsi value for the first param for the MsiSetProperty?

I am trying to do this through InstallScriptMSI.

Your InstallScript code will probably look something like this:
Dlg_MyDialog: 
nResult = MyDialog(svXmlValue);
MsiSetProperty(ISMSI_HANDLE, "MYPROPERTY", svXmlValue);
if (nResult = BACK) goto Dlg_SdWelcome;


I hope that helps.
0 Kudos
pmatlock
Level 6

Thank-you, that's what I needed...the ISMSI_HANDLE
0 Kudos
ZygoCorp
Level 6

I do this many times during our installation. My XML files have "tags" in them that I replace with real data.

This is a routine I found online that I updated; note that you could modify it further to be case sensitive. See below for some of the ways I call it.

////////////////////////////////////////////////////////////////////////////////
// FindAndReplace
//
// Base function pulled from the internet
// Replace all occurrences of the specified search string within the named file
// with the specified replacement string; function is NOT case sensitive
//
// Input: SrcDirFileName - file name to search; must NOT be read-only
// SrchString - search string; this will be replaced with RplcString
// RplcString - replacement string
//
// Returns 0 always
////////////////////////////////////////////////////////////////////////////////
function FindAndReplace(SrcDirFileName, SrchString, RplcString)
STRING svReturnLine, szString, secPart, firstPart, svResult;
STRING szMessage;
NUMBER subPos, SrchLen, nvLineNumber, nvResult, nResult;
begin
Sprintf(szMessage, "Replacing %s with %s in %s.", SrchString, RplcString, SrcDirFileName);
nResult = WriteLine(glLogFile, szMessage);

SrchLen = StrLength(SrchString); // Length of search string
nvLineNumber = 0; // Pre-set file line number to 0

// Verify that file is not read only
nResult = GetFileInfo(SrcDirFileName, FILE_ATTRIBUTE, nvResult, svResult);
if (nResult & FILE_ATTR_READONLY) then
// NOTE: if file doesn't exist, this will also be true and will come into here
// It's best to test for file existence before calling this function
Sprintf(szMessage, "Unable to update %s because it is not writeable.\nContinuing with the installation.", SrcDirFileName);
nResult = WriteLine(glLogFile, szMessage);
MessageBox(szMessage, WARNING);
goto FindAndReplaceExit;
endif;

NextLoop:
while (FileGrep(SrcDirFileName, SrchString, svReturnLine, nvLineNumber, RESTART) = 0)

// subPos is the number where the first char of search string was found
subPos = StrFind(svReturnLine, SrchString);

// firstPart is the string upto search string but not including searchString
StrSub(firstPart, svReturnLine, 0, subPos);

// secPart is the string after search string, modify the last number to include more space for the string, or less
StrSub(secPart, svReturnLine, subPos+SrchLen, 500);

// New string is firstPart followed by replace string followed by secPart
szString = firstPart+RplcString+secPart;

// Write line replacing original
FileInsertLine(SrcDirFileName, szString, nvLineNumber, REPLACE);

// The code below examines the line written back for any other occurrences
// systematically searching and re-writing back to file

// Search first line again for search string
if (FileGrep(SrcDirFileName, SrchString, svReturnLine, nvLineNumber, RESTART)=0) then
goto NextLoop; // Another occurrence found
else
// Increment line number and start all over again
nvLineNumber = nvLineNumber + 1;
endif;
endwhile; // While loop exited when END_OF_FILE reached

FindAndReplaceExit:
return 0;
end;

Example #1 of call:
szFileName = TARGETDIR ^ "Bin\\DirectoryMapConfig.xml";
if (Is(FILE_EXISTS, szFileName)) then
szSearchStr = defaultDir;
szReplaceStr = TARGETDIR;
Sprintf(szMessage, "Updating the directories noted within %s with the installation directory.", szFileName);
nResult = WriteLine(glLogFile, szMessage);
FindAndReplace(szFileName, szSearchStr, szReplaceStr);
else
szMessage = "In mpx_UpdateBinConfigurationFiles(). " + szFileName + " does not exist.";
nResult = WriteLine(glLogFile, szMessage);
//MessageBox(szMessage, INFORMATION);
endif;



Example #2 of call:
szSearchStr = "SerialNumber=\"00000\"";
szReplaceStr = "SerialNumber=\"" + szSerialNo + "\"";
FindAndReplace(szFileName, szSearchStr, szReplaceStr);


Example #3 of call:
if (TRUE) then
Sprintf(szMessage, "Disable.");
nResult = WriteLine(glLogFile, szMessage);
// Comment out the sections
szSearchStr = "";
szReplaceStr = "";
FindAndReplace(szICFileName, szSearchStr, szReplaceStr);
else
Sprintf(szMessage, "Enable.");
nResult = WriteLine(glLogFile, szMessage);
szSearchStr = "";
szReplaceStr = "";
FindAndReplace(szICFileName, szSearchStr, szReplaceStr);
szSearchStr = "
";
szReplaceStr = "";
FindAndReplace(szICFileName, szSearchStr, szReplaceStr);
endif;
0 Kudos
pmatlock
Level 6

Cool, thank-you very much for the examples!
0 Kudos