Batch environement variables woes - batch-file

I have no problem with process-level variables, such as:
Set a=ABC
Echo '%a%'
> 'ABC'
And I understand why persistent variables, being set in the registry (at one of three possible locations), are not available in the current session:
Setx a=ABC
Echo '%a%'
> '%a%'
[Open a new command window:]
Echo '%a%'
> 'ABC'
This works the same when the first portion is in a script, and the last two lines occur in a Command window (cmd). However, when I set (setx) a persistent variable in a script, and then run another script to read it, the results are wildly unpredictable to me. For instance, the first time I run the following script, I expect it to set the variable (but not Echo it), while on all subsequent runs, since the variable is set previous to calling the script, %a% should have the value ABC:
Echo '%a%'
Setx a ABC
Echo '%a%'
Pause
Unfortunately, even on the second run both Echo statements return an empty value (''). A new command window will return the expected value ('ABC'), as I noted before.
To make things worse for me, SOMETIMES I can access a previously stored variable's value - but then I can't change it. I suspect that in these instances I am accessing the variable from another environment (System vs User vs Machine), but I can't seem to understand this.
Why can I not access the persistent variable from a script? How should I be writing the script so it can?

When initiating from cmd the help. setx /? a specific area specifies:
NOTE: 1) SETX writes variables to the master environment in the registry.
2) On a local system, variables created or modified by this tool
will be available in future command windows but not in the
current CMD.exe command window.
You therefore need to close the current cmd window and start a new instance in order to load the new or modified environment variable from the master environment.
However as per your comments you simply want to store the environment variables once off for other scripts to access. therefore this:
if not defined aa setx aa ABC & exit
echo %aa%
pause
when you run it the first time, will set the variable and exit, if the variable is not yet defined, when you run the script the second time, it will not set it, as it now finds the variable exists.
if however you want to do something in the script the first time it is run as well with variable %aa% then simply set the temp variable as well.
if not defined aa setx aa ABC & set aa=ABC
echo %aa%
pause
So first time you run the above, it will set a locally and in the environment, but the 2nd time you start it, it will skip the first line as %a% is found in the environment.
We can then look at editing existing variables as well:
if not defined aa setx aa ABC & set "aa=ABC"
if not "%aa%" == "NEW_VALUE" setx aa NEW_VALUE & set "aa=NEW_VALUE"
echo %aa%
pause
Same principal, but now we check the value as well to see if it contains the modified value required.

Related

How do I use the if statement with WMIC

this is my first post. I am using a batch command to check if an instance of my program is already running based on its command line argument. I am able to see if it is running by using the following code:
wmic Path win32_process Where "CommandLine Like '%Account A%' AND Caption Like '%Leads Manager.exe%'"
If the process exists, I will get a full break down of the process information, but if the process isn't running i get No Instance(s) Available.
I want to be able to run an If statement, so if the result shows No Instance(s) Available. I want to run a command without displaying the process information and if it does exists, I want to echo Account A is already running
Hopefully someone with more experience can point me in the right direction
Here's a batch-file example, which may help you out:
#Echo Off
For %%A In (A B C D) Do WMIC Process Where^
"Name='Leads Manager.exe' And Not CommandLine Like '%%Account %A%%%'"^
Get Name 2>Nul|Find "Name">Nul && (
Start "" "C:\Leads Manager.exe" -- "C:\Account %%A.ini")
This example uses the outer For loop to choose the Account letters, it is therfore checking to see if Leads Manager.exe is running with a commandline containing the string Account A, Account B, Account C or Account D, and if not it should run Leads Manager specifying the path to the appropriate account. (Please note that your .exe and .ini file paths both contain spaces, so I have doublequoted them, but left the rest of the command as you wrote it in your comment. You may want to consider checking that what you provided was correct and adjust it as necessary before testing, or replace that line entirely with a simple Echo Is Not Running) || Echo Is Running) statement, or perhaps run another batch file instead).

Batch stops after setting variables

I'm new to batch scripting and just tried to do some simple stuff and trigger some other applications. At first my batch set some variables and then it should save the results from a command to a file. Both parts alone work fine, but if I put them together it stops after setting the variables. Can someone help me?
Code:
set path=%cd%
set filename=\MAC.txt
set filepath=%path%%filename%
arp -a |find "192.168.1.1">>%filepath%
pause
Since path is the variable used by cmd for finding executables, changing it to something where arp isn't will mean that you won't be able to locate and run arp.
Use a different variable name, such as:
set filepath=%cd%
set filename=\MAC.txt
set fullname=%filepath%%filename%
arp -a |find "192.168.1.1">>%fullname%
pause
Note that this still has another problem present in your original script, the fact that spaces in your current directory may cause issues (unless you quote them correctly).
Since you're using the current directory exclusively, you probably don't need to worry about the path:
set fullname=.\MAC.txt
arp -a |find "192.168.1.1">>%fullname%
pause

Permanent variables for batch files

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"

Assign empty system variable using setx

I need a system variable and assign an empty string value to it. I've tried
setx samplepassword ""
But upon echo %samplepassword% , what should be an empty string is instead %samplepassword%. Now I found this in the docs
Setting value of "" (empty quotes) will appear to delete the variable
- it's not shown by SET but the variable name will remain in the registry.
http://ss64.com/nt/setx.html
How can I assign an empty system variable using setx?
Update:
I have checked the environment variables via the Windows GUI: Control Panel | System | Advanced | Environment Variables and saw that the DB_PASSWORD was indeed initialized with an empty string value. But why does executing echo %samplepassword% give me the above output? I have opened a new instance of cmd to be precise.
Technically you can create an empty environment variable, but not with setx.
Run that as administrator
reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment" /v TESTENV /d ""
the registry key is added:
it even shows in environment variables system panel
But not in the list when invoking set
So even if it is possible, it is rather useless. However it could fool some programs testing if the env. variable exists by checking if registry key exists. So it could even be counter-productive and source of confusion.
I think you have a misconception here. There is no way to assign an
"empty string" to an environment (Batch) variable. The command set
"samplepassword=" deletes the variable, so echo "%samplepassword%"
just show "". You don't need setx command to do that, nor setx can
modify this behavior. – Aacini Aug 9 at 4:39
TL;DR: Technically it is not possible to create an empty variable in the environment. – Aacini
I had the same problem getting a file name with or without a suffix. You can work around this with a string prefix and string extraction (see here), e.g.
not empty string:
set COUNT=two
set SUFFIX=?s
echo %COUNT% thing%SUFFIX:~1%
gives two things
empty string
set COUNT=one
set SUFFIX=?
echo %COUNT% thing%SUFFIX:~1%
gives one thing
With the %SUFFIX:~1% you dismiss the string prefix (in this example ?) and get the rest of the string. This rest can be empty.

how to clear a variable which is set from command line by "set /p var1="

In Windows batch files, I accept variable from user input by set /p var1=, after var1 is used, I don't know how to reset/clear its value.
If I don't reset/clear its value, when user meets set /p var1= again, and user enter directly. the previous input value will be still there. I don't want it, How to reset it for new user input?
To clear a variable, regardless how it was set:
set "var1="
rare issue, but you can try this:
set "var=%var*=%"
Different answers to original question were already provided above. One additional hint: within batch-script you can use the scopes:
setlocal
...
endlocal
This ensures that the variables are only accessible within your batch script and not affecting variables outside of your batch script (i.e. your variables are also not accessible outside of the batch script). By exiting of the batch script - the variables used locally get automatically "cleared".

Resources