DOS bat file to toggle two additions to windows path

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
LMHmedchem
Posts: 7
Joined: 25 Aug 2013 23:30

DOS bat file to toggle two additions to windows path

#1 Post by LMHmedchem » 25 Aug 2013 23:50

Hello to the forum,

I have two different installs of the cygwin linux tool kit. The starting point for this tool kit is to open a bash shell in a mintty terminal. This is done with a shortcut with the following target,

C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -

In order for things to work properly, I need to add C:\cygwin\bin to the windows path. Since I have two versions of cygwin, at times I need to add C:\cygwin\bin, and at times I need to add C:\cygwin2\bin. They cannot both be in the path at the same time. The string needs to be added to the path for the session and then removed when the session is closed out.

I thought about setting up a bat file that looks like,
SET PATH = C:\cygwin\bin;%PATH%;
start C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -

this should add cygwin to the path and then start the terminal. This works more or less, but I'm not sure that cygwin has actually been added to the path, and I don't know that this addition is temporary for the current session. I looked at using "setlocal", but I don't know what that does in this context. The bat file finishes and closes, leaving the cygwin terminal running. It would seem that setlocal would expire when the bat file closes, so that doesn't seem right since mintty would still be running. I need the addition to the path to expire when the mintty terminal closes. I don't see any practical way to do that, so I think what I need is a bat file that will not close right away but will have to be manually closed. Something like,

Code: Select all

@ ECHO OFF
setlocal
SET PATH = C:\cygwin\bin;%PATH%;
start C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -
echo C:\cygwin\bin added to path
set /p WHATEVER=press enter to exit and clear path
exit


I think this will work, but I have no real way of knowing. Am I even close here???

Thanks for the advice.

LMHmedchem

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: DOS bat file to toggle two additions to windows path

#2 Post by foxidrive » 26 Aug 2013 03:07

The environment variables that are set in any batch file are lost when the batch closes. So permanence is safely out of the way (unless using setx).

This should work - add a single command in each install that has a different name and you can then see which install is active by trying the command.

Code: Select all

@echo off
SET PATH = C:\cygwin\bin;%PATH%;
start "" /b C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -


The /b opens the program in the same console.

LMHmedchem
Posts: 7
Joined: 25 Aug 2013 23:30

Re: DOS bat file to toggle two additions to windows path

#3 Post by LMHmedchem » 26 Aug 2013 23:12

This appears to work. It is hard to tell if the correct directory has been added to the path since cygwin truncates it to some extent. I am wondering what happens if I have a mintty terminal open using the bat file you described and then open another terminal from it's normal shortcut. Is the path correct for the second terminal? I guess I am asking if I have to open every mintty terminal from this bat file for the path to be right.

The reason for this question is that I have other script files that run off of shortcuts. Do I need to have all of these be run through a bat file?

Since one of the installations is something I use only occasionally, maybe it might make more sense to have one cygwin install included in that path as you would normally add it as an environment variable. Then I could have a bat file for the cygwin2 install that would remove cygwin1 from the path and add cygwin2. For normal use, cygwin1 would always be the that path and I would not have to deal with it. If I need cygwin2, I could start a terminal with the bat file that would configure the environment for just the one session.

Does this make sense? I guess I would need to know how to remove something from the path. Also, is there a DOS command that would let me know if a dll at a particular path was loaded?

LMHmedchem

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: DOS bat file to toggle two additions to windows path

#4 Post by foxidrive » 26 Aug 2013 23:38

Every cmd session has it's own environment, which can be modified and it doesn't affect any other cmd session, new or old.

Your scripts run in the cygwin cmd session, right?

One way to check which one is active, is to copy ls.exe to aa.exe in cygwin1 and copy ls.exe to bb.exe in cygwin2.
If you can run aa then you know you are in cygwin1 and if you can run bb you are in cygwin2.

LMHmedchem
Posts: 7
Joined: 25 Aug 2013 23:30

Re: DOS bat file to toggle two additions to windows path

#5 Post by LMHmedchem » 27 Aug 2013 14:59

foxidrive wrote:Every cmd session has it's own environment, which can be modified and it doesn't affect any other cmd session, new or old.
I found this in another group,

"As it is: no. Unix shells work like that, but DOS doesn't. In fact, when you set a variable in a DOS batch file its value stays until you start the COMMAND.COM (or whatever replacement you use) anew. This is the reason why you can set the PATH variable in AUTOEXEC.BAT and have that change be persistent."

This would imply that changes to the path would be persistant, even after the cmd session is closed. Perhaps I am not understanding that correctly.

foxidrive wrote:Your scripts run in the cygwin cmd session, right?
No, not any more. Once, when cygwin bash was running, it was using cmd as the terminal. Now cygwin mintty is used as the terminal. If I start a shell from the desktop shortcut, I end up with a mintty.exe process and a bash.exe process. There is no cmd process running. With the bat file your suggested, the bat file adds C:\cygwin\bin to PATH, starts the mintty terminal with start "" /b C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -, and then the bat file exits. I'm not sure the the /b is doing anything since the bat file closes and there is no cmd running. Mintty may inherit from the bat file. It sounds like the addition to the path is independent of the shell session, but I don't know if that is right either. I guess I don't know much at this point.

foxidrive wrote:One way to check which one is active, is to copy ls.exe to aa.exe in cygwin1 and copy ls.exe to bb.exe in cygwin2.
If you can run aa then you know you are in cygwin1 and if you can run bb you are in cygwin2.
There are a number of ways for me to determine which install I am in. The bigger issue is which version of the cygwin1.dll is loaded. That is loaded based on the value in the PATH. If C:\cygwin\bin is in the path, one version of the dll gets loaded. If C:\cygwin2\bin is in the path, the second version would get loaded. If the path does not match, it would be possible to start a program from inside one of the installs while the other dll was loaded.

I do think now that the best option is to have C:\cygwin\bin in the path by adding it as an environment variable. This is the version that will be used most of the time. If I need the other version, I would want a bat file that would remove C:\cygwin\bin from the path and add C:\cygwin2\bin. I think it would make sense for that bat file to stay open until I was done with the cygwin2 stuff. After I was done, I would enter something into the interactive bat file to let it know to remove C:\cygwin2\bin from the path and restore C:\cygwin\bin.

If that makes sense, I have no idea as to how to go about it.

LMHmedchem

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: DOS bat file to toggle two additions to windows path

#6 Post by penpen » 28 Aug 2013 16:25

LMHmedchem wrote:
foxidrive wrote:Every cmd session has it's own environment, which can be modified and it doesn't affect any other cmd session, new or old.
I found this in another group,

"As it is: no. Unix shells work like that, but DOS doesn't. In fact, when you set a variable in a DOS batch file its value stays until you start the COMMAND.COM (or whatever replacement you use) anew. This is the reason why you can set the PATH variable in AUTOEXEC.BAT and have that change be persistent."

This would imply that changes to the path would be persistant, even after the cmd session is closed. Perhaps I am not understanding that correctly.
This is true for MS-DOS based OSes: MS-DOS, Win1-3.11/95/98/ME.
The environment variables of all windows versions above are taken from the registry only:
HKCU\Environment, or
HKLM\System\CurrentControlSet\Control\Session Manager\Environment, or
... .

If you start a command shell, by executing a batch file, a DOS Environment block is created.
This is a copy of the registry values from the registry.
The variables in this block may be changed as you wish using set, but they don't change the registry values
(except when using setx).
So if you start another batch it has its own environment block, independent of the first one.

LMHmedchem wrote:
foxidrive wrote:Your scripts run in the cygwin cmd session, right?
No, not any more. Once, when cygwin bash was running, it was using cmd as the terminal.
I'm not sure, but i think you meant cygwin bash uses the cmd shell, that was created if cmd is executed,
in the same way powershell uses it.

LMHmedchem wrote:Now cygwin mintty is used as the terminal. If I start a shell from the desktop shortcut, I end up with a mintty.exe process and a bash.exe process. There is no cmd process running.
If you start it this way, then the program is started with the default "registry" environment set of variables, i think.
If it is a link to a batch file, then the environment set of the batch file is used.

LMHmedchem wrote:With the bat file your suggested, the bat file adds C:\cygwin\bin to PATH, starts the mintty terminal with start "" /b C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -, and then the bat file exits.
(...)
The bigger issue is which version of the cygwin1.dll is loaded. That is loaded based on the value in the PATH.
(...)
The environment block of the batch file should be passed to the programs that are called, as a copy,
so even if the calling process ends the environment variable set should be the same.
But the cygwin terminal may be programmed to ignore such a local environment block
and load the environment variables from registry.
If i remember right, you may check this using "printenv" within the cygwin shell.

LMHmedchem wrote:I do think now that the best option is to have C:\cygwin\bin in the path by adding it as an environment variable. This is the version that will be used most of the time. If I need the other version, I would want a bat file that would remove C:\cygwin\bin from the path and add C:\cygwin2\bin. I think it would make sense for that bat file to stay open until I was done with the cygwin2 stuff. After I was done, I would enter something into the interactive bat file to let it know to remove C:\cygwin2\bin from the path and restore C:\cygwin\bin.

If that makes sense, I have no idea as to how to go about it.

LMHmedchem
If the cygwin terminal ignores a local environment block, then this may indeed be the best,
although i then would use subst to switch between the different versions.
BUT if cygwin make use of the given local environment block, foxidrive's solution is better,
as it doesn't blow up the global variables.

penpen

Jess Selien
Posts: 13
Joined: 26 Sep 2012 12:08

Re: DOS bat file to toggle two additions to windows path

#7 Post by Jess Selien » 28 Aug 2013 16:47

For temporary kick off of a program, I like to use the start command like this...

rem
rem - start xyz app-
chdir /d "path"
start app.exe
rem

This will start you off with the computer looking in that directory for any other files it may need to process.

If you want a more permanent change for a long program or using a program often, you can alter the path setting or the environmental variable path list.

LMHmedchem
Posts: 7
Joined: 25 Aug 2013 23:30

Re: DOS bat file to toggle two additions to windows path

#8 Post by LMHmedchem » 02 Sep 2013 22:59

If I understand your post, when a cmd shell is opened, it gets a set of environment variables from entries in the registry. I believe the same is true when you start an instance of bash running in a mintty terminal. The path will contain only what is currently in the registry.

If I start a cmd shell from a bat file and use SET, I can add to the path. The additions to the path will be in scope as long as the bat cmd session is open. If the cmd shell calls any programs, those programs will receive a copy of PATH as read from the registry and any additions that were made in the cmd session (I guess like fork???). Even if the bat cmd session closes, any programs called from the cmd session will retain their modified copies of PATH. I have confirmed this with my current setup.

I have two installations of cygwin. At this point, neither location is in the path (in the registry entries). I have a .bat file from which I can start cygwin mintty/bash of each installation. For installation 1, the bat file is,

Code: Select all

@echo off
SET PATH = C:\cygwin\bin;%PATH%;
start "" /b C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -


If I use this bat to start a bash shell and run printenv, I can see that C:\cygwin\bin is now in the PATH

PATH = C:\cygwin\bin;C:\Program Files\Intel\iCLS Client\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Emergent 5.3.9 (32-bit)\bin;

If I open bash from the second bat file,

Code: Select all

@echo off
SET PATH = C:\cygwin2\bin;%PATH%;
start "" /b C:\cygwin2\bin\mintty.exe -i /Cygwin-Terminal.ico -


I find that the cygwin2 install is now in the path,

PATH = C:\cygwin2\bin;C:\Program Files\Intel\iCLS Client\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Emergent 5.3.9 (32-bit)\bin;

This more of less confirms that I can create the proper environment for each install by always starting cygwin programs from a bat file that will pre-set the environment variables. This solution is reasonable, but it means that every shortcut for a cygwin program needs to have an accompanying bat file to start it. That would not be the end of the world, but since I don't use the second install very often, I think it makes more sense to have the cygwin1 install be an environment variable in the registry and therefore the default for all cygwin shortcuts. If I need the cygwin2 install, I could use a bat file that would remove C:\cygwin\bin from the environment block and add C:\cygwin2\bin. This would configure the cygwin2 environment properly for the small number of cases where I need it and let the rest work automatically.

I have not idea how to write a bat file that would do that, so if this is a reasonable option, I would appreciate some suggestions on how to go about that.

LMHmedchem

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: DOS bat file to toggle two additions to windows path

#9 Post by penpen » 03 Sep 2013 06:35

LMHmedchem wrote:If the cmd shell calls any programs, those programs will receive a copy of PATH as read from the registry and any additions that were made in the cmd session (I guess like fork???)...
I'm not sure what you are meaning.
Fork copies the whole process data, while in this case only a new process is created.
But if you mean that the newly created process is allowed to make a flat copy of some needed data, then you're right.

LMHmedchem wrote:I have not idea how to write a bat file that would do that, so if this is a reasonable option, I would appreciate some suggestions on how to go about that.
Assumed, that there is no path containing doublequotes, this may work for you:

Code: Select all

@echo off

:: remove "C:\cygwin\bin" from PATH
set "PATH=;%PATH%;"
set "PATH=%PATH:;;=;%"
set "PATH=;%PATH:;C:\cygwin\bin;=;%;"
set "PATH=%PATH:;;=%"

set "PATH=C:\cygwin2\bin;%PATH%"
start "" /b C:\cygwin2\bin\mintty.exe -i /Cygwin-Terminal.ico -

Btw: Note that spaces may be part of the variable name, so SET PATH = 1 would create a variable named "PATH " with content " 1",
but will not alter the "PATH" variable.

penpen

LMHmedchem
Posts: 7
Joined: 25 Aug 2013 23:30

Re: DOS bat file to toggle two additions to windows path

#10 Post by LMHmedchem » 04 Sep 2013 18:29

I notice in your script that you enclose the value you assign to PATH in quotes,

set "PATH=C:\cygwin2\bin;%PATH%"

where the examples I was working with did not have the quotes,

SET PATH=C:\cygwin\bin;%PATH%;
(I removed the spaces as you suggested).

I don't see any differences in the output from printenv when I run it both ways. Is there some reason for the quotes?

LMHmedchem

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: DOS bat file to toggle two additions to windows path

#11 Post by penpen » 05 Sep 2013 06:48

Yes, there is one:
If a batch variable contains special characters, that have a special meaning in batch scripts,
and so the command line interpreter reacts on them in a different way.
If you encapsulate these characters within doublequotes, the command line interpreter
treats them as normal characters with no special meaning.
Another option were, to escape these special characters, but this is not simple:
You have to find them, and the % has to be escaped in another way,
depending on if you execute from a batch or from DOS shell.
For example:

Code: Select all

set "variable=i like to echo this: %% & echo that: )"
echo 1. %variable%
echo 2. "%variable%"
echo 3. i like to echo this: %%%% ^& echo that: ^)
echo 4. i like to echo this: %% ^& echo that: ^)
If there are no doublequotes in the variable and extensions are enabled (default),
then assigning the variable value to another variable is easy, just use this form:

Code: Select all

set "variable=%another variable%"

Btw: If there are double quotes within the variable, this does not mean it the assignment will fail,
when not using this form, but it may fail:

Code: Select all

set ok=This is "OK"
set fail=This " fail & echo " works.

set "test1=%ok%"
set "test2=%fail%"

echo %test1%
echo %test2%

penpen

Post Reply