Updated WiX generation script

This is long overdue, but I finally sat down and tweaked the script I provided in WiX for dummies post so it no longer uses FileGroup. This walks through a tree and generates a component for every file. The FileGroup element now appears to have been removed from WiX rather than just deprecated, so if any of you followed the steps in the original post, you'll need this when you update to a newer build of WiX. Another approach is to use Tallow.exe, but I haven't played with it enough to say how.

--- generate-install-script.js ---

// Generates the WiX XML necessary to install a directory tree.
var g_shell = new ActiveXObject("WScript.Shell");
var g_fs = new ActiveXObject("Scripting.FileSystemObject");
if (WScript.Arguments.length != 2)
{
 WScript.Echo("Usage: cscript.exe generate-install-script.js <rootFolder> <outputXMLFile>");
 WScript.Quit(1);
}
var rootDir = WScript.Arguments.Item(0);
var outFile = WScript.Arguments.Item(1);
var baseFolder = g_fs.GetFolder(rootDir);
var componentIds = new Array();

WScript.Echo("Generating " + outFile + "...");

var f = g_fs.CreateTextFile(outFile, true);
f.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
f.WriteLine("<Include>");
f.WriteLine("  <Directory Id=\"TARGETDIR\" Name=\"SourceDir\">");
f.Write(getDirTree(rootDir, "", 1, baseFolder, componentIds));
f.WriteLine("  </Directory>");
f.WriteLine("  <Feature Id=\"DefaultFeature\" Level=\"1\" ConfigurableDirectory=\"TARGETDIR\">");
for (var i=0; i<componentIds.length; i++)
{
 f.WriteLine("    <ComponentRef Id=\"C__" + componentIds[i] + "\" />");
}
f.WriteLine("  </Feature>");
f.WriteLine("</Include>");
f.Close();

// recursive method to extract information for a folder
function getDirTree(root, xml, indent, baseFolder, componentIds)
{
 var fdrFolder = null;
 try
 {
  fdrFolder = g_fs.GetFolder(root);
 }
 catch (e)
 {
  return;
 }

 // indent the xml
 var space = "";
 for (var i=0; i<indent; i++)
  space = space + "  ";

 if (fdrFolder != baseFolder)
 {
  var directoryId = "_" + FlatFormat(GetGuid());

  xml = xml + space + "<Directory Id=\"" + directoryId +"\"";
  xml = xml + " Name=\"" + fdrFolder.ShortName.toUpperCase() + "\"";
  xml = xml + " LongName=\"" + fdrFolder.Name + "\">\r\n";
 }

 var componentGuid = GetGuid();
 var componentId = FlatFormat(componentGuid);


 xml = xml + space + "  <Component Id=\"C__" + componentId + "\""
     + " Guid=\"" + componentGuid + "\">\r\n";

 if (fdrFolder.Files.Count > 0)
 {
  var enumFiles = new Enumerator(fdrFolder.Files);

  for (;!enumFiles.atEnd();enumFiles.moveNext())
  {

   var file = enumFiles.item();

   var fId = "_" + FlatFormat(GetGuid());
   xml = xml + space + "    <File Id=\"" + fId +
            "\" Name=\"" + file.ShortName.toUpperCase() +
            "\" LongName=\"" + file.Name +
            "\" src=\"$(var.redist_folder)" + file.Path.substring(baseFolder.Path.length) +
            "\" Vital=\"yes" +
            "\" DiskId=\"1\"/>\r\n";
  }
 }
 else
 {
  xml = xml + space + "    <CreateFolder />\r\n";
 }

 xml = xml + space + "  </Component>\r\n";

 componentIds[componentIds.length] = componentId;


 var enumSubFolders = new Enumerator(fdrFolder.SubFolders);

 var depth = indent + 1;
 for (;!enumSubFolders.atEnd();enumSubFolders.moveNext())
 {
  var subfolder = enumSubFolders.item();
  xml = getDirTree(enumSubFolders.item().Path, xml, depth, baseFolder, componentIds);
 }

 if (fdrFolder != baseFolder)
 {
  xml = xml + space + "</Directory>\r\n";
 }

 return xml;
}

// Generate a new GUID
function GetGuid()
{
 return new ActiveXObject("Scriptlet.Typelib").Guid.substr(1,36).toUpperCase();
}

// Convert a GUID from this format
//   7E70E5E5-CE19-4270-A740-223A09796433
// to this format:
//   7E70E5E5CE194270A740223A09796433
function FlatFormat(guid)
{
 return guid.replace(/-/g, "");
}

3 Comments

Comments have been disabled for this content.