cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
mumbles
Level 7

XPath and Installscript...

Hello All,

I've been struggling with this for two days now. This ability is barely documented and it's very difficult to get any feedback.

Essentially, i'm trying to replace some values in an XML file:


function string FileStringReplacement(hMSI, sDestPath, sDestFile, sMachineDeviceName)

OBJECT oDoc, Lot;
NUMBER nvFileHandle, nvResult;
STRING svString, szResult, szPath, szFile, szReplace, strTempString;


begin

set oDoc = CreateObject("Msxml2.DOMDocument.4.0");
oDoc.async = FALSE;
oDoc.setProperty("SelectionLanguage", "XPath");

oDoc.load(sDestPath + sDestFile);

set Lot = oDoc.selectNodes("/Device/@Name");

Lot.attributes.getNamedItem("Value").value = sMachineDeviceName;

oDoc.save(sDestPath + sDestFile);
set oDoc = NOTHING;

end;



The XML file:


false
false
5
Datascope.DatascopeDevice
Datascope




Nothing is happening. Any ideas? Please advise, i'm going insane over here... It's scheduled after the files are installed and it's running next to another custom action which is working. So i know it's not a scheduling problem. And i cannot use XMLFileChanges there is to much logic behind what i need to do....

TIA!
Labels (1)
0 Kudos
(13) Replies
Christopher_Pai
Level 16

I can't imagine why you can't use Xml File Changes. You read in all the XML that you need into properties, do your business logic in InstallScript and then use XML Changes to write all of the properties back.

The key is the hard part ( xpath and supporting rollback ) is handled for you for free while you write a minimal set of code in InstallScript.
0 Kudos
mumbles
Level 7

BasicMSI,

I thought you retired Chris?

If what i'm doing above can't be done in a Basic MSI, what's your method Chris? Can you be a little specific?

The problem mostly is that i'm generating xml, not just changing it. I'm reading it from one file, and dynamically placing large chunks in another file based on conditions based on several properties.
0 Kudos
mumbles
Level 7

Any ideas?
0 Kudos
Christopher_Pai
Level 16

I'd have to see everything to give you a full opinion. Certainly you can put your chunks on in different components and then use conditions on those components to drive what gets written. Seems possible but I'm sitting over here...
0 Kudos
OldBean
Level 5

What Chris suggested should work in you case. Since you are going to create a xml, what I can see here is to import a skeleton xml (right click on 'xml file change' then ->Import, a wizard would show up), you might put some tokens in it, after importing, you can change element/attributes on how you would like it to be handled via 'Operation' and "scheduling' under General tab, and tweak Element Properties under Advance tab.
0 Kudos
mumbles
Level 7

Essentially,

Users select from a combobox which system they intend to use. 1 out of 7.

Based on that dropdown, a bunch of other textedit fields appear and take in information about those options. Each are global properties. So unfortunately, they can select up to 4 machines.

So we are now up to 7 possible types. Each of these types has it's own xml file. The master xml file sits in an outside directory. (But installed with the product also.)

/Settings
7 xml specific files with multiple nodes.

/
1 master.xml file.

So let's say someone chooses machine 1 as their first machine, i need to grab the text from settings/machine1.xml and place it in master.xml and replace the values with properties set from the dialogs.

Then they can select three more machines, which need to copy 3 more sections of xml into the master.xml file, and change their properties based on global properties also collected from the dialog.

You guys are telling me this is all possible via xmlchanges section? What am i missing? lol...

I've got the properties coming through customactiondata tokenized. No problem getting them over to the differed sequence. Just can't find a universal good way to do this.
0 Kudos
Christopher_Pai
Level 16

I'm sure it's possible, but at that level of complexity, is it best to put it in the installer at all? Some people believe in configuration data is a pain and belongs in the application not the installer.
0 Kudos
mumbles
Level 7

Your preaching to the choir Chris. Preaching to the choir. 🙂
0 Kudos
Christopher_Pai
Level 16

I'm in the middle of the road on this one. If an application only has one or two pieces of critical configuration then I'll probably do it in the installer. Things like I just installed a database and now I need to tweak a web.config connection string to point to it or I just created a service account and now I need to set the app_pool or windows service to use it.

But if something asks for dozens of settings I'll usually kick back and tell dev that it's unsustainable. I usually show them two installs as an example:

SQL Server - boat loads of custom UI and windows workflow to get a bunch of settings and do all the config during the installer

Team Foundation Server - a simple installer that lays everything down and then gives you a configuration utility to configure the different roles ( app tier, build controller, proxy ) in the different ways with a command line and config file to drive it all.

All in all, I like the TFS route the best.
0 Kudos
mumbles
Level 7

While i know you are right and there is nothing more in this world i want to do than to push back on this, with this particular project, it's just not possible.

I have to get this working. For the life of me, even my most basic example above, i can't get it to do anything to the XML. I don't know if it's because i'm pointing to DOM 4.0 or because of other reasons. This is extremely frustrating.... If i do get this working, i'm going to create a whole tutorial around this for someone else possibly facing the same issues.
0 Kudos
Christopher_Pai
Level 16

If I'm reading this right I think you could simplify by using the DuplicateFiles table.

Master.xml -> 1.xml 2.xml 3.xml 4.xml

You duplicate only based on component conditions. This should get you most of the way there and only use XPath to tweak the properties that need to be tweaked.
0 Kudos
mumbles
Level 7

Chris not a bad idea at all. I went the C# console app route instead. Too complicated otherwise. Thanks though!
0 Kudos
mumbles
Level 7

Here is the code i used, i created a C# console application. Disclaimer - I'm no c# guru, so i'm sure there are better more efficient ways of doing this. But if you have a little familiarity with xpath and c#, you can whip up something relatively easy with my script.

So basically, depending on my properties set in the registry, it instructs the console app, which is called via custom action to perform an action based on what i've set in the UI of my app.

Enjoy!

[CODE]using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Net;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Xml;
using System.Data;
using Microsoft.Win32;
using System.Collections;


namespace DeviceLinkHelper
{
class Program
{
public const string regKeyPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\PlexusIS\\DeviceLink\\";
public static string machineSettingsDir;
public static string machineInstallDir;

static void Main(string[] args)
{

//set variables...
machineSettingsDir = RegGetter(regKeyPath, "InstallDir");
machineSettingsDir = machineSettingsDir + "Settings\\";
machineInstallDir = RegGetter(regKeyPath, "InstallDir");


//Refactor this **** when time allows...
//MachineOne Variable Set.
string regKeyPathOne = regKeyPath + "MachineOne";
string machineOneType = RegGetter(regKeyPathOne, "MachineOneType");
string machineOneDeviceName = RegGetter(regKeyPathOne, "MachineOneDeviceName");
string machineOneConnectionType = RegGetter(regKeyPathOne, "MachineOneConnectionType");
string machineOneIpAddress = RegGetter(regKeyPathOne, "MachineOneIpAddress");
string machineOneIpPort = RegGetter(regKeyPathOne, "MachineOneIpPort");
string machineOneComPort = RegGetter(regKeyPathOne, "MachineOneComPort");
string machineOneDataBits = RegGetter(regKeyPathOne, "MachineOneDataBits");
string machineOneStopBits = RegGetter(regKeyPathOne, "MachineOneStopBits");
string machineOneBaudRate = RegGetter(regKeyPathOne, "MachineOneBaudRate");
string machineOneParity = RegGetter(regKeyPathOne, "MachineOneParity");
string machineOneDebug = RegGetter(regKeyPathOne, "MachineOneDebug");
string machineOneEnabled = RegGetter(regKeyPathOne, "MachineOneEnabled");
string machineOnePollInterval = RegGetter(regKeyPathOne, "MachineOnePollInterval");


if (machineOneType == null)
{
//do nothing.
}
else
{

switch (machineOneType)
{
case "DATASCOPE":
{
xmlFileWriter(machineSettingsDir + "Datascope.DatascopeDevice.xml", machineOneDeviceName, machineOneConnectionType, machineOneIpAddress, machineOneIpPort, machineOneComPort, machineOneDataBits, machineOneStopBits, machineOneBaudRate, machineOneParity, machineOneDebug, machineOneEnabled, machineOnePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Datascope.DatascopeDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DATEXOHMEDA":
{
xmlFileWriter(machineSettingsDir + "DatexOhmeda.DatexOhmedaDevice.xml", machineOneDeviceName, machineOneConnectionType, machineOneIpAddress, machineOneIpPort, machineOneComPort, machineOneDataBits, machineOneStopBits, machineOneBaudRate, machineOneParity, machineOneDebug, machineOneEnabled, machineOnePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "DatexOhmeda.DatexOhmedaDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DATEXOHMEDARGM5250":
{
xmlFileWriter(machineSettingsDir + "DatexOhmeda.OhmedaRGM5250.xml", machineOneDeviceName, machineOneConnectionType, machineOneIpAddress, machineOneIpPort, machineOneComPort, machineOneDataBits, machineOneStopBits, machineOneBaudRate, machineOneParity, machineOneDebug, machineOneEnabled, machineOnePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "DatexOhmeda.OhmedaRGM5250.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DRAGERVITALINK":
{
xmlFileWriter(machineSettingsDir + "Drager.DragerVitalinkDevice.xml", machineOneDeviceName, machineOneConnectionType, machineOneIpAddress, machineOneIpPort, machineOneComPort, machineOneDataBits, machineOneStopBits, machineOneBaudRate, machineOneParity, machineOneDebug, machineOneEnabled, machineOnePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Drager.DragerVitalinkDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DRAGERMEDIABUS":
{
xmlFileWriter(machineSettingsDir + "Drager.DragerMedibusDevice.xml", machineOneDeviceName, machineOneConnectionType, machineOneIpAddress, machineOneIpPort, machineOneComPort, machineOneDataBits, machineOneStopBits, machineOneBaudRate, machineOneParity, machineOneDebug, machineOneEnabled, machineOnePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Drager.DragerMedibusDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

}

}


//MachineTwo Variable Set.

string regKeyPathTwo = regKeyPath + "MachineTwo";
string machineTwoType = RegGetter(regKeyPathTwo, "MachineTwoType");
string machineTwoDeviceName = RegGetter(regKeyPathTwo, "MachineTwoDeviceName");
string machineTwoConnectionType = RegGetter(regKeyPathTwo, "MachineTwoConnectionType");
string machineTwoIpAddress = RegGetter(regKeyPathTwo, "MachineTwoIpAddress");
string machineTwoIpPort = RegGetter(regKeyPathTwo, "MachineTwoIpPort");
string machineTwoComPort = RegGetter(regKeyPathTwo, "MachineTwoComPort");
string machineTwoDataBits = RegGetter(regKeyPathTwo, "MachineTwoDataBits");
string machineTwoStopBits = RegGetter(regKeyPathTwo, "MachineTwoStopBits");
string machineTwoBaudRate = RegGetter(regKeyPathTwo, "MachineTwoBaudRate");
string machineTwoParity = RegGetter(regKeyPathTwo, "MachineTwoParity");
string machineTwoDebug = RegGetter(regKeyPathTwo, "MachineTwoDebug");
string machineTwoEnabled = RegGetter(regKeyPathTwo, "MachineTwoEnabled");
string machineTwoPollInterval = RegGetter(regKeyPathTwo, "MachineTwoPollInterval");

if (machineTwoType == null)
{
//Do nothing.
}
else
{

switch (machineTwoType)
{
case "DATASCOPE":
{
xmlFileWriter(machineSettingsDir + "Datascope.DatascopeDevice.xml", machineTwoDeviceName, machineTwoConnectionType, machineTwoIpAddress, machineTwoIpPort, machineTwoComPort, machineTwoDataBits, machineTwoStopBits, machineTwoBaudRate, machineTwoParity, machineTwoDebug, machineTwoEnabled, machineTwoPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "WelchAllynPropaq.WelchAllynPropaqDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DATEXOHMEDA":
{
xmlFileWriter(machineSettingsDir + "DatexOhmeda.DatexOhmedaDevice.xml", machineTwoDeviceName, machineTwoConnectionType, machineTwoIpAddress, machineTwoIpPort, machineTwoComPort, machineTwoDataBits, machineTwoStopBits, machineTwoBaudRate, machineTwoParity, machineTwoDebug, machineTwoEnabled, machineTwoPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "DatexOhmeda.DatexOhmedaDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DATEXOHMEDARGM5250":
{
xmlFileWriter(machineSettingsDir + "DatexOhmeda.OhmedaRGM5250.xml", machineTwoDeviceName, machineTwoConnectionType, machineTwoIpAddress, machineTwoIpPort, machineTwoComPort, machineTwoDataBits, machineTwoStopBits, machineTwoBaudRate, machineTwoParity, machineTwoDebug, machineTwoEnabled, machineTwoPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "DatexOhmeda.OhmedaRGM5250.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DRAGERVITALINK":
{
xmlFileWriter(machineSettingsDir + "Drager.DragerVitalinkDevice.xml", machineTwoDeviceName, machineTwoConnectionType, machineTwoIpAddress, machineTwoIpPort, machineTwoComPort, machineTwoDataBits, machineTwoStopBits, machineTwoBaudRate, machineTwoParity, machineTwoDebug, machineTwoEnabled, machineTwoPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Drager.DragerVitalinkDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DRAGERMEDIABUS":
{
xmlFileWriter(machineSettingsDir + "Drager.DragerMedibusDevice.xml", machineTwoDeviceName, machineTwoConnectionType, machineTwoIpAddress, machineTwoIpPort, machineTwoComPort, machineTwoDataBits, machineTwoStopBits, machineTwoBaudRate, machineTwoParity, machineTwoDebug, machineTwoEnabled, machineTwoPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Drager.DragerMedibusDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}




}
}


//MachineThree Variable Set.
string regKeyPathThree = regKeyPath + "MachineThree";
string machineThreeType = RegGetter(regKeyPathThree, "MachineThreeType");
string machineThreeDeviceName = RegGetter(regKeyPathThree, "MachineThreeDeviceName");
string machineThreeConnectionType = RegGetter(regKeyPathThree, "MachineThreeConnectionType");
string machineThreeIpAddress = RegGetter(regKeyPathThree, "MachineThreeIpAddress");
string machineThreeIpPort = RegGetter(regKeyPathThree, "MachineThreeIpPort");
string machineThreeComPort = RegGetter(regKeyPathThree, "MachineThreeComPort");
string machineThreeDataBits = RegGetter(regKeyPathThree, "MachineThreeDataBits");
string machineThreeStopBits = RegGetter(regKeyPathThree, "MachineThreeStopBits");
string machineThreeBaudRate = RegGetter(regKeyPathThree, "MachineThreeBaudRate");
string machineThreeParity = RegGetter(regKeyPathThree, "MachineThreeParity");
string machineThreeDebug = RegGetter(regKeyPathThree, "MachineThreeDebug");
string machineThreeEnabled = RegGetter(regKeyPathThree, "MachineThreeEnabled");
string machineThreePollInterval = RegGetter(regKeyPathThree, "MachineThreePollInterval");

if (machineThreeType == null)
{
//do nothing.
}
else
{

switch (machineThreeType)
{
case "DATASCOPE":
{
xmlFileWriter(machineSettingsDir + "Datascope.DatascopeDevice.xml", machineThreeDeviceName, machineThreeConnectionType, machineThreeIpAddress, machineThreeIpPort, machineThreeComPort, machineThreeDataBits, machineThreeStopBits, machineThreeBaudRate, machineThreeParity, machineThreeDebug, machineThreeEnabled, machineThreePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Datascope.DatascopeDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DATEXOHMEDA":
{
xmlFileWriter(machineSettingsDir + "DatexOhmeda.DatexOhmedaDevice.xml", machineThreeDeviceName, machineThreeConnectionType, machineThreeIpAddress, machineThreeIpPort, machineThreeComPort, machineThreeDataBits, machineThreeStopBits, machineThreeBaudRate, machineThreeParity, machineThreeDebug, machineThreeEnabled, machineThreePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "DatexOhmeda.DatexOhmedaDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DATEXOHMEDARGM5250":
{
xmlFileWriter(machineSettingsDir + "DatexOhmeda.OhmedaRGM5250.xml", machineThreeDeviceName, machineThreeConnectionType, machineThreeIpAddress, machineThreeIpPort, machineThreeComPort, machineThreeDataBits, machineThreeStopBits, machineThreeBaudRate, machineThreeParity, machineThreeDebug, machineThreeEnabled, machineThreePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "DatexOhmeda.OhmedaRGM5250.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DRAGERVITALINK":
{
xmlFileWriter(machineSettingsDir + "Drager.DragerVitalinkDevice.xml", machineThreeDeviceName, machineThreeConnectionType, machineThreeIpAddress, machineThreeIpPort, machineThreeComPort, machineThreeDataBits, machineThreeStopBits, machineThreeBaudRate, machineThreeParity, machineThreeDebug, machineThreeEnabled, machineThreePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Drager.DragerVitalinkDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DRAGERMEDIABUS":
{
xmlFileWriter(machineSettingsDir + "Drager.DragerMedibusDevice.xml", machineThreeDeviceName, machineThreeConnectionType, machineThreeIpAddress, machineThreeIpPort, machineThreeComPort, machineThreeDataBits, machineThreeStopBits, machineThreeBaudRate, machineThreeParity, machineThreeDebug, machineThreeEnabled, machineThreePollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Drager.DragerMedibusDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}



}
}


//MachineFour Variable Set.
string regKeyPathFour = regKeyPath + "MachineFour";
string machineFourType = RegGetter(regKeyPathFour, "MachineFourType");
string machineFourDeviceName = RegGetter(regKeyPathFour, "MachineFourDeviceName");
string machineFourConnectionType = RegGetter(regKeyPathFour, "MachineFourConnectionType");
string machineFourIpAddress = RegGetter(regKeyPathFour, "MachineFourIpAddress");
string machineFourIpPort = RegGetter(regKeyPathFour, "MachineFourIpPort");
string machineFourComPort = RegGetter(regKeyPathFour, "MachineFourComPort");
string machineFourDataBits = RegGetter(regKeyPathFour, "MachineFourDataBits");
string machineFourStopBits = RegGetter(regKeyPathFour, "MachineFourStopBits");
string machineFourBaudRate = RegGetter(regKeyPathFour, "MachineFourBaudRate");
string machineFourParity = RegGetter(regKeyPathFour, "MachineFourParity");
string machineFourDebug = RegGetter(regKeyPathFour, "MachineFourDebug");
string machineFourEnabled = RegGetter(regKeyPathFour, "MachineFourEnabled");
string machineFourPollInterval = RegGetter(regKeyPathFour, "MachineFourPollInterval");


if (machineFourType == null)
{
//do nothing.
}
else
{

switch (machineFourType)
{
case "DATASCOPE":
{
xmlFileWriter(machineSettingsDir + "Datascope.DatascopeDevice.xml", machineFourDeviceName, machineFourConnectionType, machineFourIpAddress, machineFourIpPort, machineFourComPort, machineFourDataBits, machineFourStopBits, machineFourBaudRate, machineFourParity, machineFourDebug, machineFourEnabled, machineFourPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Datascope.DatascopeDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DATEXOHMEDA":
{
xmlFileWriter(machineSettingsDir + "DatexOhmeda.DatexOhmedaDevice.xml", machineFourDeviceName, machineFourConnectionType, machineFourIpAddress, machineFourIpPort, machineFourComPort, machineFourDataBits, machineFourStopBits, machineFourBaudRate, machineFourParity, machineFourDebug, machineFourEnabled, machineFourPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "DatexOhmeda.DatexOhmedaDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DATEXOHMEDARGM5250":
{
xmlFileWriter(machineSettingsDir + "DatexOhmeda.OhmedaRGM5250.xml", machineFourDeviceName, machineFourConnectionType, machineFourIpAddress, machineFourIpPort, machineFourComPort, machineFourDataBits, machineFourStopBits, machineFourBaudRate, machineFourParity, machineFourDebug, machineFourEnabled, machineFourPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "DatexOhmeda.OhmedaRGM5250.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DRAGERVITALINK":
{
xmlFileWriter(machineSettingsDir + "Drager.DragerVitalinkDevice.xml", machineFourDeviceName, machineFourConnectionType, machineFourIpAddress, machineFourIpPort, machineFourComPort, machineFourDataBits, machineFourStopBits, machineFourBaudRate, machineFourParity, machineFourDebug, machineFourEnabled, machineFourPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Drager.DragerVitalinkDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}

case "DRAGERMEDIABUS":
{
xmlFileWriter(machineSettingsDir + "Drager.DragerMedibusDevice.xml", machineFourDeviceName, machineFourConnectionType, machineFourIpAddress, machineFourIpPort, machineFourComPort, machineFourDataBits, machineFourStopBits, machineFourBaudRate, machineFourParity, machineFourDebug, machineFourEnabled, machineFourPollInterval);
xmlDestinationFileWriter(machineSettingsDir + "Drager.DragerMedibusDevice.xml", machineInstallDir + "DeviceLink.xml");
break;
}




}
}
}

//Function to get registry values set by Installshield to use in this helper app to set the xml.
static string RegGetter(string keyPath, string keyName)
{
string returnKey = (string)Registry.GetValue(keyPath, keyName, null);
if (returnKey == null)
{
Console.WriteLine("Registry key " + keyName + " is empty!");
}
return returnKey;
}


//Function to registry values to XML files...
static void xmlFileWriter(string xmlFile, string xmlMachineDeviceName, string xmlMachineConnectionType, string xmlMachineIpAddress, string xmlMachineIpPort, string xmlMachineComPort, string xmlMachineDataBits, string xmlMachineStopBits, string xmlMachineBaudRate, string xmlMachineParity, string xmlMachineDebug, string xmlMachineEnabled, string xmlMachinePollInterval)
{
//start parsing file here.

var xdocument = System.Xml.Linq.XDocument.Load(xmlFile);
var elements = xdocument.XPathSelectElements("//Device");

try
{
foreach (var element in elements)
{
element.Attribute("Name").SetValue(xmlMachineDeviceName);
element.Attribute("ConnectionType").SetValue(xmlMachineConnectionType);
element.Attribute("IPAddress").SetValue(xmlMachineIpAddress);
element.Attribute("IPPort").SetValue(xmlMachineIpPort);
element.Attribute("ComPort").SetValue(xmlMachineComPort);
element.Attribute("BaudRate").SetValue(xmlMachineBaudRate);
element.Attribute("Parity").SetValue(xmlMachineParity);
element.Attribute("DataBits").SetValue(xmlMachineDataBits);
element.Attribute("StopBits").SetValue(xmlMachineStopBits);
element.SetElementValue("Debug", xmlMachineDebug);
element.SetElementValue("Enabled", xmlMachineEnabled);
element.SetElementValue("PollInterval", xmlMachinePollInterval);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}


xdocument.Save(xmlFile);

}

//Function to write machine specific
static void xmlDestinationFileWriter(string sourceFile, string destFile)
{

//First, grab the variables from the registry needed to perform the replacements in the xml.
string machineInstallDir = RegGetter(regKeyPath, "InstallDir");
string machineDomainID = RegGetter(regKeyPath, "DomainID");
string machinePlexusCloud = RegGetter(regKeyPath, "PlexusCloud");
string machineTcpCommondPort = RegGetter(regKeyPath, "TcpCommondPort");
string machineTcpIpAddy = RegGetter(regKeyPath, "TcpIpAddy");
string machineTcpPortNo = RegGetter(regKeyPath, "TcpPortNo");
string machineUdpPortNo = RegGetter(regKeyPath, "UdpPortNo");
string machineUseHttps = RegGetter(regKeyPath, "UseHttps");
string machineUseTcp = RegGetter(regKeyPath, "UseTcp");
string machineUseUdp = RegGetter(regKeyPath, "UseUdp");
string machineUseUdpIpAddy = RegGetter(regKeyPath, "UseUdpIpAddy");

//Second, set the xml elements in the existing skeleton file.
var xdocument = System.Xml.Linq.XDocument.Load(destFile);
var elements = xdocument.XPathSelectElements("//DeviceLink");

try
{
foreach (var element in elements)
{
element.Attribute("DomainID").SetValue(machineDomainID);
element.Attribute("UseHttps").SetValue(machineUseHttps);
element.Attribute("PlexusCloudURL").SetValue(machinePlexusCloud);
element.Attribute("UseTCP").SetValue(machineUseTcp);
element.Attribute("IPAddress").SetValue(machineTcpIpAddy);
element.Attribute("Port").SetValue(machineTcpPortNo);
element.Attribute("UseUDP").SetValue(machineUseUdp);
element.Attribute("UDPRemoteIPAddress").SetValue(machineUseUdpIpAddy);
element.Attribute("UDPRemotePort").SetValue(machineUdpPortNo);
element.Attribute("CommandPort").SetValue(machineTcpCommondPort);

}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
xdocument.Save(destFile);



//Third, append the device xml file into the node.
XmlDocument sourceDoc = new XmlDocument();
XmlDocument destDoc = new XmlDocument();

sourceDoc.Load(sourceFile);
destDoc.Load(destFile);

try
{
//Load both files.
sourceDoc.Load(sourceFile);
destDoc.Load(destFile);
//sourceDoc.PreserveWhitespace = true; don't do this, ends up messing up the formatting. Go figure.
//destDoc.PreserveWhitespace = true;


//Grab elements from source file, write them to dest file.
var node = destDoc.SelectSingleNode("//Devices");
node.AppendChild(destDoc.ImportNode(sourceDoc.SelectSingleNode("//Device"), true));

destDoc.Save(destFile);

}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

}
[/CODE]
0 Kudos