Registry Appending |
The Registry command like Windows Installer does support registry appending (look for "[~]") but has features (see the "Updating (not setting) Registry causes invalid values" section).
The following code demonstrates one alternative:
<$DirectoryTree Key="INSTALLDIR" Dir="[ProgramFilesFolder]\MyDeviceDrivers" CHANGE="\" PrimaryFolder="Y"> ;---------------------------------------------------------------------------------- ;--- Add/Remove installation directory into "DevicePath" (search list) v06.118) --- ;---------------------------------------------------------------------------------- <$VbsCa Binary="UpdateWindowsDeviceSearchPath.vbs"> ;--- Define the "variables" --------------------------------------------- const InstallDirName = "INSTALLDIR" ;;Directory KEY const RegName = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DevicePath" const Delimiter = ";" ;;Code assumes 1 character exactly! ;--- CA Entry points ---------------------------------------------------- <$VbsCaEntry "Append"> CaDebug 1, "Appending installation directory to Windows search path" UpdateRegistry(true) <$/VbsCaEntry> <$VbsCaEntry "Remove"> CaDebug 1, "Removing installation directory to Windows search path" UpdateRegistry(false) <$/VbsCaEntry> <?NewLine><?NewLine> ;============================================================================ sub UpdateRegistry(Appending) ;============================================================================ ;--- Get the install directory name --------------------------------- dim INSTALLDIR : INSTALLDIR = VbsCaPropertyGet(InstallDirName, "C:\tmp\INSTALLDIR.TST", "Please enter the installation directory name") if INSTALLDIR = "" then VbsCaRaiseError "UpdateRegistry()", "The """ & InstallDirName & """ property/directory is blank!" end if if right(INSTALLDIR, 1) = "\" then INSTALLDIR = left(INSTALLDIR, len(INSTALLDIR)-1) end if ;--- Read the existing registry value ------------------------------- CaDebug 0, "Reading : " & RegName on error resume next dim oShell : set oShell = CaMkObject("WScript.Shell") dim RegVal : RegVal = oShell.RegRead(RegName) if err.number <> 0 then ;--- Failed to read the value ----------------------------------- dim Reason : Reason = "0x" & hex(err.number) & " - " & err.description on error goto 0 VbsCaRaiseError "UpdateRegistry()", "Could not read the Windows plug and play search path at: " & RegName & vbCRLF & vbCRLF & "Reason: " & Reason else ;--- Update the string we just read ----------------------------- RegVal = UpdatePathString(RegVal, INSTALLDIR, Delimiter, Appending) ;--- Write the updated value to the Registry -------------------- CaDebug 0, "Writing : " & RegVal oShell.RegWrite RegName, RegVal, "REG_EXPAND_SZ" if err.number <> 0 then ;--- Failed to write the value ------------------------------ Reason = "0x" & hex(err.number) & " - " & err.description on error goto 0 VbsCaRaiseError "UpdateRegistry()", "Could not write to the Windows plug and play search path at: " & RegName & vbCRLF & vbCRLF & "Reason: " & Reason end if end if set oShell = Nothing ;--- Finished Update ------------------------------------------------ CaDebug 0, "Finished RegistryUpdate()" end sub <?NewLine><?NewLine> ;============================================================================ function UpdatePathString(Byval ExistingPath, ByVal Path, ByVal Delimiter, ByVal Inserting) ;============================================================================ ;--- Log start ------------------------------------------------------ CaDebug 0, "UpdatePathString()" VbsCaLogInc 1 CaDebug 0, "Original PATH = " & ExistingPath ;--- Remove any Existing path (looking for EXACT match) ------------- dim Ps Ps = Delimiter & ExistingPath & Delimiter ;;Make it easier to remove existing string... Ps = replace(Ps, Delimiter & Path & Delimiter, ";") ;;Removing existing string ;--- Add the path to the end of the string if we are Inserting ------ if Inserting then ;--- Add to start or end of the search path? ---------------- #if ['{$APPEND=^Y^ $$upper}' = 'N'] ;--- Want to PREPEND ------------------------------------ Ps = Path & Delimiter & Ps #else ;--- Normally APPEND ------------------------------------ Ps = Ps & Delimiter & Path #endif end if ;--- Fix up any duplicated delimiters ------------------------------- do while Instr(Ps, Delimiter&Delimiter) <> 0 Ps = replace(Ps, Delimiter&Delimiter, Delimiter) loop ;--- Remove any delimiters from start and end of string ------------- if left(Ps, 1) = Delimiter then Ps = mid(Ps, 2) end if if right(Ps, 1) = Delimiter then Ps = left(Ps, len(Ps)-1) end if ;--- Exit, log value ------------------------------------------------ CaDebug 0, "New Path = " & Ps UpdatePathString = Ps VbsCaLogInc -1 end function <$/VbsCa> <$VbsCaSetup Binary="UpdateWindowsDeviceSearchPath.vbs" Entry="Append" Seq="InstallInitialize-" CONDITION=^<$CONDITION_EXCEPT_UNINSTALL>^ Type="IMMEDIATE"> <$VbsCaSetup Binary="UpdateWindowsDeviceSearchPath.vbs" Entry="Remove" Seq="InstallInitialize-" CONDITION=^<$CONDITION_UNINSTALL_ONLY>^ Type="IMMEDIATE">