5

I am writing an batch file in Windows to run post-installation scripts, and one of the things that needs to be done is to add a directory to the system path.

The script is working, and it does something like this:

setx Path "%PATH%;c:\path\to\add" -m

This is setting the path correctly, but this script could potentially be run multiple times if the user reinstalls the program.

I would like to search the string for c:\path\to\add so I don't keep adding the same path over and over to the system path. This is pretty trivial in Linux with sed, but I don't know what the command is in Windows. I've found findstr, but this seems to only work on files.

Is this possible in Windows without installing additional software?

EDIT:

I'm using Inno Setup to create the install executable.

beatgammit
  • 19,817
  • 19
  • 86
  • 129
  • what installation software are you using? – David Heffernan Jul 11 '11 at 22:53
  • I'm using Inno Setup. It creates an installer based on input. There's a way to run commands before and after installation. I edited my post with this info. – beatgammit Jul 11 '11 at 22:54
  • 2
    here's your answer http://stackoverflow.com/questions/3304463/how-do-i-modify-the-path-environment-variable-when-running-an-inno-setup-installe – David Heffernan Jul 11 '11 at 22:58
  • @David Heffernan- Is there a way to do this without using Pascal? I'd like to do this using just built-in commands, like sed on *nix. – beatgammit Jul 11 '11 at 23:01
  • Pascal Scripting is built into InnoSetup. Beware: Using an external script is may introduce dependencies that may not always be present. – Robert Love Jul 12 '11 at 05:05
  • @David Heffernan- Just not a big fan of pascal. Also, I may not stick with Inno Setup, so a more generic solution would be better. – beatgammit Jul 12 '11 at 06:14

5 Answers5

3

At the risk of some downvotes till an expert provides a sound way of doing this,
the below removes the specific path from the environment variable if it exists, so that it can be added again:

set str=%path%
:: str is the same with path

set str=%str:;C:\Path\To\Add=%
:: ";c:\path\to\add" is now removed from str

setx Path "%str%;c:\path\to\add" -m
:: proceed with setting the path


This carries the risk of removing the string if it is in fact actually a part of a path, for instance c:\path\to\add\somefolder. Also if the path actually ends with a \, or it is the first entry and it in fact does not start with ;, etc..

Various forms can be called consecutively to circumvent some of these,

set str=%str:;C:\Path\To\Add\;=;%
set str=%str:;C:\Path\To\Add;=;%
set str=%str:;C:\Path\To\Add\=%
set str=%str:C:\Path\To\Add\;=%
set str=%str:;C:\Path\To\Add=%

But, AAMOF I'n not sure this is a sane way of doing this..

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • +1 because this is pretty clever. I didn't know about string manipulation in batch, and this led me to [this page](http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Remove).I like this solution, but I'll wait for a bit to see if there are any cleaner solutions. – beatgammit Jul 12 '11 at 03:23
  • Very good, I learned something new here today. So for a simple batch script where the setx is not required, a _prepend_ can be distilled down to: `set PATH=%PATH:;D:\my\app\bin=%` `set PATH=D:\my\app\bin;%PATH:D:\my\app\bin;=%` (although the repetition of `D:\my\app\bin\` is somewhat unsatisfactory) – Ed Randall Dec 16 '13 at 11:49
1

This is my code snippet to find the "cvsnt" path in the PATH variable.

if not "x%PATH:cvsnt=%" == "x%PATH%" goto proceed
set PATH=w:\build-repository\cvsnt\2.5.03-2382;%PATH%
echo Path added
:proceed

The part to look at is

not "x%PATH:cvsnt=%" == "x%PATH%"

First I replace all occurrences of "cvsnt" with an empty string. The result is compared to PATH without replacement of "cvsnt". If they are not equal because of "cvsnt" was replaced then it exists in PATH and the code can proceed.

The starting x before %PATH% is only a placeholder to protect against certain "improper" starting characters. see Batch file: Find if substring is in string (not in a file)

Community
  • 1
  • 1
Christoph Dittberner
  • 1,366
  • 2
  • 9
  • 12
1

The setx utility has a drawback, it can not handle variables longer than 1024 characters.

I have been wrote a script to handle cases longer than the limit and without a need to install anything. Answered the question here: Set environment variables with NSIS in Window 7

Community
  • 1
  • 1
Andry
  • 2,273
  • 29
  • 28
0

This is a bit of a hackish workaround, but follows the logic you expect:

  1. Search the PATH
  2. Conditionally add to the PATH

It never removes anything from the PATH, so there's no fear of screwing up Windows by removing something accidently. Also, it checks the PATH variable directly, so you don't have to worry about another file with the same name that lives somewhere on the PATH.

echo %PATH% > myTmpPath.tmp
find /C /I "c:\path\to\add" myTmpPath.tmp
if %ERRORLEVEL% neq 0 setx PATH "%PATH%;c:\path\to\add"
del myTmpPath.tmp

I hate using temporary files, but it's quick and dirty, and probably safer than removing something from the PATH.

The third line is the only tricky one. Basically, this line tests the outcome of the FIND command above. Rob van der Woude states:

FIND returns an errorlevel of 1 or higher if the search string wasn't found.

He also explains:

Some executables return negative numbers for errorlevels! However, this can be fixed by using the following code to check for non-zero return codes:
IF %ERRORLEVEL% NEQ 0 ...

Rustavore
  • 1,845
  • 2
  • 23
  • 31
0

Instead of adding the path each time - you could check if the executable you are looking for can be found within the path using a command like this:

for %f in (cmd.exe) do if [%~$PATH:f]==[] setx Path "%PATH%;c:\path\to\add" -m

Make sure to check for /? to read more about the magic of %~$PATH:f.

Martin
  • 10,738
  • 14
  • 59
  • 67