I am working on creating a batch file that adds will create registry entries in order to add custom commands into the UI of our file management software.
The issue is that the location of the key varies based on the version of the software a user is on.
Is it possible to create a patch file that will search within registry keys/sub keys and create new values there?
Here is an example of the registry location, the portion surrounded by ** will change based on version:
[HKEY_CURRENT_USER\Software\Motive\M-Files\**12.0.6550.8**\Client\MFShell\Rombald\TasksBar\ShellCommands\1]
"Name"="Calendar"
"Executable"="\\\\mfiles-server\\M-Files setup\\M-Files
Calendar\\MFCalendar_v1.2.6\\MFCalendar_v1.2.6\\M-Files Calendar.exe"
"Icon"="\\\\mfiles-server\\M-Files setup\\M-Files
Calendar\\MFCalendar_v1.2.6\\MFCalendar_v1.2.6\\M-Files Calendar.exe,0"
"Arguments"="{B1438CAB-2E53-474E-AA82-3D48F787F6B7}"
Essentially I would have to look for the version of the software and insert that into the key. If more than one exists it would be the largest value.
Thanks in advance for the help!
#echo off
setlocal
for /f "delims=" %%A in (
'reg query HKCU\SOFTWARE\Motive\M-Files'
) do set "root=%%~A" & set "version=%%~nxA"
echo root: %root%
echo version: %version%
if defined root (
echo Write new reg information.
reg add "%root%\testkey" /v testvalue /d data /f
reg add "%root%\testkey" /v testversion /d "%version%" /f
)
The for loop uses the command reg query to search through
the entries in the registry key. The last entry is saved as
root and version. The variable root will have the full key path
while the variable version will be the last segment of the path
which will be just the key name. These are echoed to console.
If defined root, subkey testkey will be added with values and
data as the code shows.
So long as you only have version keys under the key of M-Files
then this may be all you may need. If not, then you may need more
code to skip the other keys.
Related
I have a NSIS script with RequestExecutionLevel admin set and within this I invoke a .bat script which adds a reg key.
When the batch-file is executed through command-prompt the reg key gets added. But when running the installer, it executes the .bat file but fails to add the reg key.
nsExec::ExecToStack '"$pluginsdir${SETUP_PATH}\UpdateNtpConfiguration.bat" $Ip1'
UpdateNtpConfiguration.bat content
set adds=%1
REM Get the list of ntp servers showing up in System Date & Time->Internet Time dropdown
set "num=0"
for /F %%G in ('reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers ^| findstr "^[^a-z] ^("') do if %%G GTR !num! set "num=%%G"
set /A num=num + 1
REM Add address at the end
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers /v "%num%" /t REG_SZ /d "%adds%" /f
goto:eof
Just like #Anders said, there are built in functions for that.
https://nsis.sourceforge.io/Docs/Chapter4.html#registry
If an an error happens with this command, it will be a lot easier to debug as it is built-in.
If you're not doing anything else in the batch file, it is better to find out if NSIS has a command already integrated with it....
EDIT:
It also might be that the admin installer is run the bat file without admin privs.
After some debugging found out that NSIS was writing the registry values in 32 bit reg space(HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft). I had to append /reg:64 to make it add to the 64 bit reg space.
Also the reason I had the bat script was to have some logic to look for duplicates before adding the key.
I'm trying to make a batch file that creates a entry in the registry.
The entry must be link to a executable. It needs two parameters :
(path) The folder to process (see below project1)
(path) The folder that will contain the file returned by the process. I want this to be the parent folder of the first parameter (see below DirectoryProject)
Tree :
../somewhere/my/program/program.exe
../DirectoryProject
../DirectoryProject/project1
../DirectoryProject/output.data
Exemple :
"../somewhere/my/program/program.exe" "../DirectoryProject/project1" "../DirectoryProject"
The first parameter is easy, it is %%1. It has the folder's path I right clicked as value. The last parameter is however harder to get.
I first tried to manipulate the variable %%1.
reg add "%RootKey%\Software\Classes\Directory\shell\%KeyName%\command" /VE /D "cmd /c cd \"%%1\" & \"%Exec%\" \"%%1\" \"%%~dp1\"" /F
The program logs the parameters it reveice. The last parameter is equal to %%~dp1 so it does not work.
Then I tried a tricky way using the first parameter and the CD command
reg add "%RootKey%\Software\Classes\Directory\shell\%KeyName%\command" /VE /D "cmd /c cd \"%%1\" & \"%Exec%\" \"%%1\" \"%CD%\"" /F
In this case %CD% will always be the path of the batch file so clearly not what I want nether
I'm still looking
Thanks for your interest and help
If the value of %1 is a fully qualified and existing path then the root folder would generally be the drive letter followed by a backslash, normally denoted by %~d1\. However, given your latest clarification, it appears your looking for the current working directory, commonly denoted as %CD%.
I'm assuming that you wanted to manipulate the second instance of %1, so based on my assessment, here's how I'd do it:
#Echo Off
Set "ExePath=C:\SomePathTo\MadeUp.exe"
Set "MenuTxt=Process with MadeUp"
Set "KeyName=LaunchTest"
Set "RootKey=HKCU"
Reg Add "%RootKey%\Software\Classes\Directory\shell\%KeyName%" /VE /D "%MenuTxt%" /F >Nul
Reg Add "%RootKey%\Software\Classes\Directory\shell\%KeyName%\command" /VE /D "\"%ExePath%\" \"%%~1\" \"%CD%\"" /F >Nul
Please make sure that you modify your specific executable path on line 2 as required.
Note that the text description you want in the context menu, currently Process with MadeUp can be changed to suit your preference, you can do that on line 3.
I have left your registry key name as you had it, LaunchTest, this can be changed in line 4, (when it's no longer a test).
A user menu entry should be entered into the HKCU key, so I'm using that.(If you want it for all users then change HKCU to HKLM on line 5. Whilst it does not match your provided key, it is the correct way to do it. Entries from both HKCU\Software\Classes and HKLM\SOFTWARE\Classes are auto propagated to HKCR, you shouldn't add things directly to it.If you change it to HKLM be aware that there's a likelihood the script will need to be run As administrator)
If you had wanted the root directory of the right clicked folder then you'd change \"%CD%\" to \"%%~d1\\\" on line 7.
So, this is a particularly puzzling problem for me. I'm open to using whatever I must, but I typically only write simple batch files.
I have a huge research project at the hospital where I work, and the data I'm working with is presented to me with a 4 digit subject identifier followed by a timestamp, as seen in this example:
6443_20170419_141200416
6443_20170419_141200447
6443_20170419_141200500
6476_20170419_141200537
6476_20170419_141201112
etc.
I have literally thousands of these folders, and in each of them is between 1 and 3 files with very long file names - the only commonality is the .DCM extension.
What I'd like to do is have a script that will extract the first 4 characters of the folder name, create a new directory with that 4 character name, and then copy any files located within folders with the matching prefix into the newly created folder.
For example, let's say the folders which all start with 6443 have several .DCM files in them. I want to create a new folder named 6443 (in a different location that the then current directory, to avoid accidental deletion), and then move all of the .DCM files from each directory into the new folder.
I have a .TXT file which contains all of the subject ID #'s that I've been using for various other scripted tasks, using FOR /F to walk this file, if that gives anyone an idea for a solution.
This once is really picklin' my noggin. Help!!!
----- ADDITIONAL INFO -----
I've been making progress, but it's still not right. I'm using the script as shown below, but it's moving ALL of the files in each of the folders to each of the newly created folders, instead of sorting them by 4 digit prefix.
#ECHO on
cls
FOR /f "delims=_" %%a IN ('dir /b /ad "*_*_*"') DO (
if not exist %%a MD .\combined\%%a
FOR /d /r %%d IN ("*") DO (
copy %%d\* .\combined\%%a\*
)
)
Here is the corrected script:
#echo on
cls
for /F "tokens=1* delims=_" %%a in ('dir /B /A:D "????_*"') do (
if not exist ".\combined\%%a\" md ".\combined\%%a"
copy ".\%%a_%%b\*.dcm" ".\combined\%%a"
)
What I changed:
the tokens option has been added to the outer for /F loop in order to be able to rebuild the original source directory name later;
the directory search pattern has been improved;
the if query checked the wrong directory;
the inner for loop has been removed, because it iterated over all source directories again;
the source and destination paths for the copy command have been adapted;
all paths are properly quoted;
I am doing a simple batch file to copy folders and files located under the same path of the batch files to the desktop. I can easily get the path where the batch file is located using
%~dp0
but I want to know how to get the path of the user's desktop (I am using Widows 7 Ultimate)
Any suggestions?
I suppose you're under windows environnement, so %USERPROFILE%\Desktop should be ok
This is the location of the current users desktop:
%userprofile%\desktop
If Desktop locations in a different folder only this will be correct answer:
Batch string:
for /f "usebackq tokens=3*" %%D IN (`reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop`) do set DESKTOP=%%D
V2 (Works with spaces) 4.10.2016:
for /f "usebackq tokens=1,2,*" %%B IN (`reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop`) do set DESKTOP=%%D
If you have non-ASCII symbols, you also need to convert ANSI encoding to OEM, example for cyrillic:
CHCP 1251 >Nul
for /f "usebackq tokens=1,2,*" %%B IN (`reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop`) do set DESKTOP=%%D
CHCP 866 >Nul
for /f "delims=" %%i IN ('echo %DESKTOP%') do set DESKTOP=%%i
Then just use:
echo %DESKTOP%
I think this one should be ok too
%systemdrive%\Documents and Settings\All Users\Desktop
Regards
I found the answer
Regedit /e /a dd.txt
"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
find /i dd.txt "Desktop" >d.txt
For /F "tokens=2 delims==" %%a in (d.txt) do set mydesktop=%%a
The default for the Windows desktop directory of current user is defined with %USERPROFILE%\Desktop. USERPROFILE is one of the predefined Windows environment variables.
So it would be possible to use just the following folder path:
"%UserProfile%\Desktop"
But it would be better to get the desktop directory path from Windows registry instead of using simply the default. There are two registry keys containing a string value with name Desktop with the path to user's desktop directory:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
This registry key contains several string values usually of type REG_EXPAND_SZ which define the paths to the various shell folders defined for the current user account. The shell folders contain usually an environment variable reference like %USERPROFILE% which is the reason for the type REG_EXPAND_SZ which means the string value must be additionally expanded to get absolute path to the shell folder. The batch file below expands the environment variable reference by using the command CALL to force one more command line parsing by Windows command processor.
For example, the command set "DesktopFolder=%%~K" becomes first on execution of for the command set "DesktopFolder=%USERPROFILE%\Desktop". This command is parsed a second time by cmd.exe to something like set "DesktopFolder=C:\Users\UserName\Desktop" because of the command call before really executing the command set to define the environment variable DesktopFolder with the real absolute folder name read from the Windows registry.
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
This registry key contains nearly the same string values as the registry key above, but the string values are usually of type REG_SZ. This registry key is for downwards compatibility for applications not supporting the other registry key with the string values with environment variable references.
It is possible that a shell folder is defined only in one of the two registry keys. For example on Windows XP the string values Administrative Tools, CD Burning, Fonts and Recent exist only under registry key Shell Folders and do not exist under key User Shell Folders.
Information added by Compo with comments below my similar answer on:
How to create a directory in the user's desktop directory?
Windows itself uses by default the string values defined under key User Shell Folders and uses a string value defined under key Shell Folders only if not existing under key User Shell Folders.
Windows does not propagate a modification on a string value under key User Shell Folders to the string value with same name under key Shell Folders if a user or a program modifies directly in registry a string value under key User Shell Folders without making appropriate change to key with same name under key Shell Folders.
So in case of Desktop in User Shell Folders contains a different directory path than Desktop in Shell Folders, Windows uses the path defined with Desktop in User Shell Folders.
A user has the freedom to change any folder to whatever the user wants. But the user must take care to change a string value in both registry keys on existing twice. Some of the shell folders can be easily modified via an option on graphical user interface of Windows or a Windows application like the Downloads shell folder.
See also the Microsoft documentations for Known Folders and KNOWNFOLDERID and the other documentation pages referenced on these pages as well as the documentation about Application Registration.
Here is a batch file which gets the user's desktop directory from Windows registry as much safe as possible.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "DesktopFolder="
for /F "skip=1 tokens=1,2*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop 2^>nul') do if /I "%%I" == "Desktop" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "DesktopFolder=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "DesktopFolder=%%~K"
if not defined DesktopFolder for /F "skip=1 tokens=1,2*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v Desktop 2^>nul') do if /I "%%I" == "Desktop" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "DesktopFolder=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "DesktopFolder=%%~K"
if not defined DesktopFolder set "DesktopFolder=\"
if "%DesktopFolder:~-1%" == "\" set "DesktopFolder=%DesktopFolder:~0,-1%"
if not defined DesktopFolder set "DesktopFolder=%UserProfile%\Desktop"
echo User's desktop folder is: %DesktopFolder%
endlocal
This batch file works even on Windows XP on which reg.exe outputs the results of the query different to reg.exe of Windows Vista and newer Windows versions.
See Microsoft article about Using command redirection operators for an explanation of 2>nul which redirects the error message output by command MD on directory already existing to handle STDERR to the device NUL to suppress this error message.
However, the user's desktop directory should contain only shortcut files (*.lnk files) and the files and directories created by the user on the desktop. No program should create ever other files than shortcut files in the user's desktop directory. Microsoft defined several other shell folders for applications like APPDATA (application data) or LOCALAPPDATA (local application data) for applications.
Some additional facts about handling of string value Desktop under the keys User Shell Folders and Shell Folders by Windows as observed with Windows XP SP3 x86 with always restarting Windows after making a change in registry hive of current user:
A change of the path string of the string value Desktop under the key User Shell Folders for example from %USERPROFILE%\Desktop to %USERPROFILE%\MyDesktop and of course creation of the directory %USERPROFILE%\MyDesktop changes the Windows desktop directory to custom %USERPROFILE%\MyDesktop on next log on and the string value of Desktop under key Shell Folders is adapted by Windows on next restart. It was not tested by me if Desktop under the key Shell Folders is adapted also on just doing a log off and log on. It is definitely better to change both Desktop string values at the same time to change the desktop directory permanently to a directory different from default %USERPROFILE%\Desktop.
A removed or renamed string value Desktop under the key User Shell Folders is never recreated by Windows. So it is possible that this string value does not exist if Desktop under the key User Shell Folders was by mistake once deleted or renamed or the registry file is partly damaged with the result that this string value does not exist. A user would not notice that issue as the further tests below showed.
The string value Desktop of type REG_SZ under key Shell Folders is always set to expanded path of %USERPROFILE%\Desktop if string value Desktop of type REG_EXPAND_SZ under key User Shell Folders does not exist at all. Windows creates also the directory %USERPROFILE%\Desktop automatically if not existing in this error handling case
If the string value Desktop of type REG_SZ under key Shell Folders and the string value Desktop of type REG_EXPAND_SZ under key User Shell Folders are both deleted or renamed by a user or program, Windows creates on next start the string value Desktop of type REG_SZ under key Shell Folders with expanded path of %USERPROFILE%\Desktop and creates also the directory if not existing. The string value Desktop of type REG_EXPAND_SZ under key USer Shell Folders is not recreated by Windows.
If the string value Desktop of type REG_SZ under key Shell Folders exists with a different expanded path than %USERPROFILE%\Desktop like expanded path of %USERPROFILE%\MyDesktop and the string value Desktop of type REG_EXPAND_SZ under the key User Shell Folders does not exit at all, Windows ignores the customized path of Desktop of type REG_SZ under the key Shell Folders and sets the value to expanded path of %USERPROFILE%\Desktop and creates additionally the directory %USERPROFILE%\Desktop if not already existing. So it is not possible to use a customized desktop directory without having the customized desktop directory defined also with string value Desktop of type REG_EXPAND_SZ under the key User Shell Folders.
I did not make tests with newer versions on Windows regarding to handling of Desktop under the keys Shell Folders and User Shell Folders if one or both string values do not exist and/or have same or different directory paths and/or have a directory path different to default.
Cleanest solution just for Desktop:
for /f "tokens=2*" %%a in ('reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop') do set DESKTOP=%%b
echo %DESKTOP%
tokens=Type (2), then remaining Data (*) so location whitespace isn't tokenized. (spaces are allowed)
But if you're looking for any registry value which may not exist:
#echo off
set SUBKEY=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
set VALUE_NAME=Desktop
for /f "tokens=*" %%a in ('reg query "%SUBKEY%" /v "%VALUE_NAME%" 2^>nul') do set LINE=%%a
if defined LINE goto else
echo "%VALUE_NAME%" value not found.
goto end
:else
for /f "tokens=2,3 delims=#" %%a in ("%LINE: =#%") do (
echo Key: %SUBKEY%
echo Name: %VALUE_NAME%
echo Type: %%a
echo Data: %%b
)
:end
echo[
pause
tokens=* gets the whole line (Name + Type + Data) which are separated by 4 spaces
%LINE: =#% replaces the 4 spaces with hashtags so we can deliminate the tokens properly
tokens=2,3 gets us the Type and Data fields which get put into %%a and %%b
If you just want the Data you can do tokens=3 and it'll be in %%a. (since it's the only token)
Of all the examples i've been looking at all over the web, i haven't seen anyone else collecting the whole line and swapping the 4 spaces so they can tokenize properly. They all let it split at every whitespace, which can exist at both the Name and the Data fields. Of course if you're just after a specific value however (like "Desktop") you know the Type will be the 2nd token, and the remaining Data (*) is the last token. If you wanted a one liner for "My Pictures", you'd do token=3* instead. ("My" "Pictures" "Type" (3) "Data" (*))
Also the 2^>nul simply prevents the reg query command telling us if the value doesn't exist.
I reccomend to use this script:
#echo off
if exist "%userprofile%\OneDrive\Desktop" (chdir %userprofile%\OneDrive\Desktop) else (chdir %userprofile%\Desktop)
If someone installed OneDrive on windows setup, their desktop will probably be located under OneDrive folder. Else it will be User\Desktop.
Environ("USERPROFILE") & "\Desktop"
I want to read a registry key's child key name and assign the child key name to a variable. I am not getting an registry query to do it.
For ex: My current key is like this "ProviderName/SoftwareName/8.0". The last part 8.0 can change as and when I switch versions. I would want to read this version number.
Thanks in advance !!
Prakash
the REG command is what you will have to parse the output for.
REG QUERY HKLM\Software\Microsoft\Office
will show you office versions (as well as some common keys)
for /f "tokens=5 delims=\" %a in ('REG QUERY HKLM\Software\Microsoft\Office') do echo %a
will output the information. you will have to convert the info into a number, then test to see if it is bigger.