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]: Share Creation
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 for the Windows SDK (Windows Installer) area.This external link was OK when tested at 15 Nov 2008Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: Read a file List[Next]: Share Creation


MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Saturday November 15 2008 at 2:05pm
Visit MAKEMSI's Home PageThis external link was OK when tested at 7 Nov 2008

HTML page dated Mon, 29 Jan 2007 00:11:11 GMT
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006 & 2007 for the Windows SDK (Windows Installer) area.This external link was OK when tested at 15 Nov 2008