注册表之转义反斜杠和双引号.bat

@goto :main_20230915_063011

测试环境:
* Windows 11 22H2 22621.1992
* cmd.exe 10.0.22621.1635
* regedit.exe x64 10.0.22621.1
* reg.exe x64 10.0.22621.1
* RegWorkshopX64.exe 5.1.0.0

https://stackoverflow.com/questions/27536949/how-to-add-a-registry-key-with-default-value-containing-double-quotes-and-percen/77109243

【注册表键值长度上限表】

当主项为以下情况时:

命令行      最长项名(254)  最长项名(手动256)  最长值名(259)  最长值数据(REG_SZ,3w)  最长值数据(REG_BINARY 无限多页,每页64KB)
reg query       OK             NO                 OK             OK                     OK
reg add         OK             NO                 OK             NO                     NO
reg copy        OK             NO                 OK             OK                     OK
reg export      OK             NO                 NO             OK                     OK
regedit /e      OK             OK                 OK             OK                     OK

* 未标明单位的,一律按字符算,中文文字算一个字符。
* 长度上限以最后存储到注册表里的长度算。不是脚本里转义后的字符长度。

:: ---------------------------------------------------------------------------------------------------------------------

:main_20230915_063011
	@echo OFF&cls&echo %0 %*

	echo.&call :TestRegAdd\\"" %*
	echo ---------------------------------------------------------------------------------------------------------------
	echo.&call :TestRegQuery\\"" %*
	echo ---------------------------------------------------------------------------------------------------------------
	echo.&call :TestRegCopy\\"" %*
	echo ---------------------------------------------------------------------------------------------------------------
	echo.&call :TestRegDelete\\""
	echo.&pause

	>nul 2>&1 reg delete "HKEY_CURRENT_USER\." /f & echo.
	>nul 2>&1 reg delete "HKEY_CURRENT_USER\.." /f & echo.
	>nul 2>&1 reg delete "HKEY_CURRENT_USER\..." /f & echo.
	>nul 2>&1 reg delete "HKEY_CURRENT_USER\...." /f & echo.
@goto :EOF

:: ---------------------------------------------------------------------------------------------------------------------

:TestRegAdd\\""
	@echo OFF&echo call %0 %*

	echo.&call :GetRegInfo || goto :eof

	echo.^> reg add %%key%% /v %%value%% /t REG_SZ /d %%data%% /f
	echo. & reg add "%key%" /v "%value%" /t REG_SZ /d "%data%" /f

	echo.&call :GetRegInfo2 || goto :eof

	echo.^> reg add %%key%% /v %%value%% /t REG_SZ /d %%data%% /f
	echo. & reg add "%key%" /v "%value%" /t REG_SZ /d "%data%" /f
	echo.
@goto :EOF

:TestRegQuery\\""
	@echo OFF&echo call %0 %*&echo.

	echo.&call :GetRegInfo || goto :eof

	echo.^> reg query %%key%% /z /s /v %%value%% /t REG_SZ /f %%data%% /d /k
	echo. & reg query "%key%" /z /s /v "%value%" /t REG_SZ /f "%data%" /d /k

	echo.&call :GetRegInfo2 || goto :eof

	echo.^> reg query %%key%% /z /s
	echo. & reg query "%key%" /z /s && echo 搜索结束: 找到 1 匹配。
	echo.

	REM 当层数大于 32 层,无法查询到叶子层的数据
	echo.^> reg query %%key%% /z /s /v %%value%% /t REG_SZ /f %%data%% /d /k
	echo. & reg query "%key%" /z /s /v "%value%" /t REG_SZ /f "%data%" /d /k
	echo.
@goto :EOF

:TestRegCopy\\""
	@echo OFF&echo call %0 %*

	echo.&call :GetRegInfo || goto :eof

	echo.^> reg copy %%key%% "HKEY_CURRENT_USER\..." /s /f
	echo. & reg copy "%key%" "HKEY_CURRENT_USER\..." /s /f

	echo.&call :GetRegInfo2 || goto :eof

	echo.^> reg copy %%key%% "HKEY_CURRENT_USER\...." /s /f
	echo. & reg copy "%key%" "HKEY_CURRENT_USER\...." /s /f
	echo.
@goto :EOF

:TestRegDelete\\""
	@echo OFF&echo call %0 %*

	echo.&call :GetRegInfo || goto :eof

	echo.^> reg delete %%key%% /v %%value%% /f
	echo. & reg delete "%key%" /v "%value%" /f

	echo.&call :GetRegInfo2 || goto :eof

	REM 层数大于 32 层,删除会出错,提示 “错误: 参数错误。” 
	echo.^> reg delete %%key%% /v %%value%% /f
	echo. & reg delete "%key%" /v "%value%" /f
	echo.

	echo.^> reg delete %%key%% /f
	echo. & reg delete "%key%" /f
	echo.
@goto :EOF


:GetRegInfo
	@echo OFF&echo call %0 %*&echo.
	:Tips 
	@rem 1.注册表键不能有空子项,即不能连续有 \\
	@rem 2.注册表键可以含有TAB符‘	’,但控制台无法直接输入。
	@rem 3.注册表根键下子键深度最多32层。超出层数时无法查看,但可以导出。

	set key=
	set "key=HKEY_CURRENT_USER\.\aa\bb"cc\"d d\ee""ff\""gg\hh"""ii\"""jj\"\""\"""\" \ "\" "\"" \ ""\"" ""\"""  \  """\"" "  " ""\"" ""  "  """"\ \  \   \"
	set key
	call :EscapeReg key
	cd.&2>nul set key&echo.||exit /b 1

	set value=
	set "value=value\.\aa\bb"cc\"d d\ee""ff\""gg\hh"""ii\"""jj\\"kk\\""ll\\"mm\\\""nn\\\"""oo\\\""""pp\"\""\"""\" \ "\" "\"" \ ""\"" ""\"""  \  """\"" "  " ""\"" ""  "  """"\ \  \   \\"
	set value
	call :EscapeReg value
	cd.&2>nul set value&echo.||exit /b 1

	set data=
	set "data=data\.\aa\bb"cc\"d d\ee""ff\""gg\hh"""ii\"""jj\\"kk\\""ll\\"mm\\\""nn\\\"""oo\\\""""pp\"\""\"""\" \ "\" "\"" \ ""\"" ""\"""  \  """\"" "  " ""\"" ""  "  """"\ \  \   \\\"
	set data
	call :EscapeReg data
	cd.&2>nul set data&echo.||exit /b 1
@goto :EOF

:GetRegInfo2
	@echo OFF&echo call %0 %*&echo.

	set key=
	REM set /p key=key: &rem HKEY_CURRENT_USER\0\1\2\3\4\5\6\7\8\9\A\B\C\D\E\F\0\1\2\3\4\5\6\7\8\9\A\B\C\D\E\F\0\1\2\3\4\5\6\7\8\9\A\B\C\D\E\F\
	set /p key=key: &rem HKEY_CURRENT_USER\..\;key\%TEMP%\!TMP!\ [ \ ] ; \" ;!@!%#$%^&*()_-+={}[]|:'",<>.?/`~^^%1\""^^^%1\""^^^^%\"1!!!!\aa\bb"cc\"d d\ee""ff\""gg\hh"""ii\"""jj\"\""\"""\" \ "\" "\"" \ ""\"" ""\"""  \  """\"" "  " ""\"" ""  "  """"\ \  \   \
	call :EscapeReg key
	cd.&2>nul set key&echo.||exit /b 1

	set value=
	set /p value=value: &rem 	;value\%TEMP%\!TMP!\ [ \ ] ; \" ;!@!%#$%^&*()_-+={}[]|:'",<>.?/`~^^%1\\""^^^%1\""^^^^%\\"1!!!!\aa\bb"cc\"d d\ee""ff\""gg\hh"""ii\"""jj\\"kk\\""ll\\"mm\\\""nn\\\"""oo\\\""""pp\"\""\"""\" \ "\" "\"" \ ""\"" ""\"""  \  """\"" "  " ""\"" ""  "  """"\ \  \   \\
	call :EscapeReg value
	cd.&2>nul set value&echo.||exit /b 1

	set data=
	set /p data=data: &  rem 	;data\%TEMP%\!TMP!\ [ \ ] ; \" ;!@!%#$%^&*()_-+={}[]|:'",<>.?/`~^^%1\\""^^^%1\""^^^^%\\"1!!!!\aa\bb"cc\"d d\ee""ff\""gg\hh"""ii\"""jj\\"kk\\""ll\\"mm\\\""nn\\\"""oo\\\""""pp\"\""\"""\" \ "\" "\"" \ ""\"" ""\"""  \  """\"" "  " ""\"" ""  "  """"\ \  \   \\\
	call :EscapeReg data
	cd.&2>nul set data&echo.||exit /b 1
@goto :EOF

:EscapeReg <&$>
	@echo off||code by tiandyoin&title 《注册表之转义反斜杠和双引号》mail: tiandyoin@163.^com
	:Tips 
	@rem 1.与双引号相连前面的连续个 \ 都需要转义,使用 \\ 表示 \,使用 \" 表示 ",也可以使用 "" 表示 "。如 \\" 转义为 \\\\\"
    @rem 2.为避免最后一个 \ 与在外层加的双引号起作用, 最后一个 \ 也要转义为 \\ 。如 s=a\, 调用 "%s%" 时,s 要转成 a\\
	 set "$=%~1"&rem
	 if not defined  $  exit /b 1
	 if not defined %$% exit /b 1
	@rem 1.  如果变量值含有单数个双引号,会引用错误, 把后面语句甚至换行符包括在引号里。 
	 rem 1.1 双倍个双引号,使能够括住成对双引号里的特殊字符。添加到注册表时会变成单数个双引号。
	 call set "$=%%%$%:"=""%%"
	 rem 1.2 先假设调用变量时会在外层加双引号,同样要双倍。
	 set "$=""%$%"""
	@rem 2.  跟双引号连着的前面连续个 \ 都需要转义, \ 变成 \\
	 set \=\
	:LOOP_ESCAPE
		set "past=%$%"
		call set "$=%%past:%\%"=%\%\"%%"
		set \=\\%\%
	@if not "%$%"=="%past%" goto :LOOP_ESCAPE
	 rem *.  最后一个反斜杠双写,以便后面可能加上双引号时,不会转义双引号。 (在复合语句中使用)
	 REM cd.&(call cmd /c "if /i ""%%$:~-1%%%%$:~-1%%""==""\\"" exit /b 1")|| call set "$=%%$%%\"&cd.
	 REM if "%$:~-1%%$:~-1%"=="\\" set "$=%$%\"
	@rem 3.  先前假设调用变量时会在外层加双引号,现在还原。
	 set "$=%$:~2,-2%"
	 set "%~1=%$%"
@exit /b 0

:: ---------------------------------------------------------------------------------------------------------------------

你可能感兴趣的:(cmd,Batch,注册表,batch,注册表,backslash,quotes,转义字符)