My program is a GUI based install and run tool for a certain program, when I say GUI, I mean batch files. When it installs a program, it needs to always know where it is installed, currently, it just records it into a variable, but that only works if they don't shut the program and return at a later date, so I wanted to know a way of storing a permanent variable.
I was thinking maybe something like this:
set instloc='C:\Users\JoeBloggs\Documents\Environment\My Programs\This program.exe'
echo %instloc% > instloc.txt
attrib +h instloc.txt
But I was wondering if there was a dedicated command for it
Set modifies the current shell's environment values, and the change is temporary but available immediately. The change will not affect other shells that are running, and as soon as you close the shell, the new value is lost.
setx modifies the value permanently, which will affect in all future shells, but does not modify the environment of the shells already running. You have to exit the shell and reopen it before the change will be available, but the value will remain modified until you change it again.
In your case, instead of using set use setx:
setx instloc "C:\Users\JoeBloggs\Documents\Environment\My Programs\This program.exe"
Related
I have a cmd batch script that sets some variables. I tried the command SET, but it lists all the environment variables, including the system default ones (or Global ones). I am interested in knowing exactly the ones which are being set inside that script. Is there any way to do that from the command line?
Also, let's say I exported all the environment variables in a text file. Can I set them all at once in a new cmd.exe instance by providing the file path? Or, looping through each one of them is the only option?
Edit: I can't modify the original batch script and don't have any control over it's future changes.
Actually i want to run 2 bat scripts , first script will set a system variable set NEWPATH="E:/Some" and second script will show the path of that variable: echo %NEWPATH%. this is not working with the same server at first time , when i restart server that will show the path otherwise it'll show nothing. so can anyone help me on that?
I don't fully grasp your problem, but here's a couple of observations.
Some theory
Environment vaiables set in a batch file (which is being executed by a shell process, cmd.exe)—or any other kind of process—can only be set for that very process.
That is, each process has a special block with environment variables made available to it by the OS when that process is created.
This also means that when the process which set an environment variable is finished, it's environment block is gone.
An environment variable can be inherited by a process which was started by the process which has set that environment variable.
What happens in your case
What this means is that if you run two batch scripts in a sequence, this means
The first cmd.exe process is strated, the batch script it executed
set an environment variable; then the process is gone, and its environment block is gone, too.
Then another cmd.exe is started, it inherits the environment block of your host process (written Go), but as you can see, whatever is set by a first batch script is not available.
What you can do about it
There are two possible ways to solve the problem:
Make the first batch script call the second one by itself.
In this case the second cmd.exe will inherit the environment variables
set by the first script and will hence "see" them.
Note that the Windows batch command language supports the calls
command to call out to other batch scripts by their pathnames.
Make the first script communicate the value of that variable to your host process and then arrange in the host process for the second cmd.exe to have the indicated variable with the indicated value in its environment.
Say, the first script could just do something like
echo VARNAME=value
to have
VARNAME=value
printed to its stdout.
Your Go process could parse that output, tear it apart on the =
character, sanitize to not affect "interesting" variables like PATH,
USERPROFILE etc, and then the host process could do
env := os.Environ()
env = env.append("VARNAME=value") // real value here
...
cmd := exec.Command(`cmd.exe`, `/c`, secondScriptFilePath)
cmd.Env = env
...
cmd.Run() // or whatever
The second case can be done a bit differently: the host process
can call os.Setenv("VARNAME=value") to make this variable appear in its
own environment block; it then will be inherited automatically by whatever processes it starts after that.
Update to address the OP's comment
…script files will be in client side so i can't add a line
echo VARNAME=value .
so is there any other possible way to do this?
There's another approach which might work in your case.
The idea is that cmd.exe is just a shell: when it's started non-interactively (that's what is done by exec.Command("cmd.exe"))
it reads commands from its standard input stream and executes them one by one—until the stream is closed (by the sender).
Hence you can do the following:
Start cmd.exe while connecting an instance of io.Pipe to its Stdin.
Open the first script yourself and shovel it at the running cmd.exe via the pipe set up on the first step.
Don't forget to Flush() the pipe.
You can use the io.Copy() function which sends all the data from an opened io.Reader to some io.Writer.
Leave the shell instance running.
When it's time, read the second script and shovel it at the same shell.
Since the shell is the same, the second script would run as if it were physically appended to the first one, and will see all the variables set by the first script.
I have experienced (random) weird corruption of environment variables from consecutive calls of multiple (3d party) batch scripts. These individual scripts call #echo off.
Is it possible to force echo on by environment variable/other means or I need to go to the every script and comment/remove the line to see what has been actually executed?
I'm quite sure that this is not possible. You can't force your system to simply ignore a command like ECHO OFF. The only way to I can think of as a workaround is to write a script which replaces all ECHO OFF commands in you bat files before execution and restoring them afterwards.
Take a look at this: https://superuser.com/questions/351661/how-do-i-force-echo-on-for-a-batch-file-without-editing-the-file
I have this batch which executes on the server computer. There is a scheduled job which runs the batch. The Batch detects a particular file and then it executes an sqlcmd like below:
if not exist %TRIG_FILE% goto No_Triggers
sqlcmd
-S %WSL_SERVER%
-d %WSL_DATABASE%
-E
-Q "DECLARE #RES integer;DECLARE #RET varchar(1);DECLARE #MSG varchar(65);EXEC Ws_Job_Release 1,'Release Job Unlock Batch','All',0,0,'Unlock_Batch',#RET OUTPUT,#MSG OUTPUT,#RES OUTPUT"
My question is - how did the batch know what the %WSL_SERVER% variable is, because when I look at the script, there is nowhere in there which sets the %WSL_SERVER% variable.
This is the first time I'm reading a .bat script, I know a fair bit of programming, but I can't see how that variable was passed into this script so that it knows which server. There's no other batch calling this, it's from the batch run by the scheduler.
thanks
gemmo
Most likely the WSL_SERVER and WSL_DATABASE are global environment variables initialised every time with your Windows session. That means they exist (are defined) in every CMD session and thus in every batch script. You can open a new Command Prompt window and issue this command
SET WSL
which will (try to) display all environment variables, whether global or local, whose names start with WSL. My guess is the output will show you at least the two WSL variables used in your script.
There is a number of global variables pre-defined and maintained by the OS. Yours, however, are probably user-defined (just my guess based on the fact that my system does not have them). User-defined variables can be created by third-party software or your own (maybe someone else's) batch scripts, as well as with a standalone invocation of the SETX command:
SETX VarName "Value"
You can use that command to change the value of any of your variables globally. Note that you can also change that value temporarily only, for the duration of the script, using the SET command as usual, if global change is undesirable:
SET "VarName=Value"
I'm using cl in cmd and having to run vcvars32.bat every time I open a cmd window is really a pain in the axx. Can anyone offer a way of running it automatically?
From cmd /?:
If /D was NOT specified on the command line, then when CMD.EXE starts, it
looks for the following REG_SZ/REG_EXPAND_SZ registry variables, and if
either or both are present, they are executed first.
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
and/or
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
You therefore could add vcvars32.bat to one of those AutoRun registry values to have it executed for every cmd.exe instance (except when /D is explicitly specified, of course).
However, be forewarned that doing this could result in other weird side-effects (for example, it could cause other .bat/.cmd scripts to be run in an environment that they aren't expecting).
A workaround that works for some people is to write a batch file and call it A.BAT and make a.bat launch vcvars32.bat. Put a.bat on the path and then it's a matter of opening the cmd prompt and typing a and enter and voila, you're set!
way old, but the easiest way to do this with, say, a shortcut created on your TaskBar is to modify your shortcut (in %appdata%\microsoft\internet explorer\quick launch\user pinned\taskbar, or thereabouts) so the target is:
%windir%\system32\cmd.exe /k vcvars32.cmd
that'll do exactly what you're looking for. The /k tells it to execute the string but keep the window open (string being your batch file). You can either put vcvars32 somewhere in your path, or specify the whole path to vcvars32.
You can use the script in http://www.alteridem.net/2010/09/02/visual-studio-2010-command-prompt-here to make it so when you right-click a folder in explorer the option shows up. After downloading and extracting the zip file you can modify the .inf to point to the correct path to your particular VS version (and change the displayed name if desired). Note the comment on the page about having to rename the file if you are running 64-bit Windows.