英文:
How to check if a registry key with %SystemRoot% in its pathname exists?
问题
我正在尝试使用 reg query
命令来以编程方式检查 Computer\HKEY_CURRENT_USER\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe
注册表键的 QuickEdit 值是否存在。如果存在,我将将该值设置为 0(以禁用 PowerShell 中的 QuickEdit)。
因为该键的路径名包含 %SystemRoot%
宏,该宏在宏扩展中求值为 C:\Windows
,所以 reg query
失败了:
C:\Users\John> reg query "HKCU\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe\QuickEdit"
ERROR: 系统无法找到指定的注册表键或值。
但是我检查了 regedit,这个键确实存在。
那么我该如何转义 %SystemRoot%
并告诉 reg query
%SystemRoot%
是路径名的一部分呢?
我尝试过 "HKCU\Console\%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe\QuickEdit"
(注意 %%
),但那并不起作用(同样的错误)。
英文:
I'm trying to use the reg query
command to programmatically check if the QuickEdit value of the Computer\HKEY_CURRENT_USER\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe
registry key exists. If so, I will set that value to 0 (to disable QuickEdit in powershell).
Because the key's pathname contains %SystemRoot%
macro, which evaluates to C:\Windows
in the macro expansion, the reg query
fails:
C:\Users\John> reg query "HKCU\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe\QuickEdit"
ERROR: The system was unable to find the specified registry key or value.
But I checked regedit and this key does exist.
So how do I escape %SystemRoot%
and tell reg query
that %SystemRoot%
is part of the pathname?
I tried "HKCU\Console\%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe\QuickEdit"
(note the %%
) but that didn't work (same error).
答案1
得分: 1
No values of HKEY_CURRENT_USER\Console
at all were returned for me from reg query /v
(Win11).
这段代码未返回任何HKEY_CURRENT_USER\Console
的数值,适用于reg query /v
(Win11)。
This worked for me:
这对我有效:
@ECHO OFF
SETLOCAL
SET "key=HKEY_CURRENT_USER\Console%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe"
SET "subkey=QuickEdit"
SET "value="
SET "keyfound="
FOR /f "delims=" %%e IN ('reg query "HKCU\Console" /s') DO (
IF DEFINED keyfound (
ECHO %%e|FINDSTR /b "HKEY" >NUL
IF ERRORLEVEL 1 (
ECHO %%e|FINDSTR /b /l /c:" %subkey%" >NUL
IF NOT ERRORLEVEL 1 SET "value=%%e"&GOTO done
) ELSE SET "keyfound="
)
IF "%%e"=="%key%" SET "keyfound=y"
)
:done
ECHO Value found=%value%
GOTO :EOF
首先查找与HKEY...
匹配的行,设置一个标志以处理后续行。
如果另一个以HKEY...
开头的行出现在行首,则关闭匹配处理(可能也可以在此处退出,因为找到了键,下一个键也找到了...)。
否则,查看行是否以 requiredsubkey
开头。如果是的话,获取整行,将其分配给value
并退出。
所以,如果value
有值,就找到了数据。
英文:
No values of HKEY_CURRENT_USER\Console
at all were returned for me from reg query /v
(Win11)
This worked for me:
@ECHO OFF
SETLOCAL
SET "key=HKEY_CURRENT_USER\Console\%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe"
SET "subkey=QuickEdit"
SET "value="
SET "keyfound="
FOR /f "delims=" %%e IN (' reg query "HKCU\Console" /s') DO (
IF DEFINED keyfound (
ECHO %%e|FINDSTR /b "HKEY" >NUL
IF ERRORLEVEL 1 (
ECHO %%e|FINDSTR /b /l /c:" %subkey% " >NUL
IF NOT ERRORLEVEL 1 SET "value=%%e"&GOTO done
) ELSE SET "keyfound="
)
IF "%%e"=="%key%" SET "keyfound=y"
)
:done
ECHO Value found=%value%
GOTO :EOF
First look for a line matching the HKEY...
, set a flag to process succeeding lines.
If another HKEY...
appears at the start of the line, turn off matching the processing (could also probably exit here, as the key has neem ound, and so has the next...).
Otherwise, see wether the line begins exactly requiredsubkey
. If it does, grab the complete line, assign it to value
and exit.
So, if value
has a value, the data was found
答案2
得分: 1
以下是已翻译的内容:
-
可以直接在 Windows 命令提示符窗口中使用以下命令:
%SystemRoot%\System32\reg.exe QUERY HKCU\Console\^%SystemRoot^%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD
注:在注册表键中的两个百分号符号都使用
^
转义,以被解释为字面字符。由于在注册表键名称中的%SystemRoot%
之前有插入符号^
,它不会被解释为变量引用。 -
在批处理文件中可以使用以下命令:
%SystemRoot%\System32\reg.exe QUERY HKCU\Console\%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD
注:在批处理文件中,百分号符号必须使用一个额外的百分号符号进行转义,以使其被解释为字面字符。
-
如果整个注册表键不包含空格或以下字符之一
&()[]{}^=;!'+,
~<>|,则可以在不使用
"包围的情况下将注册表键传递给 __REG__。这在命令提示符窗口中更容易,因为只需使用两次
^` 来转义注册表键名称中的两个百分号符号。 -
可能有三种输出:
-
如果注册表键
%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe
在注册表键HKEY_CURRENT_USER\Console
下存在,并且注册表值QuickEdit
存在且为 32 位双字 (DWORD
) 类型,则会将注册表值QuickEdit
输出到 STDOUT,此时 REG 的退出代码为0
,表示成功执行给cmd.exe
处理批处理文件或解释和执行命令提示符窗口中输入的命令。 -
如果注册表键根本不存在,将会输出以下错误消息到 STDERR:
ERROR: The system was unable to find the specified registry key or value.
在这种情况下,退出代码为
1
,表示错误已传递给父进程。 -
如果注册表存在但不包含名为
QuickEdit
的注册表值,或者包含具有不同类型的注册表值(不是DWORD
),则会将以下信息消息输出到 STDOUT:End of search: 0 match(es) found.
在这种情况下,退出代码也为
1
,表示未找到此注册表值的搜索失败。
输出可以使用
>nul 2>&1
、>nul 2>nul
或1>nul 2>nul
来抑制,如果只需要根据退出代码来评估结果,可以使用条件命令运算符&&
和/或||
,如 单行中使用多个命令的 Windows 批处理文件 中所述,或者使用命令 IF 输出上的条件,如在命令提示符窗口中运行if /?
时使用的IF [NOT] ERRORLEVEL
条件。 -
-
可以使用 FOR /F 循环来验证双字值,如下所示:
@echo off setlocal EnableExtensions DisableDelayedExpansion set "QuickEdit=" for /F "skip=2 tokens=1,3" %%I in ('%SystemRoot%\System32\reg.exe QUERY HKCU\Console\^^%%SystemRoot^^%%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD 2^>nul') do if /I "%%I" == "QuickEdit" set "QuickEdit=%%J" if not defined QuickEdit goto ValueNotFound for /F "delims=0x" %%I in ("%QuickEdit%") do echo Quick edit is enabled explicitly for Windows PowerShell console.& goto EndBatch echo Quick edit is disabled explicitly for Windows PowerShell console.& goto EndBatch :ValueNotFound echo Could not find registry value QuickEdit of type DWORD under registry key: echo( echo HKCU\Console\%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe :EndBatch endlocal echo( pause
请注意,在这种情况下,第一个 FOR /F 命令行由两个
cmd.exe
解析。第一个是处理批处理文件的 Windows Command Processor。在执行 FOR 之前,经过解析但未执行的命令行在安装了 Windows 的情况下是这样的:for /F "skip=2 tokens=1,3" %I in ('C:\Windows\System32\reg.exe QUERY HKCU\Console\^%SystemRoot^%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD 2>nul') do if /I "%I" == "QuickEdit" set "QuickEdit=%J"
FOR 或者说
cmd.exe
在后台启动了一个带有%ComSpec% /c
和上述命令行的另一个命令进程,如上所示,作为附加参数执行:C:\Windows\System32\cmd.exe /c C:\Windows\System32\reg.exe QUERY HKCU\Console\^%SystemRoot^%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD 2>nul
这就是为什么在批处理文件中,在 FOR /F 命令行中需要使用
^^
(转义的转义字符)和%%
(转义的百分号符号)来传递最终需要作为注册表键名称的一部分的两个百分号符号给 REG 两次的原因。在批处理文件中,重定向操作符
英文:
There can be used directly in a Windows command prompt window:
%SystemRoot%\System32\reg.exe QUERY HKCU\Console\^%SystemRoot^%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD
Each of the two percent signs in the registry key is escaped with ^
to be interpreted as literal character. %SystemRoot%
inside the registry key name is not interpreted as variable reference because of the caret character ^
left to the two percent signs.
In a batch file can be used:
%SystemRoot%\System32\reg.exe QUERY HKCU\Console\%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD
The percent sign must be escaped in a batch file with one more percent sign to get it interpreted as literal character.
The entire registry key does not contain a space or one of these characters &()[]{}^=;!'+,`~<>|
making it possible to pass the registry key without surrounding "
to REG. That makes it easier in command prompt window because there must be used just twice ^
to escape the two percent signs in the registry key name.
There are three outputs possible:
- There is output to STDOUT the registry value
QuickEdit
on the registry key%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe
exists at all under registry keyHKEY_CURRENT_USER\Console
and the registry valueQuickEdit
exists under that registry key and being of type 32-bit double word (DWORD
). The exit code of REG is in this case0
indicating a successful execution tocmd.exe
processing the batch file or interpreting and executing the entered commands in the command prompt window. - There is output the following error message to STDERR if the registry key does not exist at all:
ERROR: The system was unable to find the specified registry key or value.
The exit code is1
in this case to indicate the error to the parent process. - There is output the following information message to STDOUT if the registry exists but does not contain a registry value with name
QuickEdit
at all or contains that registry value with a different type thanDWORD
.
End of search: 0 match(es) found.
The exit code is also1
in this case to indicate the failed search for this registry value to the Windows Command Processor.
The output can be suppressed with >nul 2>&1
or >nul 2>nul
or 1>nul 2>nul
if just the result depending on exit code must be evaluated using either the conditional command operators &&
and/or ||
as described by single line with multiple commands using Windows batch file or an IF [NOT] ERRORLEVEL
condition as described by the usage help of command IF output on running if /?
in a command prompt window.
A FOR /F loop can be used to validate the double word value as demonstrated below.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "QUickEdit="
for /F "skip=2 tokens=1,3" %%I in ('%SystemRoot%\System32\reg.exe QUERY HKCU\Console\^^%%SystemRoot^^%%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD 2^>nul') do if /I "%%I" == "QuickEdit" set "QuickEdit=%%J"
if not defined QuickEdit goto ValueNotFound
for /F "delims=0x" %%I in ("%QuickEdit%") do echo Quick edit is enabled explicitly for Windows PowerShell console.& goto EndBatch
echo Quick edit is disabled explicitly for Windows PowerShell console.& goto EndBatch
:ValueNotFound
echo Could not find registry value QuickEdit of type DWORD under registry key:
echo(
echo HKCU\Console\%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe
:EndBatch
endlocal
echo(
pause
There must be considered in this case that the first FOR /F command line is parsed by two cmd.exe
. The first one is the Windows Command Processor which is processing the batch file. The command line after parsing before execution of FOR is with Windows installed into C:\Windows
:
for /F "skip=2 tokens=1,3" %I in ('C:\Windows\System32\reg.exe QUERY HKCU\Console\^%SystemRoot^%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD 2>nul') do if /I "%I" == "QuickEdit" set "QuickEdit=%J"
FOR respectively cmd.exe
starts in background one more command process with %ComSpec% /c
and the command line as shown above appended as additional arguments. There is executed in background:
C:\Windows\System32\cmd.exe /c C:\Windows\System32\reg.exe QUERY HKCU\Console\^%SystemRoot^%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD 2>nul
That is the reason why in this case ^^
(escaped escape character) and %%
(escaped percent sign) must be used in the batch file in the FOR /F command line to pass to REG finally twice a percent sign as part of the registry key name. The redirection operator >
within 2>nul
must be escaped with ^
just for the cmd.exe
processing the batch file.
A less comprehensive version to check the QuickEdit
value is:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
%SystemRoot%\System32\reg.exe QUERY HKCU\Console\%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD 2>nul | %SystemRoot%\System32\findstr.exe /I /R "QuickEdit.*0x0*1$" || goto NotEnabled
echo Quick edit is enabled explicitly for Windows PowerShell console.& goto EndBatch
:NotEnabled
echo Quick edit is not enabled explicitly for Windows PowerShell console.
:EndBatch
echo(
endlocal
pause
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
echo /?
endlocal /?
findstr /?
goto /?
if /?
pause /?
reg /?
reg query /?
set /?
setlocal /?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论