Board logo

标题: [文件操作] [已解决]批处理添加右键功能—复制当前文件,并改扩展名 [打印本页]

作者: HeyJude    时间: 2017-1-23 19:16     标题: [已解决]批处理添加右键功能—复制当前文件,并改扩展名

各位大侠好!
想实现这样一项功能,但在论坛的帖子中找了很久,也没能自己编出代码,劳请各位大神帮忙看看该怎样实现:

1.在右键上添加一个菜单项“复制文件并改扩展名”

2.点击这个“复制文件并改扩展名”命令,就能实现这样的效果:

①把当前已经选中的一个“×××.jpg” 文件复制到同文件夹中,并在新文件的文件名最后面(扩展名前面)添加“ - 副本”字样,即新文件名是“××× - 副本.jpg”

②把新文件“××× - 副本.jpg”的名字,改为“×××.png”

十分感谢!
作者: 老刘1号    时间: 2017-1-23 19:57

注册表-找到.jpg键-内建“右键菜单名”键值-内建command-改默认为你想要的命令
作者: HeyJude    时间: 2017-1-23 20:07

回复 2# 老刘1号


非常感谢刘大侠指点!
您说的方法我理解得还不是很清晰,眼下依然难以实现的是您说的“改默认为你想要的命令”中的“命令”内容要怎样编写。
也还请您具体指点——我1楼的难题,是否可以用批处理的 .bat 或者注册表的 .reg 来实际呈现?代码要怎样写?
万分感谢!
作者: 老刘1号    时间: 2017-1-23 20:32

  1. Windows Registry Editor Version 5.00
  2. [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shell\直接删除文件]
  3. [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shell\直接删除文件\COMMAND]
  4. @="CMD /c DEL /f /q \"%1\""
复制代码
给你个参考下
刚写的
classes后面就是文件名,可以用通配符
@代表默认=后面接命令就可以
作者: HeyJude    时间: 2017-1-23 22:08

回复 4# 老刘1号


    非常感谢刘大侠代码帮助!
经过大半天的摸索改写,我已经实现了对当前选中的.jpg文件进行右键后重命名的步骤:
@="cmd.exe /c ren \"%1\" \"牛人.png\""

但现在仍然不知道要如何把我 1 楼的两个步骤集成到这个右键中,恳请刘大侠继续帮扶!
万分感谢!
作者: CommandBatCmd    时间: 2017-1-23 22:48

回复 5# HeyJude

1楼描述的两个步骤中,文件名“××× - 副本.jpg”好像是多余的,只有“xxx.png"是最终需要的!?
作者: HeyJude    时间: 2017-1-24 00:18

回复 6# CommandBatCmd


    感谢 CommandBatCmd 大侠关注!

的确,中间的“××× - 副本.jpg”这个文件名只是我手工操作复制文件的时候 windows 系统自行生成的。在这个批处理过程中,应该是完全可以忽略跳过的。

其实,1 楼里所说的想法,右键命令就是用来一口气实现两个相连的动作:
A、在当前文件夹中,复制已经选中的当前文件;
B、复制产生的新文件,文件名和原文件相同,但后缀由 .jpg 改为 .png
作者: CommandBatCmd    时间: 2017-1-24 00:53

回复 7# HeyJude

    如果要保留源文件,直接使用copy命令,
copy /y "%~1" "%~n1.png"
把以上命令添加到“.jpg”扩展名的注册项中即可,
    如果不保留源文件,就使用ren命令。

具体写代码时,判断一下“.jpg”是否已注册,
如果已注册,使用已注册项添加右键菜单,
如果未注册,使用自定义注册项添加右键菜单。

在批处理中用命令“reg add“实现添加右键菜单。
作者: HeyJude    时间: 2017-1-24 10:45

回复 8# CommandBatCmd


    感谢 CommandBatCmd 大侠悉心指导!
试了好几个小时,您说的方法我还没有完全领会及实现。

我现在做到的是这样:

在【HKEY_CLASSES_ROOT\*\shell\复制并重命名\COMMAND】的右侧,我使用了【cmd /c copy /y "%1" "%~n1.png"】,实现了复制当前文件并改名。

但我改出来的新文件名是【%~n1.png】,不是【原文件名.png】

还请 CommandBatCmd 大侠继续点拨!而且,能不能直接写成我可以直接使用的 .bat 或 .reg 代码?万分感谢!
作者: 老刘1号    时间: 2017-1-24 13:25

回复 8# CommandBatCmd


    注册表的COMMAND没开启命令拓展,所以传参只能使用%0,套个FOR比较靠谱。
作者: HeyJude    时间: 2017-1-24 13:48

回复 10# 老刘1号


    感谢 刘大侠 诊断并指导!原来是注册表不支持【%~n1】。
for 是我非常陌生的,刘大侠 可否帮忙写一下使用 for 的代码?
万分感谢!
作者: CommandBatCmd    时间: 2017-1-24 14:19

回复 9# HeyJude


    那就直接给一个完整bat代码:
  1. @echo off&Title 添加右键“复制文件并改扩展名”&setlocal EnableExtensions
  2. SET "OldExt=.jpg"           ||@rem 指定源文件扩展名
  3. SET "KeyName=JpegFile"      ||@rem 定义源文件扩展名的注册项(如果指定扩展名已注册,则非必要,否则不能为空)
  4. SET "NewExt=.png"           ||@rem 指定新文件扩展名
  5. (REG QUERY "HKCR\%OldExt%" /ve >nul 2>nul)||(GOTO :REG)
  6. FOR /F "skip=4 tokens=1-3* delims= " %%I IN ('REG QUERY "HKCR\%OldExt%" /ve') DO IF NOT "%%~K"=="" (SET "KeyName=%%~K"&GOTO :REG) ELSE (GOTO :REG)
  7. :REG
  8. REG ADD "HKCR\%OldExt%" /ve /t REG_SZ /d "%KeyName%" /f >nul
  9. REG ADD "HKCR\%KeyName%\Shell\Copy_Ren" /ve /t REG_SZ /d "▓复制文件并改扩展名" /f >nul
  10. REG ADD "HKCR\%KeyName%\Shell\Copy_Ren\command" /ve /t REG_SZ /d "cmd /S/C \"FOR %%%%I IN (\"%%1\") DO COPY /Y \"%%%%~I\" \"%%%%~nI%NewExt%\"\"" /f >nul
  11. pause
复制代码
你测试后有什么问题再讨论!
作者: HeyJude    时间: 2017-1-24 14:41

回复 12# CommandBatCmd


    非常感谢 CommandBatCmd 大侠费了大量心血写了这么多代码,感激万分!

汇报一下我的操作情况:



一、如果将代码区中的所有代码原封不动复制到 .bat 中运行,结果是:

错误:拒绝访问。
错误:拒绝访问。
请按任意键继续. . .




二、如果将代码区首行中的【&Title 添加右键“复制文件并改扩展名”&setlocal EnableExtensions】删除,并删除这行【SET "KeyName=JpegFile"      ||@rem 定义源文件扩展名的注册项(如果指定扩展名已注册,则非必要,否则不能为空)】,运行结果是:

错误:无效项名。
键入 "REG ADD /?" 了解用法信息。
错误:无效项名。
键入 "REG ADD /?" 了解用法信息。
请按任意键继续. . .



是不是因为我的电脑注册表里其实已经有了【HKEY_CLASSES_ROOT\.jpg】、【HKEY_CLASSES_ROOT\jpegfile】和【HKEY_CLASSES_ROOT\.png】、【HKEY_CLASSES_ROOT\pnffile】?

另外,我的电脑是 Win 10 系统,是否也有关系?
作者: CommandBatCmd    时间: 2017-1-24 14:52

回复 13# HeyJude


   请用管理员身份运行,看看是否还返回“错误:拒绝访问。”?
作者: HeyJude    时间: 2017-1-24 15:23

回复 14# CommandBatCmd


    非常感谢 CommandBatCmd 大侠指点!
确实,使用【以管理员身份运行】第 12 楼完整的代码,可以顺利运行代码到底。

现在,我的注册表中:
【HKEY_CLASSES_ROOT\jpegfile\shell\Copy_Ren】的右侧,数据已经是【▓复制文件并改扩展名】了;

【HKEY_CLASSES_ROOT\jpegfile\shell\Copy_Ren\command】的右侧,数据已经是【cmd /S/C "FOR %%I IN ("%1") DO COPY /Y "%%~I" "%%~nI.png""】了。




但不知道是什么原因,在当前选中的 .jpg 文件上右键,并不能在右键菜单上出现【▓复制文件并改扩展名】。
是不是因为我是 win 10 系统的原因?
作者: CommandBatCmd    时间: 2017-1-24 15:58

回复 15# HeyJude


    1. 如果系统没有刷新,右键菜单上不会出现【▓复制文件并改扩展名】,刷新系统即可;
    2. 如果注册表项“HKCR\.jpg”的默认值“jpegfile”被其他图像程序修改,重新运行“添加右键复制文件并改扩展名.bat”即可。
你试试看如何?
作者: HeyJude    时间: 2017-1-24 16:57

回复 16# CommandBatCmd


    感谢 CommandBatCmd 大侠指点!
您的这个【cmd /S/C "FOR %%I IN ("%1") DO COPY /Y "%%~I" "%%~nI.png""】命令肯定是没有问题的。


重启电脑了,仍然是无法在当前选中的 .jpg 文件的右键菜单上找到【▓复制文件并改扩展名】。
重新运行【添加右键复制文件并改扩展名.bat】,也不行。


在【HKEY_CLASSES_ROOT】中的其他类型文件下建新项和【command】,也不行。
比如,在【HKEY_CLASSES_ROOT\textfile\shell】下建新项【EEE】和下级项【command】,刷新注册表,也无法在当前选中 .txt 文件时的右键菜单上找到【EEE】。


我在 win 7 系统的电脑上试了,也不能对某指定类型文件自定义右键菜单。真不知道是什么原因,百思不得其解了。
作者: CommandBatCmd    时间: 2017-1-24 17:17

回复 17# HeyJude


    我刚测试12楼的没有问题。
你把原始代码中用命令”REG ADD“添加到注册表中的3条注册表项导出后打包上传,看看是什么问题?
作者: HeyJude    时间: 2017-1-24 17:57

回复 18# CommandBatCmd


    非常感谢 CommandBatCmd 大侠济扶到底!
已导出这三项注册表,上传了压缩包文件,请您过目:

不知道会不会是因为注册表各项目之间大小写出入之类的原因。
作者: CommandBatCmd    时间: 2017-1-24 18:50

回复 19# HeyJude

把我注册表中的对应3条注册表项完全删除,然后导入你上传的两个注册表文件,
经测试,正常;然后混淆大小写,经测试,同样正常。没有发现不正常。

可能还是权限不够的问题?因为直接运行批处理会产生”错误:拒绝访问。“的消息。
你用管理员身份登录系统,重新运行批处理试试看怎样?
作者: CommandBatCmd    时间: 2017-1-24 21:25

回复 10# 老刘1号


注册表的COMMAND没开启命令拓展。。。

    感谢老刘1号指正,一行不经意的错误。
    怎样在注册表中开启命令拓展?尊请刘大侠传道授经!
作者: 老刘1号    时间: 2017-1-24 22:22

本帖最后由 老刘1号 于 2017-1-24 22:32 编辑

回复 21# CommandBatCmd


    仔细测试后发现%1的传参是在CMD加载之前完成的,所以理论上不能开启拓展
但是CMD是默认开启拓展的
我想你已经意识到了,所以可以在CMD的FOR内实现拓展%1
具体
  1. CMD /V:ON /K For %%a in ("%1") do Echo %%~nxa
复制代码
这样绕个弯子即可使用拓展
/Vn可以省略,CMD默认是开启拓展的
/K可以改为/C,达到执行后自动退出的目的
作者: HeyJude    时间: 2017-1-25 11:06

本帖最后由 HeyJude 于 2017-1-25 11:10 编辑

回复 20# CommandBatCmd


     非常感谢 CommandBatCmd 大侠深入分析!
  我以管理员身份重新登录了电脑,运行 .bat ,也无法实现在 .jpg 类型文件的右键菜单上显示【复制并改名】之类的新命令名。
  在整个注册表中摸索了一晚上,感觉可能会是跟某类型文件的注册信息有关,也就是说可能还会有一些角落能够彻底让某类型文件注册好、激活好。
  我的一点猜测:
  CommandBatCmd 大侠的代码,是保证注册表有了必要的“第一步”信息。剩下的,就是我的电脑还差“激活第一步”的功夫没有做。因为,我在 jpgfile 同样位置下,或者其他类型的文件下,新建右键菜单项,在选定该类型文件后右键,都是不显示新命令名的。

  这个最后一步的工作,应该是非常隐秘的角落了。等我哪天找出来了,再向您汇报!
  目前,我的曲线办法,就是把 CommandBatCmd 大侠的方法,运用到【HKEY_CLASSES_ROOT\*\shell】下,对任意文件右键时,都产生【复制并改名】右键菜单项。
作者: HeyJude    时间: 2017-1-25 11:09

回复 22# 老刘1号


  非常感谢 刘大侠 深入挖掘和指导,原来还有这么多门道,受教了!
  再次感谢 刘大侠 一路写代码帮忙!
作者: CommandBatCmd    时间: 2017-1-25 12:11

本帖最后由 CommandBatCmd 于 2017-1-25 12:42 编辑

回复 23# HeyJude

使用替换法测试一下
    把上传压缩包中“2、3  Copy_Ren.reg”的第2条值手动替换到.txt 文件类型右键菜单的“打开”中,位置在:
  1. HKEY_CLASSES_ROOT\txtfile\shell\open\command
复制代码
先备份下以上注册表项,然后将默认值改为:
  1. cmd /S/C "FOR %%I IN ("%1") DO COPY /Y "%%~I" "%%~nI.png""
复制代码
刷新注册表后【右键--》打开】测试 *.txt 文件,看能不能执行复制并重命名?

补充说一下:以上注册表项在你的电脑中不一定是默认的,用其他可用文件类型的右键菜单测试一样,
如果以上测试成功,说明.jpg 文件类型的注册表项有些问题,使用系统的文件类型注册对话框重新注册一下.jpg。
系统的文件类型注册对话框:我的电脑-->菜单-->工具-->文件夹选项-->文件类型...
作者: HeyJude    时间: 2017-1-25 13:40

回复 25# CommandBatCmd


      非常感谢 CommandBatCmd 大侠这几天费了无数心血帮忙!

  试了一下,您的方法在我的电脑上仍是不行。
  又花了大量时间找原因,终于得出一个很奇怪的结论:
  我的电脑并不是在【[HKEY_CLASSES_ROOT\×××file\shell\open\command]】这样的位置对×××类型文件的来自定义右键菜单,而是在【HKEY_CLASSES_ROOT\Applications\〖打开该类型文件的程序〗.EXE\shell\〖自定义的右键菜单项名称〗\command】中来自定义右键菜单。
  此前真不知道注册表里还有这样的优先级安排。

  再次感谢 CommandBatCmd 大侠、刘大侠 大力指导帮助!
作者: HeyJude    时间: 2017-1-25 13:45

回复 25# CommandBatCmd


    还有一个变型分支的问题,再请教一下 CommandBatCmd 大侠:

可否改一下这个语句,让复制出来的新文件使用剪贴板上的文本来作为文件名?其实质即是:如何得到剪贴板上的文本?

想将【cmd /S/C "FOR %%I IN ("%1") DO COPY /Y "%%~I" "%%~nI.png""】
改为【cmd /S/C "FOR %%I IN ("%1") DO COPY /Y "%%~I" "〖预先复制在剪贴板上的全新文件名〗.png""】
作者: CommandBatCmd    时间: 2017-1-25 15:15

回复 27# HeyJude


手动替换:
  1. cmd /S/C "FOR %%I IN ("%1") DO COPY /Y "%%~I" "〖预先复制在剪贴板上的全新文件名〗.png""
复制代码
为:
  1. cmd /S/C "FOR %%I IN ("%1") DO @mshta vbscript:createobject("scripting.filesystemobject").getfile("%%~I").copy("%%~dpI"^&clipboardData.GetData("text")^&".png")(close)"
复制代码

作者: HeyJude    时间: 2017-1-25 15:58

回复 28# CommandBatCmd


      代码完美运行!
  太感谢 CommandBatCmd 大侠了!恭祝新的一年万事如意!
作者: wind5win    时间: 2021-9-6 22:57

回复 28# CommandBatCmd


    有个感到非常复杂的添加右键想法一直没折腾出来,想请教你。任意地方复制了文件或者文件夹,到其他一个目录粘贴,想做个粘贴时判断存在重名了,自动将要复制的文件或者文件夹改名后再粘贴,请教下如何写个右键批处理或者是java、python
作者: lforl    时间: 2023-12-6 23:28

回复  CommandBatCmd


    仔细测试后发现%1的传参是在CMD加载之前完成的,所以理论上不能开启拓展
但 ...
老刘1号 发表于 2017-1-24 22:22



在命令行中,%1 是一个参数,表示传递给命令的文件的完整路径。而 %~nI 是一种参数扩展,用于提取变量 %I(在这里是循环变量)的文件名部分。
在reg的命令行中,%1 直接使用可以,但是进一步扩展使用为%~nI则不行。只能套入for中把%1传给for内部的参数,才可以利用for内部的参数进一步提取其中的文件名部分。
在这案例真切学习到了。谢谢分享!




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