Board logo

标题: [注册表类] 批处理怎样在注册表中遍历全部路径分支后删除所有含指定字符串的键和键值? [打印本页]

作者: huyou96    时间: 2017-7-31 16:21     标题: 批处理怎样在注册表中遍历全部路径分支后删除所有含指定字符串的键和键值?

我的思路是这样的,比如我要删除含有"Baidu"字符串的所有键及键值,先用reg query指令搜索到,然后再针对搜到结果用reg delete指令予以删除,由于reg指令无法指定由一个总的根部来搜起,必须从HKCR、HKCU、HKLM、HKU、HKCC这五个根搜起,那好吧,我不嫌麻烦,分别从这五个根搜起,再分别把搜到的含有特定字串的键和键值都删掉,不就实现了么。
可是,reg delete指令删除时要区分到底是对键进行删除还是对键值删除,就是说要区分对待键与键值来不同地进行删除,删除键时直接用 reg delete /f 键名 即可,删除键值时 要用 reg delete /f /v 键值名 才可以,如果是默认空键值,要用 reg delete /f /ve 才可删除之。
比如用 reg query HKCR /s ^| find /i "Baidu" 搜到的在HKCR分支下的所有含有"Baidu"字符串的键和键值,但要使用该搜到结果,就要有效分离键和键值,判断搜到的到底是键还是键值,用搜到结果字符串的前四个字符就可以判断,如果搜到结果是"HKey"打头的那绝对是键了,而其余则为键值,而其中含(Default)的又是默认空键值。

举例,以下批处理里的搜索语句可以将全注册表所有含有"Baidu"字符串都搜到

for /f "delims=" %%k in ('reg query HKCR /s ^| find /i "Baidu"') do (
echo %%k
)

for /f "delims=" %%k in ('reg query HKCU /s ^| find /i "Baidu"') do (
echo %%k
)

for /f "delims=" %%k in ('reg query HKLM /s ^| find /i "Baidu"') do (
echo %%k
)

for /f "delims=" %%k in ('reg query HKU /s ^| find /i "Baidu"') do (
echo %%k
)

for /f "delims=" %%k in ('reg query HKCC /s ^| find /i "Baidu"') do (
echo %%k
)

可是啊,这个思路看起来很好,但实际操作起来却非常不容易,搜到结果如果是在do循环语句里进行字符串比较来分辨出或分离出键与键值,这不是我的所长,我向来头疼在do语句中实现if判断,尤其是用字符串截取的比较,要知批处理没有字符串截取子字符串函数,尤其我一直搞不太明白在do循环里常用截取子字符串用法每每失灵或失效。

所以,求大虾帮忙写写能实现这样搜遍全注册表而把查到的某字符串的键和键值统统予以删除的一个批处理;不用我上面这个思路也可以,只要能实现这样的功能就可以。
先谢谢了!
作者: Batcher    时间: 2017-7-31 19:48

尤其我一直搞不太明白在do循环里常用截取子字符串用法每每失灵或失效

把你的代码发出来我看看
初步怀疑你没有开启变量延迟扩展
作者: huyou96    时间: 2017-8-1 00:55

本帖最后由 huyou96 于 2017-8-1 01:14 编辑
我的思路是这样的,比如我要删除含有"Baidu"字符串的所有键及键值,先用reg query指令搜索到,然后再针对搜 ...
huyou96 发表于 2017-7-31 16:21


版主,非常惭愧,我试验的代码满屏是错误,无法使用。惭愧惭愧啊!

大致如下:

TestQryDelBaidu.bat


for /f "delims=" %%k in ('reg query HKCR /s ^| find /i "Baidu"') do (

set /a "startfour=%%k:~0,4%%"
echo The begining four characters of result string are as follows:
echo "%%startfour%%"

if "%%startfour%%" equ "HKEY" (
set "key=%%k%%"
echo "This is a key:"
echo "%%key%%"
) else (
set "keyvalue=%%k%%"
echo "This is a key value:"
echo "%%keyvalue%%"
rem I still don't find out a way about how to cut a key value substring out of a result string...
)

)

因为对查询结果的处理不理想,也曾想过用重定向先把结果写进一个txt文本文件里去保存起来,然后再从该文件进行读取和处理,用过后在批处理里删除该文件就好了…… 也没试…… 总觉得自己水平太有限,对于这个处理起来力不从心…… 不过如果能实现这个批处理的功能,相信它的用处很大,很多据特定指定字符串来查遍整个注册表来进行删除或改写的地方,都可以不再用人工去注册表编辑器了,通过一个批处理就可搞定了……

我的思路是这样的,如果   echo "%%key%%" 这条语句结果跑正确了,那么我就可以用 reg delete "%%key%%" /f 来替代它,就可实现删除键的功能了。
echo "%%keyvalue%%" 这里的键值部分,很麻烦,首先,我做的那个查询语句的查询结果里没提供所在的键,只有键值的名称、类型、数据三样结果,其次即使知道了键值所在的键名,也要再做一次分离,把头一个去掉前后空格后的键值名分两种予以判断:如果是去掉前后空格后等于(Default)的是默认空键值,用 reg delete 键名 /f /ve 来删除,否则用  reg delete 键名 /f /v 键值名 来删除。也够麻烦的,我还没做试验…… 只有思路, 还没办法……

我连查询结果截取头四个字符跟HKey做比对,截取四个字符的子串都没做对…… 非常水,也非常惭愧……

请您多多指教啦!诚挚感谢!
作者: huyou96    时间: 2017-8-1 08:44

本帖最后由 huyou96 于 2017-8-1 08:54 编辑

向版主和大家们补充一下:

我刚刚在第3楼提及的删除键的部分请不用再考虑了。

因为根本不必要对查询结果截子串赋变量做判断了,reg query 指令所带参数开关完全可以很好很简洁地解决含有指定字符串的键的删除问题。

在批处理中实现遍历全注册表删除所有键名含"Baidu"(不分大小写)的键,代码如下:

for /f "delims=" %%k in ('reg query HKCR /s /f Baidu /k') do reg delete "%%k" /f
for /f "delims=" %%k in ('reg query HKCU /s /f Baidu /k') do reg delete "%%k" /f
for /f "delims=" %%k in ('reg query HKLM /s /f Baidu /k') do reg delete "%%k" /f
for /f "delims=" %%k in ('reg query HKU /s /f Baidu /k') do reg delete "%%k" /f
for /f "delims=" %%k in ('reg query HKCC /s /f Baidu /k') do reg delete "%%k" /f


经过上面这五条语句的删除后,其实属于键值名或键值数据里含"Baidu"的很多键值也随之而被删除掉了。

这之后,再去用如下这条批处理指令去查询,所查到的结果就都是属于键值了,再也没一个是属于键了:
for /f "delims=" %%k in ('reg query HKCR /s /f Baidu') do echo "%%k"

如果想仅仅查询默认空键值的数据中含有"Baidu"的结果,可用如下语句(可能执行起来耗时要长些):
for /f "delims=" %%k in ('reg query HKCR /s /f Baidu ^| find /i "(Default)"') do echo "%%k"
或者
for /f "delims=" %%k in ('reg query HKCR /s ^| find /i "Baidu" ^| find /i "(Default)"') do echo %%k

那现在关键问题还是我在第3楼提到过的: 现在运行查询,都只有键值了,但查询语句的查询结果里并没提供该键值所在的键,只有键值的名称、类型、数据三样结果,而若用 reg delete 指令来删除键值,确实要有该键值所在的键的位置才可以,请教:该怎么办?
(我再仔细看过 reg query /? 的英文帮助说明,我这里是英文系统,也确实没找到能得到该键值所在键的办法,不得要领啊,也许是我太笨太愚钝了吧……)

请大家帮我搞掂:
怎么才能删除注册表中剩余的名称或数据含有"Baidu"的键值?
任何方法都行,只要能达成目的就行。谢谢!
作者: Batcher    时间: 2017-8-1 10:05

回复 3# huyou96


使用 setlocal enabledelayedexpansion 开启变量延迟扩展,参考:
http://bbs.bathome.net/thread-2899-1-1.html
作者: huyou96    时间: 2017-8-1 11:48

回复  huyou96

使用 setlocal enabledelayedexpansion 开启变量延迟扩展,参考:
Batcher 发表于 2017-8-1 10:05


谢谢!非常感谢!非常棒的教程,一定要好好拜读的!受教啦!
作者: huyou96    时间: 2017-8-1 19:40

本帖最后由 huyou96 于 2017-8-1 19:52 编辑

大家好!我又上来了。一脚没踩住,又把我给冒上来了。

再次来勘误了,呵呵,也是我水平太凹,所以眼大漏神,连查询结果仔细看看都没咋看,就瞎说,有的地方说错了,而且是严重的大错特错咧,现冒上来予以更正了。

我在第4楼说的那五条删除所有键名含"Baidu"的语句是完全正确的,全注册表删除键名含指定字串的就那么简单,没说的。

是我在第3楼和第4楼所谓的有关键值名和键值数据中含"Baidu"的查询结果中仅有键值的名称、类型、数据三样结果却无所在键的键名的说法,则全都是不用心、不仔细、眼大漏神、没对结果做详尽分析的断言,就是说全都是胡说八道,现郑重予以全部推翻!呵呵,自己推翻自己之前的错误论断咯。

查询结果里怎能就没所在键的键名呢?有的啊!原来是这样子:搜寻结果里先跟出来的就是键名,然后一个键名下可能不止一个键值或键值的数据中含有指定检索的字符串,那就在该键名下都列出,每次列出都归于前次列出的那个键名之下啊,直到又出现下一个键名为止,然后又跟着这个键名下的符合的键值或键值数据……

请比较一下以下几个在命令行直接执行的查询的结果,就都清楚了。注意,这是在命令行直接查询并比对结果,所以变量用了一个百分号,如是在批处理里要做转义就要用两个百分号,这是毋庸多言的常识咯。
(可能有个别菜鸟新手,连注册表的键和键值也分不清。以资源管理器做比,键就相当于文件夹了,键名就相当于文件夹名了,键值就相当于文件了,键值名就相当于文件名了,键值数据就相当于文件里的内容了,键值类型就相当于文件类型了。注册表是从INI文件演化成树状数据库的,过去INI文件里的段名也相当于注册表的键了,在注册表编辑器里看到的一个个“文件夹”就是键了,其下含有的“文件”就是键值了,键在注册表最初时是被称为“蜂巢”即英文Hive的,所以每个根部蜂巢键都以HKey打头来命名,HKey即HiveKey的缩略形式。)

for /f "delims=" %k in ('reg query HKCR /s /f Baidu') do echo "%k"
rem 上面这条语句是对HKCR分支下所有键名、键值名、键值数据中含Baidu字符串者进行查询

for /f "delims=" %k in ('reg query HKCR /s /f Baidu /k') do echo "%k"
rem 上面这条语句是对HKCR分支下所有键名中含Baidu字符串者进行查询

for /f "delims=" %k in ('reg query HKCR /s /f Baidu /v') do echo "%k"
rem 上面这条语句是对HKCR分支下所有键值名中含Baidu字符串者进行查询

for /f "delims=" %k in ('reg query HKCR /s /f Baidu /d') do echo "%k"
rem 上面这条语句是对HKCR分支下所有键值数据中含Baidu字符串者进行查询


所以,现在都清楚了思路该怎么做:只有删除键名中含Baidu者最简单,直接提取到后删掉就行了。

要删掉键值名、键值数据中含Baidu者,还是需要在带/v开关或/d开关的for循环中将查询结果中的字符串截取头四个字符后无分大小写地跟HKey做比对,符合者存入keyname变量,然后接下来每次做头四比对,不符者都存入valueN变量或dataN,要对变量的数量进行计数,作为之后删除时大循环内小循环的循环次数用,直到遇到下一个符合头四为Hkey者,先要去执行一个小循环,因为reg delete每次只能删除一个键值,所以如某键下含有多个符合的键值或键值数据就需要在小循环里多次进行删除,删完后,再重复执行大循环的比对头四,并赋值给变量的新一番循环。

以上用中文文字伪代码描述的,要实现起来不是那么容易,我想想都觉得很难,就说结果中取到符合的键值名吧,要把查询结果中的字符串挤掉前后空格的头一个子字符串截取出来作为键值名赋给变量,想实现这个,想想都够头疼的了。
查询结果忽略前面的键名,一般都是像如下这样的含键值名、键值类型、键值数据及空格的长字符串:
"    C:\users\huyou\appdata\roaming\baidu\baidunetdisk\baidunetdisk.exe.FriendlyAppName    REG_SZ    BaiduNetdisk"
"    C:\Users\Huyou\AppData\Roaming\baidu\BaiduNetdisk\YunDetectService.exe.FriendlyAppName    REG_SZ    YunDetectService.exe"
"    URL Protocol    REG_EXPAND_SZ    C:\Users\Huyou\AppData\Roaming\baidu\BaiduNetdisk\YunDetectService.exe"
"    Target    REG_SZ    C:\Users\Huyou\AppData\Roaming\baidu\BaiduNetdisk\"
"    (Default)    REG_SZ    C:\Users\Huyou\AppData\Roaming\baidu\BaiduNetdisk\YunShellExt64.dll"
"    URL Protocol    REG_EXPAND_SZ    C:\Users\Huyou\AppData\Roaming\baidu\BaiduNetdisk\YunDetectService.exe"
"    (Default)    REG_EXPAND_SZ    C:\Users\Huyou\AppData\Roaming\baidu\BaiduNetdisk\YunDetectService.exe,0"
"    (Default)    REG_EXPAND_SZ    "C:\Users\Huyou\AppData\Roaming\baidu\BaiduNetdisk\YunDetectService.exe" "%1""
"    C:\users\Huyou\appdata\roaming\baidu\baidunetdisk\baidunetdisk.exe.FriendlyAppName    REG_SZ    BaiduNetdisk"
"    url2    REG_SZ    https://pan.baidu.com/s/1pLrOh7d"

要我来做,水平凹,说不准做大半天也没能调好理顺,暂时放在这儿吧。如果能有大虾肯出手做出来,将非常感激不尽。就先说到此为止吧。恭祝各位晚安!




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2