[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[注册表类] 求助批处理reg右键菜单实现:获取所选中的一个或多个文件路径|文件名

本帖最后由 lforl 于 2024-10-25 22:32 编辑

写一个reg右键菜单实现:当我在资源管理器中,选择一个或者多个文件的时候,获取这些文件的路径(含文件名和后缀名)。
●如果选择的是一个文件,则将其路径发送到剪贴板。
如果选择的是多个文件则将他们文件名发送到剪贴板(而非路径)。如果实在有困难,就获取多条路径也行。

外面比较常见的是一个vbs写的注册表右键。当选择多个文件的时候运行就报错。期待大佬路过,指点解决一下这个经典需求。多谢!

下面是GPT帮忙写的,没有实现效果,功力不足看不出问题在哪里。盼大佬斧正指点。
感觉关键是:在多个文件被选中的时候,用for循环得到的多个值,如何收集到一个变量里。
  1. Windows Registry Editor Version 5.00
  2. [HKEY_CLASSES_ROOT\AllFilesystemObjects\shell\CopyPathOrName]
  3. @="复制路径或(多选时)文件名(&F)"
  4. [HKEY_CLASSES_ROOT\AllFilesystemObjects\shell\CopyPathOrName\command]
  5. @="cmd /c @echo off && (if \"%%~2\"==\"\" (echo|set /p=\"%%~f1\"|clip) else (for %%i in (%%*) do @echo %%~nxi) | clip) && exit"
复制代码

本帖最后由 aloha20200628 于 2024-10-22 22:53 编辑

回复 1# lforl

参见一》https://cloud.tencent.com/developer/news/436620
参见二》https://www.xitongzhijia.net/xtjc/20170105/90289.html

TOP

分开来 ,单独弄一个bat

TOP

回复 2# aloha20200628


   shift键内置这种玩法,我玩过,复制出来的都带引号的,不太适合。谢谢哈....

TOP

注册表脚本不支持多文件,表现就是多个文件执行bat,会弹出多个cmd窗口。所以简单的脚本貌似无解,开发dll等操作不在此列
目前建议有两个,
一个利用右键发送功能,直接把多文件发送给脚本,这个可以支持多文件。
二个是采用集成有这类功能的资源管理,推荐Directory Opus,这也是我目前在用的管理器,替换系统管理器无压力。

下面是两个功能的vbs脚本,分别保存为vbs文件后,
在开始--运行--输入shell:sendto,把两个vbs文件复制进去即可,
之后选择多个文件后,点右键--发送即可实现相关功能。
  1. '复制多文件完整路径到剪切板
  2. Dim filearray()
  3. ReDim filearray(WScript.Arguments.Count - 1)
  4. For i = 0 To WScript.Arguments.Count - 1
  5. filearray(i) = WScript.Arguments(i) & ">>tem"
  6. Next
  7. filearrays=join(filearray, "&echo ")
  8. CreateObject("WScript.shell").Run "cmd /C echo " & filearrays & "&clip<tem&del tem", 0
复制代码
  1. '复制多文件名称到剪切板
  2. Dim filearray()
  3. ReDim filearray(WScript.Arguments.Count - 1)
  4. For i = 0 To WScript.Arguments.Count - 1
  5. filearray(i) = CreateObject("Scripting.FileSystemObject").GetFileName(WScript.Arguments(i)) & ">>tem"
  6. Next
  7. filearrays=join(filearray, "&echo ")
  8. CreateObject("WScript.shell").Run "cmd /C echo " & filearrays & "&clip<tem&del tem", 0
复制代码

TOP

本帖最后由 lforl 于 2024-10-23 21:35 编辑

谢谢楼上热心回复。
关于处理多个选中的文件,获取他们路径文件名,@77七 大佬帮过我,实现的比较完美。
比如这贴:

不过我还没学会如何把for循环里得到的变量,累加起来,最后传给剪贴板。
期待大佬路过出手指点...

TOP

本帖最后由 aloha20200628 于 2024-10-25 18:16 编辑

回复 1# lforl

一楼的注册表代码沿用了系统为资源管理器开启 ‘复制路径’ 右键菜单的通道,实测不能直接 ‘套壳’ 这段批处代码,但通过资源管理器的 ‘发送到’ 右键菜单机制确实可以挂载类似的批处代码,从而实现楼主的要求,以下是一个最简方法示例》
一。创建一个批处理脚本(代码如下)假设存为 sendTo.bat
二。复制 sendTo.bat 到 "C:\Users\本机用户名\AppData\Roaming\Microsoft\Windows\SendTo" 系统目录中(可在资源管理器地址栏输入 shell:sendto 开启该目录),其后会在资源管理器 '发送到' 右键菜单中出现名为 sendTo.bat 的选项,当单选或多选文件或目录后,点击此右键菜单选项即可完成被选结果 '无双引号包裹' 传至剪贴板的操作
  1. @echo off &(for %%i in (%*) do @echo,%%~i)|clip.exe&exit/b
复制代码
但这个用法至少有两点限制》
一。被选文件或目录的字符总量不能超过8K,即受限于系统命令行参数的字符总量限制
二。批处脚本被调用过程会导致闪屏,这是因开关cmd窗口所致

改用 vbs 或 jscript 代码替换批处脚本是一个没有闪屏和突破选择集字符量8K限制的解决方案,以下代码是一个jscript版本,假设存为 sendTo.js,直接复制到上述系统目录中,其后会在资源管理器 '发送到' 右键菜单中出现名为 sendTo.js 的选项,当单选或多选文件或目录后,点击此右键菜单选项即可完成被选结果 '无双引号包裹' 传至剪贴板的操作
  1. v=WSH.arguments, ws=WSH.createObject('WScript.shell');
  2. for (s='',n=0,l=v.length; n<l; n++) s+=v(n).replace(/\"/g,'')+'\r\n';
  3. fso=WSH.createObject('Scripting.FileSystemObject');
  4. tF=ws.expandEnvironmentStrings('%temp%')+'\\_.clipT';
  5. fp=fso.OpenTextFile(tF,2,true), fp.write(s.slice(0,-2)), fp.close();
  6. ws.run('cmd.exe /c clip.exe<'+tF+'&&del/q '+tF, 0, false), WSH.quit();
复制代码

TOP

回复 7# aloha20200628

谢谢大佬,.js 方案的确也是个不错的办法。发送到js之前的确没想过。

不过,我感觉原生cmd对这个问题应该有解,搜索过全网,感觉多数方案都停留在shift右键带引号那个方案。
纯粹一个reg右键解决问题,简洁。
我再研究研究...

TOP

回复 8# lforl

   注册表右键菜单定义中的批处代码可以识别 %1, %2, ..., %L 这类命令行参数,但不识别 %*,其中每个 %n 参数变量指向被选择的单个文件或目录,系统会为每个选择项自动开启一个cmd窗口进程,分别运行右键菜单定义中的同一段代码,因此当选择集(文件或目录项)较多时可能会导致系统卡死,当选择项未被双引号包裹但其中包含了&^等特殊字符时也会被系统拦截退出...
   楼主引用的 http://www.bathome.net/viewthread.php?tid=69150 二楼代码,在具体运行时也会因应文件选择集数量相应开启多个cmd窗口进程(可能因运行速度快而一闪而过未被察觉),可用如下代码(由二楼代码裁剪而成)予以验证...
  1. Windows Registry Editor Version 5.00
  2. [HKEY_CLASSES_ROOT\SystemFileAssociations\.pdf\Shell\rename1]
  3. @="自定义重命名"
  4. [HKEY_CLASSES_ROOT\SystemFileAssociations\.pdf\Shell\rename1\Command]
  5. @="cmd /v:on /c (for %%i in (\"%1\") do echo,%%~ni)&pause"
复制代码
系统内置的 ‘复制路径’ 功能可以一次性传递全部选择集至剪贴板, 系统内置的 ‘sendTo(发送到)’ 右键菜单机制(7楼示例代码)亦可一次性传递全部选择集至剪贴板,也许微软对此就提供了 ‘内径’ 而已...

TOP

  1. @="cmd /c mshta VBScript:Execute(\"For Each win In CreateObject(\"\"Shell.Application\"\").Windows:If win.Document.SelectedItems.Count>1 Then:For Each selected In win.Document.SelectedItems:f=selected.Name&vbCrLf&f:Next:Else:f=win.Document.SelectedItems.item(0).Path:End If:CreateObject(\"\"Scripting.Filesystemobject\"\").GetStandardStream(1).Write(f):Next\")(close)|clip"
复制代码

TOP

除了注册表不支持%*,无法同时传递多个变量,
还有一个问题,就是for %%i in (%*)j语句中,文件的命名不能带英文反括号,否则语句失效。
解决的办法有,但不完美,就是文件命名不能带英文反括号,或者命名必须同时有空格和英文反括号。

TOP

返回列表