找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 49686|回复: 28

[问题求助] PowerShell怎样复制 快捷方式 链接的源文件到剪贴板?

[复制链接]
发表于 2022-10-14 18:52:40 | 显示全部楼层 |阅读模式
复制 快捷方式 链接的源文件或目录到剪贴板,以便于可以在别的文件夹中粘贴。
格式:脚本.ps1 任意多个快捷方式...
发表于 2022-10-14 20:59:19 | 显示全部楼层
test.ps1
  1. $shell = New-Object -ComObject 'WScript.Shell' ; $arr = @()
  2. $args | foreach { $arr += $shell.CreateShortcut($_).TargetPath }
  3. $s = $arr -join "`r`n" ; Write-Host $s
  4. Set-Clipboard -Value $s
复制代码
powershell test.ps1 "C:\Users\Public\Desktop\腾讯QQ.lnk"  "F:\Desktop\微信.lnk"
 楼主| 发表于 2022-10-14 23:20:21 | 显示全部楼层
回复 2# went


    好像不行,粘贴按钮仍然是灰色的
发表于 2022-10-15 12:14:05 | 显示全部楼层
  1. [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
  2. $shell = New-Object -ComObject 'WScript.Shell'
  3. $paths = New-Object 'System.Collections.Specialized.StringCollection'
  4. $args | foreach {
  5.     $file_str = $shell.CreateShortcut($_).TargetPath
  6.     Write-Host $file_str
  7.     [void]$paths.Add($file_str)
  8. }
  9. [System.Windows.Forms.Clipboard]::SetFileDropList($paths)
复制代码

评分

参与人数 1技术 +1 收起 理由
g495326 + 1 乐于助人

查看全部评分

 楼主| 发表于 2022-10-15 15:02:29 | 显示全部楼层
回复 4# went


    多谢,如果能把该脚本加入到 快捷方式 的右键菜单,就更方便使用了
发表于 2022-10-15 17:35:32 | 显示全部楼层
test.bat 管理员运行
  1. @echo off & cd /d "%~dp0"
  2. set "ps1=F:\Desktop\test.ps1"
  3. reg add "HKCR\lnkfile\shell\复制源到剪贴板\command" /ve /d "powershell "%ps1%" %%1" /f
  4. pause&exit
复制代码
F:\Desktop\test.ps1
只支持单个文件右键
 楼主| 发表于 2022-10-15 19:03:00 | 显示全部楼层
回复 6# went


    多文件选择,我使用 发送到 菜单 -> 脚本.ps1解决了
    但框择多个文件时会夹杂着非lnk文件,这时脚本会报错。
    能改成对于传递进来的非lnk文件正常复制吗?即:脚本.ps1 1.lnk 2.txt 3.lnk
    复制1和3的源文件和2.txt到剪贴板
发表于 2022-10-15 23:13:08 | 显示全部楼层
回复 7# g495326
  1. [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
  2. $shell = New-Object -ComObject 'WScript.Shell'
  3. $paths = New-Object 'System.Collections.Specialized.StringCollection'
  4. $args | foreach {
  5.     if($_.EndsWith('.lnk')){
  6.         $file_str = $shell.CreateShortcut($_).TargetPath
  7.     } else {
  8.         $file_str = $_
  9.     }
  10.     Write-Host $file_str
  11.     [void]$paths.Add($file_str)
  12. }
  13. [System.Windows.Forms.Clipboard]::SetFileDropList($paths)
复制代码
 楼主| 发表于 2022-10-16 08:52:38 | 显示全部楼层
回复 8# went


    多谢,但使用过程中,只要一个链接所指向的源文件不存在,复制会失败。因为粘贴时什么都不会发生。
    例如:1.lnk 链接 1.txt,2.lnk 链接 2.txt,3.lnk 链接 3.txt,此时我把1.txt删除。然后执行:脚本.ps1 1.lnk 2.lnk 3.lnk
    然后在另一文件夹中执行粘贴将会失败。此时正常的表现应该是跳过1.txt,仅复制2.txt和3.txt。

    另一个是当链接的源文件移动了位置,脚本获取链接的源文件位置仍是旧位置,也会造成复制的失败
    例如:1.lnk 链接 1.txt(假设为c:\1.txt),然后移动1.txt到新的位置(d:\1.txt)。
    然后执行:脚本.ps1 1.lnk,获取的源文件路径是c:\1.txt,而不是d:\1.txt

    还有一个是,能否在脚本运行时,检测到shift键按下且剪贴板中有文件内容,则把当前要复制的文件内容追加到剪贴板。(在右键菜单执行脚本)
    例如:2.lnk 链接 2.txt,此时先复制1.txt,按下shift键,然后执行:脚本.ps1 2.lnk,此时剪贴板应存在1.txt和2.txt
发表于 2022-10-16 19:23:08 | 显示全部楼层
  1. using namespace 'Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes';cls
  2. [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
  3. Add-Type -Name 'WinApi' -MemberDefinition '[DllImport("user32.dll")]public static extern short GetKeyState(uint VK);'
  4. $shell = New-Object -ComObject 'WScript.Shell'
  5. $paths = New-Object 'System.Collections.Specialized.StringCollection'
  6. if([WinApi]::GetKeyState(16) -band 0x8000){ $paths = [System.Windows.Forms.Clipboard]::GetFileDropList() }
  7. $args | foreach { [void]$paths.Add($shell.CreateShortcut($_).TargetPath) }
  8. $paths = $paths | Select-Object -Unique | Where-Object {[System.IO.File]::Exists($_)}
  9. [System.Windows.Forms.Clipboard]::SetFileDropList($paths)
  10. $paths
复制代码
回复 9# g495326
 楼主| 发表于 2022-10-16 22:31:42 | 显示全部楼层
本帖最后由 g495326 于 2022-10-16 22:34 编辑

回复 10# went


    多谢。但还有些问题
    链接的源文件位置变化,运行报错
    链接的源文件是目录时,运行报错
    对于非lnk文件,运行报错
发表于 2022-10-17 20:23:34 | 显示全部楼层
本帖最后由 went 于 2022-10-19 16:04 编辑
  1. using namespace 'Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes'
  2. using namespace 'System.Windows.Forms'
  3. using namespace 'System.Collections.Specialized';cls
  4. [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
  5. Add-Type -Name 'WinApi' -MemberDefinition '[DllImport("user32.dll")]public static extern short GetKeyState(uint VK);'
  6. $shell = New-Object -ComObject 'WScript.Shell'
  7. $paths = New-Object 'StringCollection'
  8. $arr_err = New-Object 'System.Collections.ArrayList'
  9. if([WinApi]::GetKeyState(16) -band 0x8000){ write-host 'shift';$paths = [Clipboard]::GetFileDropList() }
  10. $args | foreach { [void]$paths.Add($_) }
  11. $paths = &{
  12.         $paths | Select-Object -Unique | foreach {
  13.                 #目录
  14.                 if([System.IO.Directory]::Exists($_)){ return $_ }
  15.                 #文件
  16.                 if([System.IO.File]::Exists($_)){
  17.                         #lnk文件
  18.                         if($_.EndsWith('.lnk')){
  19.                                 $p = $shell.CreateShortcut($_).TargetPath
  20.                                 if([System.IO.File]::Exists($p)){ return $p }
  21.                                 if([System.IO.Directory]::Exists($p)){ return $p }
  22.                 [void]$arr_err.Add(('{0} -> {1}' -f $_,$p))
  23.                                 return $null
  24.                         }
  25.                         #其它文件
  26.                         return $_
  27.                 }
  28.         } | Select-Object -Unique
  29. }
  30. if($paths.Count -gt 0){
  31.         [Clipboard]::SetFileDropList($paths)
  32.         'ok'
  33.         $paths
  34.         '-----------'
  35. }
  36. if($arr_err.Count -gt 0){
  37.         'fail'
  38.         $arr_err
  39.         '-----------'
  40.         pause
  41. }
复制代码
 楼主| 发表于 2022-10-17 22:10:43 | 显示全部楼层
本帖最后由 g495326 于 2022-10-17 22:19 编辑

回复 12# went


    多谢,但还是有之前的问题1,2
    1、快捷方式 链接的 源文件被删除了,运行报错。这种情况应该跳过这些文件。最后打印出这些快捷方式的路径,并阻塞等待任意键之后结束(之所以阻塞,是因为右键菜单中执行,脚本执行完成后会自动关闭PS窗口)
    2、快捷方式 链接的 源文件 位置被改变,运行也会报错。比如 1.lnk 链接 1.txt,1.txt被移动到另一位置。脚本将无法获取1.txt的新位置
    3、shift的检测有时会检测不到,最后发现是脚本检测shift状态时,shift已被释放。能否脚本一运行就首先检测shift状态
发表于 2022-10-18 13:04:47 | 显示全部楼层
源文件报错第28行改为
  1. if($paths.Count -gt 0){ [Clipboard]::SetFileDropList($paths) }
复制代码
检测shift要加载dll耗时,只有多按一点时间 5-8行都是
 楼主| 发表于 2022-10-18 14:23:49 | 显示全部楼层
回复 14# went


    我的意思是,打印出链接失效的快捷方式的本身的路径,比如执行:脚本.ps1 1.lnk,1.lnk的源文件找不到,则打印1.lnk本身的路径并提示按任意键继续
    还有1.lnk 链接的源文件位置变化后,执行:脚本.ps1 1.lnk后,仍能找到新的源文件,而不是以找不到源文件处理。(记事本程序可以在处理这种情况,我想脚本也会有办法吧)
    论坛回复不及时,方便说下微信吗(可短消息回我)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 02:30 , Processed in 0.012706 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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