AddRemove Programs IsInstalled Test

From NSIS Wiki
Jump to navigationJump to search
Author: Zinthose (talk, contrib)


Summary

Header/Include to extent the LogicLib to perform a simple search for installed applications based on the Display Name.

NSISpcre plug-in is supported for regular expression pattern matching but is not required for simple explicit text matching.

Example

Default configuration is to attempt to load the NSISpcre plug-in but fail over to explicit pattern matching when the plug-in is not available.

Upon a successful match, the ${ARPRegPath} variable is populated with the registry path to the identified entry.

## Precompiler Flags
;    !define ARP_IsInstalled_NoRegExp    #   Disable Regular Expression Support
;    !define ARP_IsInstalled_RegExpReq   #   Require Regular Expression Support
 
 
!include ARP_IsInstalled.nsh
 
OutFile ARPTest.exe
ShowInstDetails show
 
Section Main
 
    ## If you need to check the 64bit registry region then use:
    ;   SetRegView 64
 
    ## To switch back to the 32bit registry branch use:
    ;   SetRegView 32
 
    ${If} ${IsInstalledARP} "(?:Microsoft)? .NET Framework 3.5 SP1"
        DetailPrint "Found It: ${ARPRegPath}"
    ${Else}
        DetailPrint "Darn... Not found!"
    ${EndIf}
SectionEnd

ARP_IsInstalled.nsh

!warning "ARP_IsInstalled is an experiment and likely broken... make sure you test it thoroughly before using in a production environment!"
 
!verbose push
!verbose 3
!include LogicLib.nsh
!verbose ${LOGICLIB_VERBOSITY}
 
!ifndef __ARP_IsInstalled__
!define __ARP_IsInstalled__
 
## PreCompiler Checks and Prerequisite Checks
    !ifdef ARP_IsInstalled_NoRegExp & ARP_IsInstalled_RegExpReq
        !error "It is impossible to both require and disable Regular Expression support!"
    !endif
 
    !ifndef ARP_IsInstalled_NoRegExp
        !ifndef PCRELIB_INCLUDED
            !ifdef ARP_IsInstalled_RegExpReq
                !include NSISpcre.nsh
            !else
                !include /nonfatal NSISpcre.nsh
                !ifndef PCRELIB_INCLUDED
                    !warning "-- NSISpcre Plug-in Required for Regular Expression Support."
                    !warning "-- Switching to explicit matching mode."
                !endif
            !endif
            !ifdef PCRELIB_INCLUDED
                !ifmacrodef REMatches
                    !insertmacro REMatches
                !endif
            !else
                !define ARP_IsInstalled_NoRegExp
            !endif
        !endif
    !else
        !warning "Regular Expression Pattern Matching is disabled! Using explicit matching mode."
    !endif
 
## Temporary Variable Creator
    !ifmacrondef _TEMP_VAR
        !macro _TEMP_VAR _VAR
            !ifndef _TEMP_VAR_${_VAR}
                !define _TEMP_VAR_${_VAR}
                Var /GLOBAL _TEMP_VAR_${_VAR}  ; Temporary variable to aid the more elaborate logic tests
            !endif
        !macroend
    !endif
 
## Example:
##      ${If} ${IsInstalledARP} `(?:Microsoft )?Office`
    !ifmacrondef _IsInstalledARP
        !macro _IsInstalledARP _a _b _t _f
            !verbose push
            !verbose ${LOGICLIB_VERBOSITY}
 
            ## Ensure Temporary Variable are Defined
                !define _TMP_RegPath `SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall`
                !insertmacro _LOGICLIB_TEMP
                !insertmacro _TEMP_VAR RegExp
                !insertmacro _TEMP_VAR RegKey
                !insertmacro _TEMP_VAR RegEnum
 
            ## Special Variable to store found Registry Path
                !insertmacro _TEMP_VAR ARP_RegPath
                !ifndef ARPRegPath
                    !define ARPRegPath $_TEMP_VAR_ARP_RegPath
                !endif
 
            ## Define Variables
                StrCpy $_TEMP_VAR_RegEnum   0
                StrCpy $_TEMP_VAR_RegKey    `${_TMP_RegPath}\`
                StrCpy $_TEMP_VAR_RegExp    `${_b}`
 
                !insertmacro _IncreaseCounter
 
             ## Start ARP Loop
 
                ## Create MAcro Safe Label For start of Do Loop 
                    _LogicLib_Label_DO_${LOGICLIB_COUNTER}:
 
                ## Clear the ${ARPRegPath} Value
                    StrCpy $_TEMP_VAR_ARP_RegPath ""
 
                ## Enumerate through the Add & Remove Programs Registry Branch to search for the supplied Regular Expression Pattern
                    EnumRegKey $_TEMP_VAR_RegKey HKLM `${_TMP_RegPath}` $_TEMP_VAR_RegEnum
 
                ## If the Enumerated value is empty then we are at the end of the branch, exit loop & LogicLib Query
                    StrCmp $_TEMP_VAR_RegKey "" `${_f}`
 
                ## Set the ${ARPRegPath} Value Just in case we have a match
                    StrCpy $_TEMP_VAR_ARP_RegPath `${_TMP_RegPath}\$_TEMP_VAR_RegKey`
 
                ## Get the Displayname for Our Expression matching
                    ReadRegStr $_LOGICLIB_TEMP HKLM $_TEMP_VAR_ARP_RegPath "DisplayName"
 
                ## Increment the Enumeration counter for the next leaf on the branch
                    IntOp $_TEMP_VAR_RegEnum $_TEMP_VAR_RegEnum + 1
 
                !ifndef ARP_IsInstalled_NoRegExp
                    ## LogicLib/NSISpcre Regularexpression query, if success then exit loop/LogicLib Query, Else continue loop
                        !insertmacro _=~ $_LOGICLIB_TEMP $_TEMP_VAR_RegExp `${_t}` _LogicLib_Label_DO_${LOGICLIB_COUNTER}
                !else
                    ## RegEx Free DisplayName check
                        !insertmacro _== $_LOGICLIB_TEMP $_TEMP_VAR_RegExp `${_t}` _LogicLib_Label_DO_${LOGICLIB_COUNTER}
                !endif
 
            ## End ARP Loop
 
            !undef _TMP_RegPath
            !verbose pop
        !macroend
        !ifndef IsInstalledARP
            !define IsInstalledARP `"" IsInstalledARP`
        !endif
    !endif
!endif
!verbose pop

Apologies

The code is a bit of a mess, and I'm still a n00b ;o)