Windows BATCH: How to disable QuickEdit Mode for individual scripts? - windows

QuickEdit mode can be useful if you wish to quickly highlight and copy text directly from the command prompt instead of redirecting output to a file. However, it has its drawbacks. If you have a batch script running, selecting text in the console will pause the script execution until the text is deselected. This can be a problem if the script is expected to continue without pause.
How can one disable QuickEdit mode for certain BATCH scripts?

A way that will affect the current command prompt session.
Here's quickEdit.bat . It is a self-compiled .net script so it requires .net installed (not installed by default on Winsows XP/2003).
Usage:
Enable:
quickEdit 1
Disable:
quickEdit 2
Get State:
quickEdit 3

Already answered here, update "QuickMode" setting in Windows Registry:
reg add HKCU\Console /v QuickEdit /t REG_DWORD /d 0 /f
However it will not affect currently opened window. But you can reopen a window:
:: Get QuickEdit Mode setting from Windows Registry
FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKCU\Console" /v QuickEdit`) DO (
set quickEditSetting=%%A %%B
)
if %quickEditSetting%==0x1 (
:: Disable QuickEdit Mode
reg add HKCU\Console /v QuickEdit /t REG_DWORD /d 0 /f
:: Open script in a new Command Prompt window
start "" "%~dpnx0" %* && exit
)
... script logic here ...
exit
Additional info about HKEY_CURRENT_USER\Console Registry configuration - https://renenyffenegger.ch/notes/Windows/registry/tree/HKEY_CURRENT_USER/console/index

Unfortunately, there is no way to edit the QuickEdit setting of the current CMD Console instance from command line. We can, however, temporarily disable the global QuickEdit setting and start a new console instance. There are a couple ways to do this, each with its own perks (pros) and drawbacks (cons). Both of the following solutions require the ability to modify the registry.
REGEDIT
PRO: Compatible with any common Windows system
CON: Requires the creation of temporary REG files
Code (goes at the beginning of your script):
if exist "%TEMP%\consoleSettingsBackup.reg" regedit /S "%TEMP%\consoleSettingsBackup.reg"&DEL /F /Q "%TEMP%\consoleSettingsBackup.reg"&goto :mainstart
regedit /S /e "%TEMP%\consoleSettingsBackup.reg" "HKEY_CURRENT_USER\Console"
echo REGEDIT4>"%TEMP%\disablequickedit.reg"
echo [HKEY_CURRENT_USER\Console]>>"%TEMP%\disablequickedit.reg"
(echo "QuickEdit"=dword:00000000)>>"%TEMP%\disablequickedit.reg"
regedit /S "%TEMP%\disablequickedit.reg"
DEL /F /Q "%TEMP%\disablequickedit.reg"
start "" "cmd" /c "%~dpnx0"&exit
:mainstart
REG
PRO: Does not require creation of temp files
CON: Not available on Windows 2000 and earlier without Resource Kit
CON: Different versions have different syntax (accounted for in code below)
Code (goes at the beginning of your script):
set reg50=::&set reg51=::&(reg /?>nul 2>&1 && set reg51=)
if %errorlevel%==5005 set reg50=
set qkey=HKEY_CURRENT_USER\Console&set qprop=QuickEdit
%reg51%if defined qedit_val (echo y|reg add "%qkey%" /v "%qprop%" /t REG_DWORD /d %qedit_val%&goto :mainstart)
%reg50%if defined qedit_val (reg update "%qkey%\%qprop%"=%qedit_val%&goto :mainstart)
%reg51%for /f "tokens=3*" %%i in ('reg query "%qkey%" /v "%qprop%" ^| FINDSTR /I "%qprop%"') DO set qedit_val=%%i
%reg50%for /f "tokens=3*" %%i in ('reg query "%qkey%\%qprop%"') DO set qedit_val=%%i
if "%qedit_val%"=="0" goto :mainstart
if "%qedit_val%"=="0x0" goto :mainstart
%reg51%echo y|reg add "%qkey%" /v "%qprop%" /t REG_DWORD /d 0
%reg50%if "%qedit_val%"=="" reg add "%qkey%\%qprop%"=0 REG_DWORD
%reg50%if "%qedit_val%"=="1" reg update "%qkey%\%qprop%"=0
start "" "cmd" /c set qedit_val=%qedit_val% ^& call "%~dpnx0"&exit
:mainstart
If you have another solution, feel free to post.

Slight update for option 1 that worked for me, that doesn't run it twice, on Win10, thanks.
if exist "c:\temp\consoleSettingsBackup.reg" regedit /S "c:\temp\consoleSettingsBackup.reg" & DEL /F /Q "c:\temp\consoleSettingsBackup.reg" & goto START
regedit /S /e "c:\temp\consoleSettingsBackup.reg" "HKEY_CURRENT_USER\Console"
reg add "HKCU\Console" /v QuickEdit /t REG_DWORD /d 0 /f
start "" "cmd" /c ""%~dpnx0" & exit"
exit
: START
rem your commands\scripts here
exit

quickedit.bat
::: TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAAClmdnY4fi3i+H4t4vh+LeL4fi2i+T4t4si9+qL4vi3i7Xbh4vg+LeLUmljaOH4t4sAAAAAAAAAAAAAAAAAAAAAUEUAAEwBAQBvnfBjAAAAAAAAAADgAA8BCwEGAAACAAAAAAAAAAAAABgQAAAAEAAAACAAAAAAQAAAEAAAAAIAAAQAAAAAAAAABAAAAAAAAAAAIAAAAAIAAAAAAAADAAAAAAAQAAAQAAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAABUEQAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAudGV4dAAAAPQBAAAAEAAAAAIAAAACAAAAAAAAAAAAAAAAAAAgAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmEQAAshEAAMQRAADWEQAAlBEAAAAAAABVi+yD7AxTVos1DBBAAGr2/9aL2IXbD4T6AAAAg/v/D4TxAAAAjUX4UFP/FQgQQACFwA+E3gAAAP8VBBBAAIXAdH+KCITJdHmA+SJ1FUCKCITJdG1AgPkidGGKCITJdfTrWYD5IHRUgPkJdE9AigiEyXXv60aA+TB0doD5T3QFgPlvdRqKUAGA+kZ0BYD6ZnUNilACgPpGdFeA+mZ0UoD5MXRWgPlPdAWA+W91DYpIAYD5TnREgPludD9AigiEyXW0i134g2X0AMHrBoPjAWoAisMEMIhF/41F9FCNRf9qAVBq9f/WUP8VABBAAIvD60iLRfgkvwyA6wWLRfgMwDlF+HQPUFP/FRAQQAD32BvAQOsmM8DrIoNl9ACNRfRqAFCNRf9qAVBq9cZF/y//1lD/FQAQQACDyP9eW8nDfBEAAAAAAAAAAAAA5hEAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKYRAACyEQAAxBEAANYRAACUEQAAAAAAAP0CU2V0Q29uc29sZU1vZGUAAKQDV3JpdGVGaWxlABABR2V0Q29tbWFuZExpbmVBADMBR2V0Q29uc29sZU1vZGUAALkBR2V0U3RkSGFuZGxlAABLRVJORUwzMi5kbGwAAAAAAAAAAAAAAAAAAA==
#setlocal disabledelayedexpansion enableextensions
#echo off
if not exist quickedit.exe (
>quickedit.b64 (
for /f "delims=: tokens=1" %%# in ('findstr "^:::" "%~f0"') do echo %%#
)
certutil -f -decode quickedit.b64 quickedit.exe >nul
del /f /q quickedit.b64
)
quickedit.exe %*
on: quickedit 1
off: quickedit 0

Related

Have a batch file check the value of a registry key, echo if it is set how I want and change it if it is not

I want to have a script that will check the following Registry Key for
HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity
Enabled Reg_DWORD 0x0
If the value is set to 0x0, I want the script to echo Hypervisor Enforced Code Integrity is Disabled
If the value is set to anything else, I want to script to echo a statement, and then edit the registry value.
This is what I have so far, my issue is that the for /f command keeps erroring out. Any help would be really appreciated.
Set regkey="HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
Set Value=Enabled
for /f "tokens=2* delims= "
%%A IN (reg query %regkey% /v %Value%) DO SET base=%%B
if %base%=0x0 && goto Disabled else goto Enabled
:Disabled
echo Hypervisor Enforced Code Integrity is Disabled
pause
exit
:Enabled
echo Hypervisor Enforced Code Integrity is Enabled
echo
echo Continuing will Disable Hypervisor Enforced Code Integrity and then your computer will reboot
echo
echo ****Save your work before continuting****
pause
reg add %regkey% /v %value% /t REG_DWORD /d 0x0
shutdown /r /f /t 005 /c "Restarting to Disable Hypervisor Enforced Code Integrity"
Your main issue, is a failure to read or understand the basic command usage information. If you open a Command Prompt window, type for /?, and press the ENTER key, you should see that you are using:
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
Instead of:
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
However, there are several things you could do to improve your script, for this, and future tasks, so I have included a rewritten example for you too. It includes sections which are reusable for other registry checks, a user modifiable registry key and value pair to use with those, and parts specific only to the task laid out in the question.
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Rem The next two lines are user editable.
Set "RegKey=HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
Set "RegVal=Enabled"
Rem please do not modify the next twenty three lines.
Set "Elv=0"
For %%G In (RegKey RegVal) Do If Not Defined %%G (
%%G has not been defined.
Set "Elv="
)
If Not Defined Elv GoTo EndIt
Set "RegData="
For /F Delims^=^ EOL^= %%G In (
'%SystemRoot%\System32\reg.exe Query "%RegKey%" /V "%RegVal%" 2^>NUL ^| %SystemRoot%\System32\findstr.exe /RIC:"\<%RegVal%\>"'
) Do (
Set "RegData=%%G"
SetLocal EnableDelayedExpansion
For /F "Tokens=1,*" %%H In ("!RegData:*%RegVal%=!") Do (
EndLocal
Set "RegData=%%I"
)
)
If Not Defined RegData (
Echo The registry information does not exist.
GoTo EndIt
)
Rem The following five lines are specific to your task.
Set "Enabled=Disabled"
For %%G In (1 0x1 0x00000001) Do If "%RegData%" == "%%G" Set "Enabled=Enabled"
Echo Hypervisor Enforced Code Integrity is %Enabled%
If "%Enabled%" == "Disabled" GoTo EndIt
Rem Please do not modify the next seven lines.
Set "RegRoot=%RegKey:\="&:"%"
(Set RegRoot) 2>NUL | %SystemRoot%\System32\findstr.exe /XLI "HKLM HKEY_LOCAL_MACHINE" 1>NUL && Set "Elv=1"
%SystemRoot%\System32\reg.exe Query HKU\S-1-5-19 1>NUL 2>&1 || (
Echo To modify the registry, this script must be run elevated.
GoTo EndIt
)
Rem The following nine lines are specific to your task.
Echo(
Echo Your computer needs to reboot to disable Hypervisor Enforced Code Integrity.
Echo(
Echo ****Please save your work before continuting.****
Pause
%SystemRoot%\System32\reg.exe Add "%RegKey%" /V "%RegVal%" /T REG_DWORD /D 0 /F 1>NUL
%SystemRoot%\System32\shutdown.exe /R /T 5 /C "Restarting to Disable Hypervisor Enforced Code Integrity." /D P:2:4
Rem Please do not modify anything below.
:EndIt
Echo Press any key to exit . . .
Pause 1>NUL
Exit /B

Backup returned keys from reg query to file in batch

I want to be able to export key-values of registry keys as returned by reg query.
I'm trying to write a script to find registration for a particular dll and then write all keys to a backup file, before trying to achieve uninstall by deleting the keys. Here's what I could come up with so far:
#echo off
reg query HKLM\SOFTWARE\Classes /s /f %1 2>&1 >NUL
if errorlevel 1 goto DLL_MISSING
for /f "tokens=1,1" %%a in ('reg query HKLM\SOFTWARE\Classes /s /f %1 2^>NUL ^| findstr /I "^HKEY_"') do (
echo %%a
REG export %%a Backup.REG
)
goto :DLL_FOUND
:DLL_MISSING
echo Assembly not found.
goto :eof
:DLL_FOUND
echo Assembly found.
Right now reg export prompts to overwrite file, which I want append instead.
How can I achieve the same?
Also, please do suggest if there is some better way to automate uninstall duplicate(?) installs as installed by 'regasm'.
I could prefer batch-file based solution instead of Powershell or something else. Thanks!
reg.exe does not support appending/combining of several exported keys. The easiest workaround seems to be to output each key's data into a separate file, and then merge these into a single file afterwards. Note that you need to make sure that the output key file is not picked up by the FOR loop, which I ensured by simply placing the combined key file in a subfolder called target.
#ECHO OFF
MKDIR target
ECHO Windows Registry Editor Version 5.00 > target\combined.reg
FOR %%G IN (*.reg) DO (
TYPE "%%G" | FINDSTR /V "Windows Registry Editor" >> target\combined.reg
DEL "%%G"
)
This is what I wrote:
It's basically similar to what was proposed by #zb226.
#echo off
reg query HKLM\SOFTWARE\Classes /s /f %1 2>&1 >NUL
if errorlevel 1 goto DLL_MISSING
ECHO Windows Registry Editor Version 5.00 > backup.reg
for /f "tokens=1,2" %%a in ('reg query HKLM\SOFTWARE\Classes /s /f "%1" 2^>NUL ^| findstr /I "^HKEY_"') do (
echo Deleting : %%a
reg export %%a bkp_tmp.reg /y >nul 2>&1
type bkp_tmp.reg | FINDSTR /V "Windows Registry Editor" >> backup.reg
reg delete %%a /f >nul 2>&1
)
del /f bkp_tmp.reg
goto :DLL_FOUND
:DLL_MISSING
echo Assembly not found.
goto :eof
:DLL_FOUND
echo Assembly found.
It's ugly, as there definitely are key repetitions, but works for now.
The same goes for reg delete operations. It's manageable for now, but definitely there could be a better solution.

(Windows 8.1) Get path of selected folder from custom context menu option

First of all, I have almost no idea about batch language. I'm working on a batch file that writes to the registry in order to add a context menu option that removes "desktop.ini" from the folder from where the context menu option is called. So far, what I got is:
#echo off
#reg add "HKEY_CLASSES_ROOT\Folder\shell\resetFolderSettings" /t REG_SZ /v "" /d "Reset folder settings" /f
rem #reg add "HKEY_CLASSES_ROOT\Folder\shell\resetFolderSettings\command" /t REG_SZ /v "" /d "del /A s h \"%cd%\desktop.ini\" && pause" /f
#reg add "HKEY_CLASSES_ROOT\Folder\shell\resetFolderSettings\command" /t REG_SZ /v "" /d "cmd.exe /c echo \"%~dp0\desktop.ini\" && pause" /f
pause
Which doesn't work because what gets written into the registry is the static folder path from where the installation .bat is called. I'm having quite some trouble finding a solution to this problem so I finally decided I had no choice but to ask for help here.
Use %V to denote the folder from where the context menu option is called.
Hence, the parameters you should use in
reg add "HKCR\Folder\shell\resetFolderSettings\command" ...
could be from a batch script (see that %V should be escaped as %%V):
... /t REG_SZ /v "" /d "%comspec% /c echo \"%%V\desktop.ini\"&&pause" /F
or directly from cmd window - % sign is not escaped here:
... /t REG_SZ /v "" /d "%comspec% /c echo \"%V\desktop.ini\"&&pause" /F
Edit. To make %comspec% expandable as well (and with operational del /A command instead of echo):
... /t REG_EXPAND_SZ /ve /d ^%comspec^%" /c del /A \"%V\desktop.ini\"&pause" /F
used directly from cmd window. See escaped % as ^% (however only those out of double-quoted part of command line) above.
Use another escaping scheme from a batch-script: escape all % as %% how seen in both %%comspec%% and %%V as follows:
... /t REG_EXPAND_SZ /ve /d "%%comspec%% /c del /A \"%%V\desktop.ini\"&pause" /F
Result:
==> reg query "HKCR\Folder\shell\resetFolderSettings\command" /ve
HKEY_CLASSES_ROOT\Folder\shell\resetFolderSettings\command
(Default) REG_EXPAND_SZ %comspec% /c del /A "%V\desktop.ini"&pause

Windows batch command to make changes effective immediately

I have a batch script that lets users change their background from black to white or vice versa. The problem I'm having is that the script only makes immediate change sometimes, and other times the user has to log off and log back on for the background to change. Here is what I have so far:
#echo off
call :quiet
exit /b
:quiet
:: For comparison, using the black wallpaper registry value
set "black=C:\Users\UserName\AppData\Roaming\Microsoft\Windows\Themes\MDCBackground_black.bmp"
:: Set reg query result to current
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKCU\Control Panel\Desktop" /v Wallpaper') DO SET current=%%B
:: For debugging purpose.
ECHO current=%current%
pause
if "%current%"=="%black%" (
call :MakeDayWallpaper>nul 2>&1
:: Make changes without requiring logoff
RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters
) else (
call :MakeNightWallpaper>nul 2>&1
:: Make changes without requiring logoff
RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters
)
EXIT /b
:MakeDayWallpaper
REG ADD "hkcu\control panel\desktop" /v wallpaper /t REG_SZ /d "" /f
REG ADD "hkcu\control panel\desktop" /v wallpaper /t REG_SZ /d "C:\Users\UserName\AppData\Roaming\Microsoft\Windows\Themes\MDCBackground_white.bmp" /f
REG DELETE "hkcu\Software\Microsoft\Internet Explorer\Desktop\General" /v Wallpaper /f
REG ADD "hkcu\control panel\desktop" /v WallpaperStyle /t REG_SZ /d 2 /f
EXIT /b
:MakeNightWallpaper
REG ADD "hkcu\control panel\desktop" /v wallpaper /t REG_SZ /d "" /f
REG ADD "hkcu\control panel\desktop" /v wallpaper /t REG_SZ /d "C:\Users\UserName\AppData\Roaming\Microsoft\Windows\Themes\MDCBackground_black.bmp" /f
REG DELETE "hkcu\Software\Microsoft\Internet Explorer\Desktop\General" /v Wallpaper /f
REG ADD "hkcu\control panel\desktop" /v WallpaperStyle /t REG_SZ /d 2 /f
EXIT /b
The line RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters is the command that allows the immediate change. When I look at shell I can see that the registry value is changing every time the script is executed, but despite this fact, sometimes the background does not change until the user logs off and logs on.
It might be that the registry changes aren't taking effect until the log off/log on is done (I'm not sure why it would sometimes work immediately though). Try restarting explorer afterwards and see if that helps.
taskkill /im explorer.exe /f
explorer.exe

Windows batch script to switch desktop background

Is there a way to check what a user currently has as their background and then changing it depending on what it is? For example: I want a white background during day time and a black background for night time. Running the script would check the current background, if it is white it will switch to the black background, and if it is black it will switch to the white.
I'm a little unfamiliar with Windows batch script and I'm seeking some tips and advice on how I can accomplish the task above. Here is what I've been able to find so far:
#echo off
call :quiet>nul 2>&1
goto :EOF
:quiet
:: Configure Wallpaper
REG ADD "HKCU\Control Panel\Desktop" /V Wallpaper /T REG_SZ /F /D "%SystemRoot%\energybliss.bmp"
REG ADD "HKCU\Control Panel\Desktop" /V WallpaperStyle /T REG_SZ /F /D 0
REG ADD "HKCU\Control Panel\Desktop" /V TileWallpaper /T REG_SZ /F /D 2
:: Configure the screen saver.
:: REG ADD "HKCU\Control Panel\Desktop" /V SCRNSAVE.EXE /T REG_SZ /F /D "%SystemRoot%\System32\scrnsave.scr"
:: REG ADD "HKCU\Control Panel\Desktop" /V ScreenSaveActive /T REG_SZ /F /D 1
:: Set the time out to 900 seconds (15 minutes).
:: REG ADD "HKCU\Control Panel\Desktop" /V ScreenSaveTimeOut /T REG_SZ /F /D 900
:: Set the On resume, password protect box
:: REG ADD "HKCU\Control Panel\Desktop" /V ScreenSaverIsSecure /T REG_SZ /F /D 1
:: Remove the user's ability to see the Screen Saver, background, and appearance tabs of Display Properties.
::REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" /V NoDispScrSavPage /T REG_DWORD /F /D 1
::REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" /V NoDispBackgroundPage /T REG_DWORD /F /D 1
::REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" /V NoDispAppearancePage /T REG_DWORD /F /D 1
:: Make the changes effective immediately
%SystemRoot%\System32\RUNDLL32.EXE user32.dll, UpdatePerUserSystemParameters
You can use code like that:
#echo off
:: '>nul 2>&1' was moved to other place
call :quiet
exit /b
:quiet
:: Put there wallpaper name (with extension, bigger that 8 symbols)
set "Wallpaper.Night.BadWrited=Wallpaper1.bmp"
:: It is a dirty hack and example of bad code
for /F "tokens=*" %%a in ('reg query "HKCU\Control Panel\Desktop" /v Wallpaper') do set "Wallpaper.Current.BadWrited=%%a"
:: Take last 8 symbols of wallpaper name. Change number of symbols to your own minimal
set "Wallpaper.Current.BadWrited=%Wallpaper.Current.BadWrited:~-8%"
set "Wallpaper.Night.BadWrited=%Wallpaper.Night.BadWrited:~-8%"
if "%Wallpaper.Current.BadWrited%"=="%Wallpaper.Night.BadWrited%" (
call :MakeDayWallpaper>nul 2>&1
) else (
call :MakeNightWallpaper>nul 2>&1
)
exit /b
:MakeDayWallpaper
echo Day wallpaper setted
:: Put your code here
exit /b
:MakeNightWallpaper
echo Night wallpaper setted
:: Put your code here
exit /b
But i recommend to use the system scheduler. You can acces it from control panel, 'Scheduled Tasks' or something. You can make 2 files named 'makeday.bat' and 'makenight.bat'. Scheduler will run them every day at needed time

Resources