I want to make a script so i could use Win+R, "venv (some path)" and add it in path env variable.
Problem is that i'm not really a batch coder and idk language.
I wrote sth that "should look like working code" but it's not.
Could you help me to make this script working?
echo %venvPath%
#set PATH=%PATH%;%venvPath
If you simply need the variable to be updated for the duration of a specific cmd.exe instance, then you should change your second line to:
#Set "PATH=%PATH%%venvPath%;"
If you need it to be more permamently defined, (for future cmd.exe instances), and as there are both a User, and a System, environment, (and the PATH variable is a joining of both), below is one method you could employ from a Windows batch/command script.
User Environment, (recommended):
#For /F "EOL=H Tokens=2,*" %%G In ('%SystemRoot%\System32\reg.exe Query "HKCU\Environment" /V Path 2^>NUL') Do #%SystemRoot%\System32\setx.exe Path "%%H%venvPath%;"
System Environment, (will need to be Run as administrator):
#For /F "EOL=H Tokens=2,*" %%G In ('%SystemRoot%\System32\reg.exe Query "HKLM\SYSTEM\CurrentControlset\Control\Session Manager\Environment" /V Path 2^>NUL') Do #%SystemRoot%\System32\setx.exe Path "%%H%venvPath%;" /M
If, of course, you need it for both the current cmd.exe instance, and all future instances, you'd need to implement both methods.
Notes
There is a 1024 character string length limitation when using setx.exe. This means that for safety, the expanded content of %%H plus the expanded value of %venvPath%, should not exceed that character length. It may therefore be prudent to save the content of %%H%venvPath% as a variable, then perform a character length check on it, before invoking the setx.exe command.
In addition, it would also be prudent to determine whether the expanded content of %venvPath%, is already listed within the existing %PATH% variable value before you attempt to add it. Whilst duplicating it may not immediately or seriously impact the variable, it would unnecessarily increase the character length, and therefore increase the likelihood of the forementioned limitation in subsequent setx.exe commands, with PATH.
Related
Windows default user profile is usually %SystemDrive%\users\default but its real location is not an environment variable but it can be useful to have it.
Default user profile path can be detected by system registry query like that
#echo off
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CurrentVersion\ProfileList" /v "Default"') do set "defaultuserprofile=%%b"
echo %defaultuserprofile%
pause
But we get the value %SystemDrive%\Users\Default where %SystemDrive% is not converted to C: (or other letter) so environment variable %defaultuserprofile% can not be used as normal environment variable path for file operations.
Alternative variant can be something like
#echo off
cd /d "%public%"
cd ..\
set usersdir=%cd%
set defaultuserprofile=%usersdir%\default
echo %defaultuserprofile%
pause
But it seems to be not so good.
So how is it possible to get Windows default user profile path via CMD?
Don't your really want %PUBLIC%, which is C:\Users\Public? At least that's closest equivalent on Windows 10 to a "Default" folder.
#echo off
setlocal
set "defaultuserprofile="
for /f "tokens=1,2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /v "Default"') do (
if "%%~A" == "Default" call set "defaultuserprofile=%%C"
)
echo "%defaultuserprofile%"
pause
The type of the data is REG_EXPAND_SZ. To expand the %SystemDrive% embedded in the string, use call set. call causes another parse of the command so that set assigns C:\ instead of %SystemDrive%.
Like the 2nd OP code, which is not as reliable as the reg query:
#echo off
cd /d "%Public%\..\Default" || exit /b 1
echo "%cd%"
pause
If you want to view the Default folder and other hidden folders in the Users directory, use:
dir /a:h
Output is the symlink named All Users, the folder named Default and the symlink named Default User on Windows 10 v1903.
Firstly, just to mention the purpose of the Default user profile is as the basis for all new user profiles. Therefore it should be used only to configure applications, settings and customizations for each future new user account on the PC. (modifications within it do not propagate to existing users).
The following method is similar to the existing answer, in that an additional expansion is used to cater for any variables within the contained data string. Please note that the value type of the data is by default REG_EXPAND_SZ, but it can also be of type REG_SZ, (the expand type is only necessary if the string contains a variable).
#Echo Off
Set "RKey=HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList"
Set "RVal=Default"
Set "ProfilePath="
For /F "Tokens=2*" %%G In (
'""%__APPDIR__%reg.exe" Query "%RKey%" /V "%RVal%" 2>NUL|"%__APPDIR__%find.exe" /I "%RVal%""'
)Do For /F "Tokens=*" %%I In ('Echo("%%~H"')Do Set "ProfilePath=%%~I"
If Not Defined ProfilePath Exit /B 1
Rem Your code using "%ProfilePath%" goes below here
Echo "%ProfilePath%" & Pause
I have Remarked a line with comment, which can be optionally omitted, and provided an example line below it for demonstration purposes, please modify that as necessary.
The code uses full paths for all external commands, (via a special variable, %__APPDIR__%, which will always point to their correct location). I have done that in order to remove any reliance on the content of the editable environment variables %PATH% and %PATHEXT%, (deliberate, or accidental, modification of those two environment variables could otherwise break the code).
I want to create a batch file to add the current directory to my System variable PATH, (not my User variable).
When I use:
SETX /M PATH "%CD%;%PATH%"
it does the needed thing. However, I get an error message:
data being saved is truncated to 1024 characters.
When I check the System variable using the GUI, I saw that User Path is getting added to the System Path. As a result, the System Path has duplicated entries.
I tried assigning the %PATH% variable to a temporary variable and echoing but I saw the duplications there as well.
I saw in some stack answer that the %PATH% variable we use in the batch file is actually a concatenation of both User Path and System Path.
At the Command Prompt, I tried:
REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH"
but I don't have idea much about whether we can use it to take that PATH value and assign to another variable.
So I need to find a way to assign ONLY the SYSTEM PATH to a temporary variable, let's say SYS_PATHS. How can I do that?
Is there a better way to overcome this scenario?
I found the answer to the question I asked in a link provided by #Mofi. This is how you can take the system path only, and append a directory to it.
set "env=HKLM\System\CurrentControlSet\Control\Session Manager\Environment"
for /f "tokens=2*" %%I in (
'reg query "%env%" /v Path ^| findstr /i "\<Path\>"'
) do setx /m PATH "%%J;%CD%"
I'm struggling to read the value of a registry key into a variable. The registry value may, or may not, contain spaces. In this case I'm trying to look up SDK paths.
It's easy to get the value with reg query, but it's returned in a remarkably unhelpful format:
C:\Users\Administrator\Desktop>reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDKTools" /v InstallationFolder
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDKTools
InstallationFolder REG_SZ C:\Program Files\Microsoft SDKs\Windows\v7.1\bin\
The key name, key type, and key value are separated by a series of spaces, not tabs.
You'd think you could use something like:
FOR /F "usebackq tokens=3* skip=2" %%L IN (
`reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDKTools" /v InstallationFolder`
) DO SET sdkpath=%%L
... but if the key contains spaces, as in this case, the result emitted on the command line is:
C:\Users\Administrator\Desktop>SET sdkpath=C:\Program
Which isn't helpful. There doesn't seem to be a wildcard variable to say "All matches". And you can't just write:
DO SET sdkpath=%%L %%M
... because if there are not spaces in the path, that will produce a literal %M (and would also produce a trailing space).
So. Is there any way to do this simple thing in a batch file?
I've written most of my tooling in Powershell (and some Perl), but I need to use a batch file for the "simple" task of calling the visual studio / windows sdk environment script and then invoking the code in sane languages once the environment is set up.
You'd think that after 10+ years of cmd.exe's existence, and command.com before it, this would be easy. Help?
(I can use Perl and the Win32:: packages to query the registry, but it doesn't help me get it into a batch var...)
Using Win2k12.
I've read:
Read registry value that contains spaces using batch file
Shell script reading windows registry
and many others, but none handle the general case of correctly reading a value from a key without knowing whether or not it contains spaces / how many.
Ah this is one of the annoying details about the for /f command. In order to read all the characters including the spaces with the * the previous token needs to be declared. tokens=2,* The functional reason is stated in the documentation.
If the last character in the tokens= string is an asterisk (*), an additional variable is allocated and receives the remaining text on the line after the last token that is parsed.
FOR Documentation
FOR /F "usebackq tokens=2,* skip=2" %%L IN (
`reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDKTools" /v InstallationFolder`
) DO SET sdkpath=%%M
Use Quotation marks
SET "sdkpath=%%M"
instead SET sdkpath=%%M
This will avoid problems with spaces.
I am writing a batch script that, quite reasonably, depends on "C:\WINDOWS\system32" being part of the PATH environment variable. I recently encountered a (developer's) machine that had a really weird path that didn't include system32, and therefore my batch script didn't work.
I looked up ways for my batch script to check the PATH variable and add system32 if it is not there. However, the solution I found used setx which ironically enough ALSO depends on system32 in the PATH variable. Are there any programmatic ways to add system32 to the PATH without it already being there?
Also please let me know if this is such an edge case that it doesn't make sense to make my script robust against it. I'm not expecting any of my typical users to have such a borked PATH variable. Should I bother?
try this:
for /f "delims=" %%a in ("%comspec%") do set "PATH=%PATH%;%%~DPa"
or this:
for /f "delims=" %%a in ("%comspec%") do set "compath=%%~DPa"
set "PATH=%PATH%;%compath:~0,-1%"
#ECHO OFF
SETLOCAL
SET "required=c:\windows\system32"
for %%p in ("%path:;=" "%") do (
FOR %%j IN ("" \) DO (
IF /i %%p=="%required%%%~j" GOTO :nextstep
)
)
SETx PATH "%required%;%path%"
:nextstep
ECHO PATH=%path%
GOTO :EOF
Here's my take on the problem. PATH may contain the required directory with or without a trailing \, and it may or may not have a preceding or trailing ;
I'd suggest that you examine the operation of SETX however. It sets an environment variable for FUTURE cmd sessions, not the CURRENT or EXISTING sessions, AFAIAA....and perhaps not for PATH or some other variables (I tried setting PATH using the SETX in the above batch - future sessions did NOT acquire the new value set, but it appeared to be set according to regedit32 - perhaps it needs a reboot - haven't investigated further at this stage)
Note that the above will need to have the required directory appended to %path% if my observations are borne out...
I created a batch file that searches for the users desktop folder in Windows.
for /F "skip=2 tokens=3* delims= " %%a in ('reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop') do set DESKTOP=%%a
If my desktop folder isn't in C:\Users\User\Desktop, it will work and return the correct folder, for example in my case E:\User\Desktop. If the desktop folder is in C:\Users\User\Desktop, the script above will result into %USERPROFILE%\Desktop. Later in the script I try to create a new file on desktop. In the first option it will work, because E:\User\Desktop is a real directory. In the second one it won't because obviously %USERPROFILE%\Desktop doesn't count as a directory.
echo start javaw -jar "path/to/program.jar" >"%DESKTOP%\Start program.bat"
How to get it work on both situations?
Doing
if /I "%DESKTOP%" EQU "%USERPROFILE%\Desktop"
doesn't help because it is the same as
if /I "%DESKTOP%" EQU "C:\Users\User\Desktop"
You could use call to expand the variable:
call set desktop=%desktop%
You need an extra round of normal expansion. As wmz has already answered, you can get that extra round by using CALL.
You should be careful about special characters like & or ^ that are valid in folder and file names. I recommend using quotes in your assignment to protect special characters.
call set "DESKTOP=%DESKTOP%"
I am assuming the value of DESKTOP does not already include quotes. All bets are off if you have a mixture of definitions that sometimes include quotes, and other times don't.
Suppose DESKTOP=This & that\%VAR% and VAR=& the other thing. The end result with the quoted assignment using CALL will be correct: This & that\& the other thing.
I have seen & in folder names in the real world, so the quotes are a good thing. However, there is a problem if your value contains ^. A quoted ^ is doubled if passed through CALL.
Suppose DESKTOP=one^two%var% and VAR=^three, the end result of the quoted assignment using CALL will be one^^two^three.
I don't think I have ever run across ^ in a folder name, but it is possible, and there is a solution. You can use CMD /C to get another round of expansion, and use FOR /F to capture the result.
The following will give the correct result of one^two^three. I use "eol=:" because a valid path can never begin with :.
for /f "eol=: delims=" %%B in ('cmd /c echo "%DESKTOP%"') do set "DESKTOP=%%~B"
You do not need to use an intermediate assignment of DESKTOP. In all of the above, you can substitute your FOR /F %%a in place of %DESKTOP%.