MAKEMSI quickly and reliably creates MSI files in a non-programmatic way
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
[Bottom][Contents][Prev]: Read a file List[Next]: Remove Trailing Slashes from Directory Names
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->Tips and Tricks->File and Directory->Registry Appending

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">


Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: Read a file List[Next]: Remove Trailing Slashes from Directory Names


MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Saturday May 28 2022 at 3:11pm
Visit MAKEMSI's Home Page
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.