如何检查具有其路径名中包含 %SystemRoot% 的注册表键是否存在?

huangapple go评论108阅读模式
英文:

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

以下是已翻译的内容:

  1. 可以直接在 Windows 命令提示符窗口中使用以下命令:

    %SystemRoot%\System32\reg.exe QUERY HKCU\Console\^%SystemRoot^%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD
    

    注:在注册表键中的两个百分号符号都使用 ^ 转义,以被解释为字面字符。由于在注册表键名称中的 %SystemRoot% 之前有插入符号 ^,它不会被解释为变量引用。

  2. 在批处理文件中可以使用以下命令:

    %SystemRoot%\System32\reg.exe QUERY HKCU\Console\%%SystemRoot%%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD
    

    注:在批处理文件中,百分号符号必须使用一个额外的百分号符号进行转义,以使其被解释为字面字符。

  3. 如果整个注册表键不包含空格或以下字符之一 &()[]{}^=;!&#39;+,~<>|,则可以在不使用 "包围的情况下将注册表键传递给 __REG__。这在命令提示符窗口中更容易,因为只需使用两次^` 来转义注册表键名称中的两个百分号符号。

  4. 可能有三种输出:

    • 如果注册表键 %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,表示未找到此注册表值的搜索失败。

    输出可以使用 &gt;nul 2&gt;&amp;1&gt;nul 2&gt;nul1&gt;nul 2&gt;nul 来抑制,如果只需要根据退出代码来评估结果,可以使用条件命令运算符 &amp;&amp; 和/或 ||,如 单行中使用多个命令的 Windows 批处理文件 中所述,或者使用命令 IF 输出上的条件,如在命令提示符窗口中运行 if /? 时使用的 IF [NOT] ERRORLEVEL 条件。

  5. 可以使用 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 &amp;()[]{}^=;!&#39;+,`~&lt;&gt;| making it possible to pass the registry key without surrounding &quot; 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:

  1. 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 key HKEY_CURRENT_USER\Console and the registry value QuickEdit exists under that registry key and being of type 32-bit double word (DWORD). The exit code of REG is in this case 0 indicating a successful execution to cmd.exe processing the batch file or interpreting and executing the entered commands in the command prompt window.
  2. 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 is 1 in this case to indicate the error to the parent process.
  3. 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 than DWORD.
    End of search: 0 match(es) found.
    The exit code is also 1 in this case to indicate the failed search for this registry value to the Windows Command Processor.

The output can be suppressed with &gt;nul 2&gt;&amp;1 or &gt;nul 2&gt;nul or 1&gt;nul 2&gt;nul if just the result depending on exit code must be evaluated using either the conditional command operators &amp;&amp; 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 &quot;QUickEdit=&quot;
for /F &quot;skip=2 tokens=1,3&quot; %%I in (&#39;%SystemRoot%\System32\reg.exe QUERY HKCU\Console\^^%%SystemRoot^^%%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD 2^&gt;nul&#39;) do if /I &quot;%%I&quot; == &quot;QuickEdit&quot; set &quot;QuickEdit=%%J&quot;
if not defined QuickEdit goto ValueNotFound
for /F &quot;delims=0x&quot; %%I in (&quot;%QuickEdit%&quot;) do echo Quick edit is enabled explicitly for Windows PowerShell console.&amp; goto EndBatch
echo Quick edit is disabled explicitly for Windows PowerShell console.&amp; 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 &quot;skip=2 tokens=1,3&quot; %I in (&#39;C:\Windows\System32\reg.exe QUERY HKCU\Console\^%SystemRoot^%_System32_WindowsPowerShell_v1.0_powershell.exe /v QuickEdit /t REG_DWORD 2&gt;nul&#39;) do if /I &quot;%I&quot; == &quot;QuickEdit&quot; set &quot;QuickEdit=%J&quot;

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&gt;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 &gt; within 2&gt;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&gt;nul | %SystemRoot%\System32\findstr.exe /I /R &quot;QuickEdit.*0x0*1$&quot; || goto NotEnabled
echo Quick edit is enabled explicitly for Windows PowerShell console.&amp; 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 /?

huangapple
  • 本文由 发表于 2023年6月22日 00:46:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76525498.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定