无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
查看: 4250|回复: 39
打印 上一主题 下一主题

[求助] 如何用一行PECMD命令,实现PnPUtil输出输入?

[复制链接]
跳转到指定楼层
1#
发表于 2020-6-14 08:18:40 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 2010hook 于 2020-6-14 08:58 编辑

目标:先枚举已安装的第三方驱动,然后删除对应DriverStore文件。
  1. PnPUtil /enum-drivers
  2. PnPUtil /delete-driver *.inf /force
复制代码

要求1:用一行简洁的PECMD命令实现,以便写到注册表。并且能与TEAM命令共存。不可调用CMD。
要求2:如果指定只删除oem*这类驱动,又该怎么写?我想看怎么截取字符。

非常感谢!
2#
发表于 2020-6-14 09:33:01 来自手机 | 只看该作者
一行代码,套起来很晕。
多几行呗。
exec* -err+ &a=PnPUtil.exe /enum-drivers
MESS %&a%

评分

参与人数 1无忧币 +5 收起 理由
2010hook + 5 感谢大佬出手!真的需要嵌套呢,劳烦再指点.

查看全部评分

回复

使用道具 举报

3#
 楼主| 发表于 2020-6-14 14:09:26 | 只看该作者
本帖最后由 2010hook 于 2020-6-14 21:53 编辑
红毛樱木 发表于 2020-6-14 09:33
一行代码,套起来很晕。
多几行呗。
exec* -err+ &a=PnPUtil.exe /enum-drivers

输出结果包含一些空行和不需要的信息,如何准确获取所需要的行?如何准确获取包含指定字符的行?
比如:末尾是 .inf 的行,文件名长短不一。

感觉还是CMD语法简单。
回复

使用道具 举报

4#
发表于 2020-6-14 18:04:28 | 只看该作者
本帖最后由 dos时代菜鸟 于 2020-6-14 19:59 编辑

pecmd 可以实现 命令输出 文本流 的精确获取,

参考这个 pecmd 脚本


  1. envi drv3x=某个 inf 文件

  2. EXEC* &drv_result=!pnputil -i -a "%drv3x%"    ``尝试安装并将结果信息存入变量 drv_result
  3. read -*,6,Line,&drv_result  ``根据 drv_result 获取 ome inf 缓存驱动inf名称
  4. mstr oem_name=<2>%line%
  5. ifex x:\windows\inf\%oem_name%,Exec =!pnputil /delete-driver "%oem_name%" /force  ``强行删除缓存
复制代码


评分

参与人数 1无忧币 +5 收起 理由
2010hook + 5 谢谢

查看全部评分

回复

使用道具 举报

5#
发表于 2020-6-14 21:39:45 | 只看该作者
  1. ENVI^ EnviMode=1
  2. SET$ &NL=0d 0a  //设置&NL变量为换行符
  3. EXEC* -err+ -hide &PnPUtilInfos=PnPUtil.exe -e  //读取PnPUtil.exe返回信息
  4. LPOS* * ,*&FixLines=.inf%&NL%,,&PnPUtilInfos    //获取以“.inf”+“换行符”为结尾的行号
  5. FORX *v &FixLines,&Lines,
  6. {*
  7.     READ -*,%&Lines%,&OemInfInfo,&PnPUtilInfos  //读取以“.inf”+“换行符”为结尾的行的数据
  8.     MSTR * &OemInfName=<-1>&OemInfInfo  //获取改行的inf文件名全称
  9.     MESS. %&OemInfName%<这里执行你要执行的命令>
  10. }
复制代码


这只是一种方法

感觉LPOS换成用SED的表达式可能更高级,不会正则表达式,有高手来个SED的不?

评分

参与人数 1无忧币 +5 收起 理由
2010hook + 5 辛苦

查看全部评分

回复

使用道具 举报

6#
 楼主| 发表于 2020-6-14 21:51:54 | 只看该作者
PECMD复杂到,我看了两晚都不知道用什么命令,更别说诸多参数。

点评

多用几个命令,多几次就适应PECMD的语法了。  详情 回复 发表于 2020-6-14 23:00
所以,我也不愿意学PECMD,还不如学学真正的编程语言。  详情 回复 发表于 2020-6-14 22:31
回复

使用道具 举报

7#
发表于 2020-6-14 21:56:22 | 只看该作者
谢谢分享
回复

使用道具 举报

8#
发表于 2020-6-14 22:31:32 | 只看该作者
2010hook 发表于 2020-6-14 21:51
PECMD复杂到,我看了两晚都不知道用什么命令,更别说诸多参数。

所以,我也不愿意学PECMD,还不如学学真正的编程语言。
回复

使用道具 举报

9#
发表于 2020-6-14 23:00:17 | 只看该作者
2010hook 发表于 2020-6-14 21:51
PECMD复杂到,我看了两晚都不知道用什么命令,更别说诸多参数。

多用几个命令,多几次就适应PECMD的语法了。

评分

参与人数 1无忧币 +5 收起 理由
2010hook + 5 努力吧

查看全部评分

回复

使用道具 举报

10#
 楼主| 发表于 2020-6-14 23:00:44 | 只看该作者
dos时代菜鸟 发表于 2020-6-14 18:04
pecmd 可以实现 命令输出 文本流 的精确获取,

参考这个 pecmd 脚本

改成这样,执行失败,未删除。
  1. team exec* -err+ &oem=pnputil.exe /enum-drivers|read -*,*,line,&oem|exec* pnputil /delete-driver %line% /force
复制代码

点评

你得先熟悉 pnputil 的命令输出, 他的 第六行 中包含了 他在驱动安装完毕后生成的 oem 类 驱动的名字,也就是驱动缓存对应的 inf ,把这个 名字用 pecmd 的文本流操作指令 弄出来,再 用 pnputil 把这个 oem*.in  详情 回复 发表于 2020-6-15 08:11
回复

使用道具 举报

11#
 楼主| 发表于 2020-6-14 23:03:48 | 只看该作者
本帖最后由 2010hook 于 2020-6-14 23:17 编辑

正则式,用于匹配字符格式,似乎不能判断是否为指定字符。

改成这样,未成功删除:
  1. ENVI^ EnviMode=1
  2. SET$ &NL=0d 0a
  3. EXEC* -err+ -hide &PnPUtilInfos=pnputil.exe /enum-drivers
  4. LPOS* * ,*&FixLines=.inf%&NL%,,&PnPUtilInfos
  5. FORX *v &FixLines,&Lines,
  6. {*
  7.     READ -*,%&Lines%,&OemInfInfo,&PnPUtilInfos
  8.     MSTR * &OemInfName=<-1>&OemInfInfo
  9.     EXEC* pnputil /delete-driver "%&OemInfName%" /force
  10. }
复制代码
回复

使用道具 举报

12#
 楼主| 发表于 2020-6-14 23:08:12 | 只看该作者
算了,PECMD语法过于繁琐,还是改用cmd,简洁清晰,成功率高。
  1. exec *cmd /c "for /f %%a in ('pnputil /enum-drivers') do (if /i "%%~xa" equ ".inf" pnputil /delete-driver %%a /force)"
复制代码
回复

使用道具 举报

13#
发表于 2020-6-14 23:12:37 | 只看该作者
本帖最后由 slore 于 2020-6-14 23:20 编辑

如果语法设计少些符号,像常规语言这样自然就好了,
  1. exec('pnputil.exe /enum-drivers').find('oem*inf').each(inf)(exec('pnputil /delete-driver ' + inf + ' /force'))
复制代码


不然还还是 for + findstr 简单直接。
  1. for /f "tokens=2 delims=:" %%i in ('pnputil.exe /enum-drivers^|findstr "oem.*inf"') do echo pnputil /delete-driver %%i /force'
复制代码


不用看帮助,基本上一次cmd打出来就能用。

评分

参与人数 1无忧币 +5 收起 理由
2010hook + 5 说得对。不止oem开头的inf。

查看全部评分

回复

使用道具 举报

14#
 楼主| 发表于 2020-6-14 23:36:22 | 只看该作者
slore 发表于 2020-6-14 23:12
如果语法设计少些符号,像常规语言这样自然就好了,

你打算抽空重写一个吗?

点评

需要重写么?直接cmd就可以了。cmd做不到的用pecmd, 非要都用pecmd的话,有点折磨自己了。学习曲线高,也不通用。 不是专业的话,能解决问题也无性能影响写脚本就行了。 作为启动管理器,也就快捷方式和固定任  详情 回复 发表于 2020-6-14 23:55
回复

使用道具 举报

15#
发表于 2020-6-14 23:38:06 | 只看该作者
本帖最后由 红毛樱木 于 2020-6-14 23:42 编辑
2010hook 发表于 2020-6-14 23:03
正则式,用于匹配字符格式,似乎不能判断是否为指定字符。

改成这样,未成功删除:
  1. ENVI^ EnviMode=1
  2. SET$ &NL=0d 0a  //设置&NL变量为换行符
  3. EXEC* -err+ -hide &PnPUtilInfos=PnPUtil.exe -e  //读取PnPUtil.exe返回信息
  4. LPOS* * ,*&FixLines=.inf%&NL%,,&PnPUtilInfos    //获取以“.inf”+“换行符”为结尾的行号
  5. FORX *v &FixLines,&Lines,
  6. {*
  7.     READ -*,%&Lines%,&OemInfInfo,&PnPUtilInfos  //读取以“.inf”+“换行符”为结尾的行的数据
  8.     MSTR * &OemInfName=<-1>&OemInfInfo  //获取改行的inf文件名全称
  9.     //MESS. %&OemInfName%<这里执行你要执行的命令>
  10.     EXEC -wait -hide PnPUtil.exe -f -d %&OemInfName%
  11. }
复制代码


测试成功,没问题。EXEC* &PnPUtilInfos=
这种有返回信息的获取,自动加-wait的

这里的
EXEC -wait -hide PnPUtil.exe -f -d %&OemInfName%
不需要返回信息,要自己加-wait
语法帮助里有说明的。


需要用最新版的PECMD2012才可以的。http://bbs.wuyou.net/forum.php?mod=viewthread&tid=205402


点评

非常感谢热心帮助!  发表于 2020-6-15 13:45

评分

参与人数 1无忧币 +5 收起 理由
2010hook + 5

查看全部评分

回复

使用道具 举报

16#
 楼主| 发表于 2020-6-14 23:48:43 | 只看该作者
红毛樱木 发表于 2020-6-14 23:38
测试成功,没问题。EXEC* &PnPUtilInfos=
这种有返回信息的获取,自动加-wait的

我看只有2018stable可供下载。
对了,精简版和无IMd版有什么区别么?
回复

使用道具 举报

17#
发表于 2020-6-14 23:55:47 | 只看该作者
2010hook 发表于 2020-6-14 23:36
你打算抽空重写一个吗?

需要重写么?直接cmd就可以了。cmd做不到的用pecmd,
非要都用pecmd的话,有点折磨自己了。学习曲线高,也不通用。
不是专业的话,能解决问题也无性能影响写脚本就行了。

作为启动管理器,也就快捷方式和固定任务栏还有隐藏运行3个命令需要额外写(100行左右就够了)。
上面是lua语言的写法。WinXShell可以用,不用自己做解析。

其他子命令功能不是必须的。
即便上面的命令也有shortcut.exe, PinTool.exe, PinUtil.exe, hiderun.exe, nircmd.exe ... 小命令多的很。

有点跑题了,用自己习惯的擅长的就行。也不要追求1行代码,pecmd多写几行清楚的话,
多些几行也没啥问题啊。
目前对我来说cmd+lua够用,作为开发者自己也可以随意改造扩展,不会花费时间另写命令,
对于绝大部分人pecmd也足够用。


点评

所言极是,受教了。WinXShell更规范强大,慢慢学习。  发表于 2020-6-15 11:44
适合自己的才是最好的。  详情 回复 发表于 2020-6-15 00:07
回复

使用道具 举报

18#
发表于 2020-6-15 00:07:42 | 只看该作者
slore 发表于 2020-6-14 23:55
需要重写么?直接cmd就可以了。cmd做不到的用pecmd,
非要都用pecmd的话,有点折磨自己了。学习曲线高, ...

适合自己的才是最好的。
回复

使用道具 举报

19#
发表于 2020-6-15 08:11:19 | 只看该作者
本帖最后由 dos时代菜鸟 于 2020-6-15 08:50 编辑
2010hook 发表于 2020-6-14 23:00
改成这样,执行失败,未删除。

你得先熟悉 pnputil  的命令输出,
他的 第六行 中的 第二个单词是 他在驱动安装完毕后生成的  oem 类 驱动的名字,也就是驱动缓存对应的 inf ,把这个 名字用 pecmd 的文本流操作指令 弄出来,再 用 pnputil 把这个 oem*.inf  强行卸载,他对应的 缓存也就没有了呗。

如果用 pnputil.exe /enum-drivers 获取当前系统所有的 oem 也不难,找出每行第二个单词前三个字母是 oem 的,就行呗。
  1.     ENVI^ EnviMode=1
  2.     Exec* &oem_s=!PnPUtil.exe -e
  3.     envi. oem_XXX=
  4.     Forx *NL &oem_s,oem_x,
  5.     {
  6.             mstr oem_x2=<2>,%oem_x%
  7.             mstr oem_x3=0,3,%oem_x2%
  8.             ifex '%oem_x3%'='oem',
  9.             {
  10.                     envi.  oem_XXX=%oem_xxx%\n%oem_x2%
  11.             }
  12.     }
  13.     mess %oem_xxx%
复制代码



点评

pnputil我熟悉,就不知怎么修改pecmd得到所需*.inf参数。  发表于 2020-6-15 11:53
回复

使用道具 举报

20#
 楼主| 发表于 2020-6-15 11:36:09 | 只看该作者
本帖最后由 2010hook 于 2020-6-15 13:36 编辑
dos时代菜鸟 发表于 2020-6-15 08:11
你得先熟悉 pnputil  的命令输出,
他的 第六行 中的 第二个单词是 他在驱动安装完毕后生成的  oem 类  ...

非常感谢耐心讲解,我慢慢学习。
大家不要被oem字样所误导,用某些第三方工具集成驱动,名字是原始文件名,不带oem字样。只要列出的inf都属第三方。
我这贴提及oem,原本想学习pecmd怎么提取字符串,没想到其繁琐程度远超想象。

点评

那就换个思路,找个关键词,设置关键词是 “发布名称:” ,中文环境下测试成功。 [attachimg]459561[/attachimg]  详情 回复 发表于 2020-6-15 21:52
那是PECMD作者把功能实现的太复杂,支持更多复杂要求。 比如,批处理默认for就是一行行的内容分割。 PECMD一段内容你可以随意分割,所以需要NL,或者 SET$ &NL=0d 0a //设置&NL变量为换行符 这就增加  详情 回复 发表于 2020-6-15 12:49
我贴的示例代码,按你要求一直不差的弄得哎  详情 回复 发表于 2020-6-15 12:26
回复

使用道具 举报

21#
发表于 2020-6-15 12:26:46 来自手机 | 只看该作者
2010hook 发表于 2020-6-15 11:36
非常感谢耐心讲解,我慢慢学习。
大家不要被oem字样所误导,用某些第三方工具集成驱动,名字是原始文件 ...

我贴的示例代码,按你要求一直不差的弄得哎

点评

我不懂改成15楼那样,超出我能力了。  发表于 2020-6-15 13:43
一行简洁的PECMD命令实现。。。  发表于 2020-6-15 12:38
回复

使用道具 举报

22#
发表于 2020-6-15 12:49:18 | 只看该作者
2010hook 发表于 2020-6-15 11:36
非常感谢耐心讲解,我慢慢学习。
大家不要被oem字样所误导,用某些第三方工具集成驱动,名字是原始文件 ...
原本想学习pecmd怎么提取字符串,没想到其繁琐程度远超想象。


那是PECMD作者把功能实现的太复杂,支持更多复杂要求。

比如,批处理默认for就是一行行的内容分割。

PECMD一段内容你可以随意分割,所以需要NL,或者
SET$ &NL=0d 0a  //设置&NL变量为换行符

这就增加了命令的使用难度。多少人知道0d 0a是啥意思?

另外pecmd的命令按设计来说是支持各种编码以及二进制模式,不限定为文本,所以
使用复杂度就上去了。

字符串操作看上面的例子就是 mstr命令吧,不过貌似不支持嵌套,

mstr oem_x2=<2>,%oem_x%
mstr oem_x3=0,3,%oem_x2%

要分好几步骤拆分。

单词获取  <数字>,源字符串
字符串截取  起始位置,长度,源字符串

再多了些引入的临时变量会更多,不知道是否支持 正则表达式,不然的话可以一次性取出。

点评

SED命令支持正常表达式,可是不会写高级的正则表达式。。。  详情 回复 发表于 2020-6-15 13:32
回复

使用道具 举报

23#
发表于 2020-6-15 13:32:28 | 只看该作者
slore 发表于 2020-6-15 12:49
那是PECMD作者把功能实现的太复杂,支持更多复杂要求。

比如,批处理默认for就是一行行的内容分割 ...

SED命令支持正常表达式,可是不会写高级的正则表达式。。。
回复

使用道具 举报

24#
发表于 2020-6-15 21:52:27 | 只看该作者
2010hook 发表于 2020-6-15 11:36
非常感谢耐心讲解,我慢慢学习。
大家不要被oem字样所误导,用某些第三方工具集成驱动,名字是原始文件 ...

那就换个思路,找个关键词,设置关键词是 “发布名称:” ,中文环境下测试成功。



  1. ENVI^ EnviMode=1
  2. envi X_sing=发布名称:

  3.     Exec* &oem_s=!PnPUtil.exe -e
  4.     envi. oem_XXX=
  5.     Forx *NL &oem_s,oem_x,
  6.     {
  7.             mstr oem_x1,oem_x2=<1><2>%oem_x%
  8.             ifex '%oem_x1%'='%X_sing%',
  9.             {
  10.                     envi.  oem_XXX=%oem_xxx%\n%oem_x2%
  11.             }
  12.     }
  13.     mess %oem_xxx%
复制代码





回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-5-7 22:06

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表