0

Locate if the program exists and set a custom variable in batch windows.

I wonder if a specific program is installed and know its location. The problem is that there are two unknowns. The first is the platform between x86 and x64. The second is the version numbers defined in the installation path. A constraint is added to this, if multiple versions exist, choose the latest and preference x64 platform.

GhostScript and ImageMagick example, there may be more than one version installed:

C:\Program Files\gs\gs9.16\bin
C:\Program Files (x86)\gs\gs9.15\bin
C:\Program Files\ImageMagick-6.9.2-Q16
C:\Program Files\ImageMagick-6.9.2-Q8

I have a track but it is not conclusive.

@ECHO OFF    
@SETLOCAL enableexpansion
@FOR /F "tokens=*" %%G IN ('@dir/b /s /a:d "%ProgramFiles(x86)%\gs\gs*" "%ProgramFiles%\gs\gs*" "%ProgramFiles%\doesnt-exist*"') DO @SET _GSWIN="%%G\bin\gswin.exe"
@echo %_GSWIN%
ENDLOCAL
Paul
  • 2,620
  • 2
  • 17
  • 27

1 Answers1

1

Running in a command prompt window set lists all environment variables for current user.

There are system variables which exist for all user accounts and user variables whereby there are by default only 2 user variables defined for user customization in System Control Panel: TEMP and TMP which replace the system variables TEMP and TMP of system account. The other user account related variables like USERPROFILE, USERNAME, etc. are defined by Windows automatically.

On Windows x86 there is only the variable ProgramFiles while on Windows x64 there are the variables ProgramFiles and ProgramFiles(x86).

So the easiest and in my point of view best method to find out if batch file is executed on a machine running Windows x86 or x64 is checking existence respectively value of environment variable ProgramFiles(x86) as the batch code below demonstrates.

I nearly never recommend searching for an executable in directories by chance. Most installers give the user the opportunity to install an application into any directory. Therefore searching for an application directory or executable in %ProgramFiles% and %ProgramFiles(x86)% is in general not a good idea.

Most application installers add something to registry containing version and directory of installed application. The reason is simple. The installer needs to know itself on update/upgrade if a previous version is already installed, which version the installed version has, and where the application is installed.

Many installers add a registry key for uninstall and many add the executable of the installed application also to registry key App Paths. For details about App Paths see

I have installed only Ghostscript 8.71 on an old machine running German Windows XP x86. Installer of Ghostscript v8.71 has not added any executable key to App Paths. But the Ghostscript installer has added the registry key GPL Ghostscript to HKLM\Software with one more subkey being version of installed Ghostscript and two registry values.

[HKEY_LOCAL_MACHINE\SOFTWARE\GPL Ghostscript\8.71]
"GS_DLL"="C:\\Programme\\Ghostscript\\gs8.71\\bin\\gsdll32.dll"
"GS_LIB"="C:\\Programme\\Ghostscript\\gs8.71\\lib;C:\\Programme\\Ghostscript\\fonts"

Ghostscript v8.71 is installed into standard program files directory of German Windows XP x86.

Therefore I suggest to get all subkeys of GPL Ghostscript to determine highest version of an installed Ghostscript and the path of the DLL file from string value GS_DLL.

The batch code below demonstrates evaluation of the standard program files directories of Windows and how to get directory and version of an installed Ghostscript with highest version number.

@echo off
setlocal EnableExtensions EnableDelayedExpansion

if "%ProgramFiles(x86)%" == "" (
    echo Windows x86 is running on this machine.
    echo.
    echo The standard program files directory is:
    echo    %ProgramFiles%
) else (
    echo Windows x64 is running on this machine.
    echo.
    echo The standard program files directories are:
    echo    %ProgramFiles%
    echo    %ProgramFiles(x86)%
)
echo.

call :GetGsData

if "%GhostscriptDirectory%" EQU "" (
    echo Ghostscript is not installed on this machine.
    goto EndBatch
)

echo Found Ghostscript version %GhostscriptVersionMajor%.%GhostscriptVersionMinor% in directory:
echo    %GhostscriptDirectory%
goto EndBatch


rem Look in registry under "HKEY_LOCAL_MACHINE\Software\GPL Ghostscript"
rem and also under "HKEY_LOCAL_MACHINE\Software\Wow6432Node\" for one or
rem more installed versions of Ghostscript and get latest version of a
rem still installed Ghostscript as well as its installation directory.

:GetGsData
set "GhostscriptVersionMajor=0"
set "GhostscriptVersionMinor=0"
set "GhostscriptDirectory="

rem call :GetGsVersion "HKCU\Software\GPL Ghostscript"
call :GetGsVersion "HKLM\Software\GPL Ghostscript"
call :GetGsVersion "HKLM\Software\Wow6432Node\GPL Ghostscript"
goto :EOF

:GetGsVersion
for /F "skip=2 tokens=4,5 delims=.\" %%I in ('%SystemRoot%\System32\reg.exe query "%~1" 2^>nul') do (
    call :GetGsDirectory "%%I" "%%J"
)
goto :EOF


rem This subroutine queries for string value GS_DLL in found Ghostscript
rem registry key. If this string value is not found, this registry key
rem is ignored and nothing is changed on the variables for Ghostscript.

rem But if the string value GS_DLL is found, it is checked next, if the
rem DLL specified with full path really exists. The subroutine is exited
rem with no change if the DLL does not exist (anymore).

rem But if the DLL exists, it is checked if the version of this installation
rem of Ghostscript is higher than a perhaps already found installation of
rem Ghostscript before. The variables for Ghostscript are update if this
rem installation is of a newer version as previous installation.

:GetGsDirectory
for /F "skip=2 tokens=1,2*" %%A in ('%SystemRoot%\System32\reg.exe query "HKLM\Software\GPL Ghostscript\%~1.%~2" /v GS_DLL 2^>nul') do (

    rem Is this the line with the string value GS_DLL?
    if /I "%%A" == "GS_DLL" (

        rem Does the DLL file not exist?
        if not exist "%%~C" goto :EOF

        rem Is major version lower than already determined major version?
        if %~1 LSS !GhostscriptVersionMajor! goto :EOF

        rem Is major version equal already determined major version, but
        rem minor version is lower than already determined minor version?
        if %~2 EQU !GhostscriptVersionMajor! (
            if %~2 LSS !GhostscriptVersionMinor! goto :EOF
        )

        rem Okay, this version is higher than already determined version.
        set "GhostscriptVersionMajor=%~1"
        set "GhostscriptVersionMinor=%~2"

        rem Get drive and path of DLL file.
        for %%D in ("%%~C") do set "GhostscriptDirectory=%%~dpD"
        rem Remove directory "bin" from path of the DLL file.
        set "GhostscriptDirectory=!GhostscriptDirectory:\bin\=!"
        goto :EOF
    )
)
rem Exit subroutine with no change as string value of DLL file not found.
goto :EOF


:EndBatch
endlocal
echo.
pause

It would be good for understanding the processing of the reg outputs to run once in a command prompt window the following commands:

  • reg query "HKLM\Software\GPL Ghostscript"
  • reg query "HKLM\Software\GPL Ghostscript\9.16" /v GS_DLL

For understanding the other used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • for /?
  • goto /?
  • if /?
  • set /?
  • reg query /?

If Ghostscript installer supports also installation of Ghostscript for current user only which I don't know, it would be good to uncomment the line

rem call :GetGsVersion "HKCU\Software\GPL Ghostscript"

by removing command rem from beginning of line.

There is no HKCU\Software\Wow6432Node. (Or more precise there should be no Wow6432Node in HKEY_CURRENT_USER\Software according to specification of Microsoft.)

I can't suggest something similar for ImageMagick as I don't have this application installed on any of my computers. I'm using IrfanView (free for private usage).

Community
  • 1
  • 1
Mofi
  • 46,139
  • 17
  • 80
  • 143