HOWTO: Find application's install path with JScript using Windows Registry

So, you need to write a script to determine application's install path. You could use wmi console and iterate over programs, but that somehow modifies installer's data. The easiest and safest way to determine that is to browse Windows Registry.
When a program gets installed, its information gets written to a HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{app guid} key.

The following JScript, which was written for use with TestComplete will do the trick. This script works in the following manner:
1) It gets all subkeys of HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ and writes it out to a text file.
2) After file has been written, it is read back into an array of string for GUID extraction
3) Once we have a GUID string, we're testing the registry path to see if it matches application we are looking for.

So, without further delay, here's the code:

function extractGUID(curString) {
   var regEx = "^.[^{]*({.[^}]*})";
   var matches = curString.match(regEx);
   var guid = "";
 
   // get the last match as it should be the guid   
   return ((matches != null) && (matches.length > 1)) ? matches[matches.length - 1] : "";
}
 
function FindInstallLocation(guidStr, displayNameValue) {
   var retVal = "";
   if (!guidStr || (guidStr == "")) {
      return retVal;
   }
   var curKeyFile = aqEnvironment.GetEnvironmentVariable("temp", Sys.OSInfo.Windows64bit) + "\\curKey.txt";
   var uninstallLoc = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + guidStr;
 
   var commandToRun = "cmd /c \"reg.exe query " + uninstallLoc + " > " + curKeyFile + "\"";
   var shObj = Sys.OleObject("WScript.Shell");
   shObj.Run(commandToRun, 0, true);
 
   // make sure that file was created
   if (!aqFile.Exists(curKeyFile)) {
      Log.Error("'" + curKeyFile + "' File was not found!");
      return retVal;
   }
 
   // open file for reading
   var keyHandle = null;
   var installLocationName = "InstallLocation";
   var displayNameName = "DisplayName";
   try {
      keyHandle = aqFile.OpenTextFile(curKeyFile, aqFile.faRead, aqFile.ctANSI, false);
      var fileContents = keyHandle.ReadAll();
      aqString.ListSeparator = "\n";
      var totalLines = aqString.GetListLength(fileContents);
      // loop until we've gone through entire file
      var wasDisplayNameFound = false;
      for (var i = 0; i < totalLines; i++) {
         // if we have already found our name and location, exit out
         if (wasDisplayNameFound && (retVal != "")) {
            break;
         }
 
         //var curLine = keyHandle.ReadLine();
         var curLine = aqString.Trim(aqString.GetListItem(fileContents, i), 3);
         if (curLine == "") { continue; }
         // see if it a display name KVP
         if (aqString.Find(curLine, displayNameName, 0, true) >= 0) {
            // make sure that it matches what we are looking for
            if (aqString.Find(curLine, displayNameValue, false) == -1) {
               break;
            }
            else {
               wasDisplayNameFound = true;
            }
         }
         // see if we are at the install location KVP
         if (aqString.Find(curLine, installLocationName, 0, true) >= 0) {
            // extract the value
            var matches = curLine.match("\\s*\\w*\\s*\\w*\\s*(.*)");
            if (matches.length > 0) {
               // get the last match
               retVal = matches[matches.length - 1];
            }
         }
      }
      if (!wasDisplayNameFound) {
         retVal = "";
      }
   }
   catch (e) {
      Log.Error(e.description);
   }
   finally {
      if (keyHandle != null) {
         keyHandle.Close();
      }
      aqFile.Delete(curKeyFile);
   }
 
   return retVal;
}
 
function getSoftInfo(appOfInterest ) {
   var allKeysFile = aqEnvironment.GetEnvironmentVariable("temp", Sys.OSInfo.Windows64bit) + "\\uninstallhive.txt";
 
   var uninstallKeyLoc = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
   var commandToRun = "cmd /c \"reg.exe query " + uninstallKeyLoc + " > " + allKeysFile + "\"";
   var shObj = Sys.OleObject("WScript.Shell");
   shObj.Run(commandToRun, 0, true);
 
   // make sure that file was created
   if (!aqFile.Exists(allKeysFile)) {
      Log.Error("'" + allKeysFile + "' File was not found!");
      return null;
   }
 
   var installLoc = "";
   // loop through each line until we found app of interest
   var fileHandle = null;
   try {
      fileHandle = aqFile.OpenTextFile(allKeysFile, aqFile.faRead, aqFile.ctANSI, false);
      var fileConts = fileHandle.ReadAll();
      aqString.ListSeparator = "\n";
      var listLen = aqString.GetListLength(fileConts);
 
      for (var i = 0; i < listLen; i++) {
         // read a line
         var curLine = aqString.GetListItem(fileConts, i);
         if (aqString.Find(curLine, "{", 0) == -1) { continue; }
         // find the guid
         var guid = extractGUID(curLine);
         installLoc = FindInstallLocation(guid, appOfInterest);
         if (installLoc != "") {
            break;
         }
      }
   }
   finally {
      if (fileHandle != null) {
         fileHandle.Close();
      }
      aqFile.Delete(allKeysFile);
   }
 
   return installLoc;
}

To run this function, simply do something like this:

function testGetSoftInfo() {
  var appName = "Firefox";
  var appLoc = getSoftInfo(appName);
}

Comments