All;
我整天都在互联网上,试图让批处理文件写入/工作。
只是为了开始 - 我希望仅通过批处理文件和/或命令行完成这项工作。
我希望删除特定数据(不区分大小写 - 因为数据可能是'data'
或'Data'
或'DATA'
)。
我看到的实际数据的大多数操作系统都是Win XP机器。具体如下:
我希望专门从REG_MULTI_SZ
注册表值中删除数据"browser
"(同样,它也可以是"Browser
"或"BROWSER
"),子项位于:
HKLMSYSTEMCurrentControlSetServiceslanmanserverparameters
实际值为:
NullSessionPipes
我总是在这个值中看到多条数据("browser
"在混合的某个地方)。无论browser
是值中唯一的数据片段,还是多段数据,我都需要能够执行.bat才能删除它。
我的研究指出我查询数据,删除"browser
"数据,然后重新插入剩余的数据 - 我只是无法成功做到这一点。
我尝试在我的机器 (Win10) 上创建一个虚拟的测试键/值,如下所示:
HKCUTempTest
其中包含以下数据:
Test #1
Test #2
browser
Browser
BROWSER
Test #3
Test #4
我所做的一切,我都无法从这些数据中删除仅/任何形式的browser
,留下其余的"Test #x
"数据。
请告知任何人都可以提出的任何解决方案。
更新以下是我在整个研究中能够组合在一起的代码(我已经将几个不同的批处理文件放在一起,但没有积极的结果): (注意:我绝不认为这些代码是这样的,因为其中大部分是从/跨许多不同的位置编译的):
测试1.bat
这个测试不断删除整个值,我无法弄清楚。
@echo off
for /f "tokens=*" %%a in ('
reg query "HKCUTemp" /v "Test" /f "browser Browser BROWSER" /d /e
^| find "REG_MULTI_SZ"
') do (
setlocal enableDelayedExpansion
rem Split
set "line=%%a"
set "value=!line:*REG_MULTI_SZ=REG_MULTI_SZ!"
call set "name=%%line:!value!=%%"
rem Trim spaces
for /L %%b in (1,1,10) do if "!name:~-1!"==" " set "name=!name:~0,-1!"
echo Deleting !name!
reg delete "HKCUTemp" /v "!name!" /f
endlocal
)
pause
测试2.bat
这是尝试将数据导出到 txt 文件中,然后删除"浏览器" - 另一个失败的尝试。
@echo off
reg query HKCUTemp /v Test > c:Temptmp01.txt
FOR /F "tokens=2,3*" %%a in (c:Temptmp01.txt) do call :sub1 %%b
:sub1
if %1x==browser goto end
echo %1
REG ADD HKCUTemp /f /v Test /t REG_MULTI_SZ /d %1
:end
goto :eof
测试3.bat
这次尝试最终用"%b"替换了我的"Test"值的所有数据
@echo off & setlocal ENABLEEXTENSIONS
set k="HKCUTemp"
set v="Test"
for /f "tokens=*" %%a in ('reg query %k% /v %v%') do (
set "d=%%b"
)
set "d=%d:browser =%"
set "d=%d: =%"
reg add %k% /v %v% /t REG_MULTI_SZ /d "%d%" /f
我确实遇到过一些主题,其中用户表示,如果将数据转换为十六进制/二进制,这会更容易完成吗? 我希望这有助于给某人一些关于我在这里到底做错了什么的想法。
只要多字符串内容中没有一行是双引号的,我可能会这样写它:
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "_k=HKLMSYSTEMCurrentControlSetServicesLanmanServerParameters"
Set "_v=NullSessionPipes"
Set "_s=Browser"
Set "_d="
For /F "EOL=H Tokens=2*" %%A In ('Reg Query "%_k%" /V "%_v%"'
) Do If "%%A"=="REG_MULTI_SZ" Set "_d=%%B"
If "%_d%"=="" Exit /B
Set "_d=%_d: =%"
Set "_m="
For %%A In ("%_d: =","%"
) Do Echo %%A|Find /I "%_s%">Nul||Call Set "_m=%%_m%%%%A "
If "%_m%"=="" Exit /B
Reg Add "%_k%" /V "%_v%" /T "REG_MULTI_SZ" /D %_m:~,-2% /F>Nul
请注意,这使用Find
, (行15
)来匹配任何包含Browser
的行 , (不区分大小写), 如果您想匹配仅包含字符串Browser
的行, (不区分大小写),那么您可能希望查看FindStr
命令,(在命令提示符下输入FindStr /?
以获取用法信息)
有一个主要的警告:多字符串注册表项的值数据确实可能很长,如果您确定要写回注册表的字符串数据不会超过最大字符长度,那么您就没问题了。如果没有,恐怕我想不出任何其他简单的方法来执行任务。(将数据以十六进制形式写入注册表文件,*.reg
并导入/合并它)。
下面是此任务的注释批处理文件:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "skip=2 tokens=1,2*" %%A in ('%SystemRoot%System32reg.exe query HKLMSYSTEMCurrentControlSetServiceslanmanserverparameters /v NullSessionPipes 2^>nul') do if /I "%%A" == "NullSessionPipes" if "%%B" == "REG_MULTI_SZ" set "NullSessionPipes=%%C" & goto ProcessValue
echo Registry value NullSessionPipes was not found in registry.
goto EndBatch
rem The goal is to remove all ENTIRE strings BROWSER written in any case.
rem Other strings containing by chance also BROWSER at beginning or end
rem of the string should not be removed from multi-string value. For that
rem reason run case-insensitive string substitution with browser to
rem really match entire BROWSER string. But there can be multiple BROWSER
rem strings in sequence which are not all removed with one run on using
rem browser and so a loop is required make the string substitution
rem with browser until this string is not removed anymore from value.
rem But BROWSER could be exist also as first string in value with no
rem preceding . For that reason is extra added at beginning and
rem then removed after removing all entire BROWSER strings.
rem REG ADD requires that there is no at end of multi-string value
rem to successfully add the multi-string value to Windows registry. The
rem data must end with last character of last string or with just .
rem For that reason the last two characters being on Windows XP and
rem Windows Server 2003 are removed before even starting processing the
rem multi-string value. REG of Windows Vista and later Windows versions
rem does not output multi-string value with at end like REG of
rem Windows XP. It outputs the multi-string with no at end. So it
rem is necessary to append at end in case of last string is BROWSER.
rem It is also necessary to do nothing if the NullSessionPipes value exists
rem with no string resulting on Windows Vista and later Windows version in
rem nothing assigned to NullSessionPipes and so the environment variable
rem does not exit at all. On Windows XP is assigned in this case just
rem which on further processing results also in an empty string and
rem therefore deletion of environment variable NullSessionPipes after
rem removing this final end of multi-string marker.
rem On Windows Vista and later Windows versions it is also necessary to
rem append at end of environment variable string as otherwise with an
rem existing string ending by chance with a backslash this backslash would
rem be interpreted by REG as escape character for the double quote used to
rem enclose the data argument string on command line in double quotes on
rem adding the final multi-line string value. So without appending at
rem end string like TEST as last string of NullSessionPipes value would
rem become TEST" which of course is not wanted avoided by using TEST\0
rem at end of environment variable string for this use case.
rem After removing all entire BROWSER strings from value it is checked
rem if the new value is not identical to value read from registry which
rem means at least one BROWSER string was really removed and so it is
rem necessary to write new value without BROWSER back to Windows registry.
:ProcessValue
if "%NullSessionPipes%" == "" goto EndBatch
if "%NullSessionPipes:~-2%" == " " set "NullSessionPipes=%NullSessionPipes:~0,-2%"
if "%NullSessionPipes%" == "" goto EndBatch
if not "%NullSessionPipes:~-2%" == " " set "NullSessionPipes=%NullSessionPipes% "
set "NewSessionPipes= %NullSessionPipes%"
:RemoveBrowser
set "TmpSessionPipes=%NewSessionPipes: browser = %"
if not "%TmpSessionPipes%" == "%NewSessionPipes%" set "NewSessionPipes=%TmpSessionPipes%" & goto RemoveBrowser
set "NewSessionPipes=%TmpSessionPipes:~2%"
if "%NewSessionPipes%" == "%NullSessionPipes%" echo Current NullSessionPipes value does not contain the string BROWSER.& goto EndBatch
echo Current NullSessionPipes value is:
echo/
echo %NullSessionPipes%
echo/
echo New NullSessionPipes value is:
echo/
echo %NewSessionPipes%
echo/
%SystemRoot%System32reg.exe add HKLMSYSTEMCurrentControlSetServiceslanmanserverparameters /v NullSessionPipes /t REG_MULTI_SZ /d "%NewSessionPipes%"
:EndBatch
endlocal
命令行的输出
C:WindowsSystem32reg.exe query HKLMSYSTEMCurrentControlSetServiceslanmanserverparameters /v NullSessionPipes 2>nul
由 FOR在后台以cmd /C
启动的单独命令进程中执行取决于REG的版本。
在 Windows Vista 和 Windows Server 2008 以及所有更高版本的 Windows 上,输出以空行开头,第二行是注册表项,第三行包含注册表值名称、值类型和以空格分隔的值数据。
在 Windows XP 和 Windows Server 2003 上,输出以空行开头,下一版本的REG,再有一个空行,第四行包含注册表项,第五行最后包含注册表值名称、值类型和值数据,并带有四个缩进空格,并由水平制表符分隔。
因此,从REG的不同输出中,只能跳过前两行。下一行包含 Windows Vista/Server 2008 和所有更高版本的 Windows 上感兴趣的数据。但是在Windows XP和Server 2003上,有必要从捕获的REG输出中处理更多行,直到到达感兴趣的数据的第五行。因此,在退出循环并处理值之前,使用两个附加的IF条件来 100% 确定注册表值NullSessionPipes
的多字符串值确实分配给环境变量NullSessionPipes
。
Windows XP 上的REG输出,NullSessionPipes
存在但不包含任何字符串:
! REG.EXE VERSION 3.0
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServiceslanmanserverparameters
····NullSessionPipes» REG_MULTI_SZ»
上面的输出示例中·
和下面的所有其他示例中表示缩进/分隔空格字符。»
表示分隔的水平制表符。
Windows XP 上的REG输出,NullSessionPipes
存在但不包含任何字符串:
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServiceslanmanserverparameters
····NullSessionPipes····REG_MULTI_SZ····
Windows XP 上包含字符串的REG输出示例NullSessionPipes
:
! REG.EXE VERSION 3.0
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServiceslanmanserverparameters
····NullSessionPipes» REG_MULTI_SZ» browser test #1 BROWSER Browser Test#2 TEST\0browser
Windows 7 上包含字符串的REG输出示例NullSessionPipes
:
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServiceslanmanserverparameters
····NullSessionPipes····REG_MULTI_SZ····browser test #1 BROWSER Browser Test#2 TEST\0browser
对于具有多个字符串的示例,要在命令行上添加的数据字符串为:"test #1 Test#2 TEST\0"
使用REG将修改的值添加到注册表的命令行不包含强制覆盖的选项/f
。这使您可以在真正将新值写入注册表之前检查新值。插入参数/f
左边/d
,以便在验证批处理文件按预期工作后,是否应该没有覆盖现有值的提示。
要了解使用的命令及其工作原理,请打开命令提示符窗口,在那里执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
echo /?
endlocal /?
goto /?
if /?
reg /?
reg add /?
reg query /?
set /?
setlocal /?
另请参阅使用 Windows 批处理文件的单行多个命令,了解运算符&
的说明。