标题: [问题求助] PowerShell怎样复制 快捷方式 链接的源文件到剪贴板? [打印本页]
作者: g495326 时间: 2022-10-14 18:52 标题: PowerShell怎样复制 快捷方式 链接的源文件到剪贴板?
复制 快捷方式 链接的源文件或目录到剪贴板,以便于可以在别的文件夹中粘贴。
格式:脚本.ps1 任意多个快捷方式...
作者: went 时间: 2022-10-14 20:59
test.ps1- $shell = New-Object -ComObject 'WScript.Shell' ; $arr = @()
- $args | foreach { $arr += $shell.CreateShortcut($_).TargetPath }
- $s = $arr -join "`r`n" ; Write-Host $s
- Set-Clipboard -Value $s
复制代码
powershell test.ps1 "C:\Users\Public\Desktop\腾讯QQ.lnk" "F:\Desktop\微信.lnk"
作者: g495326 时间: 2022-10-14 23:20
回复 2# went
好像不行,粘贴按钮仍然是灰色的
作者: went 时间: 2022-10-15 12:14
- [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
- $shell = New-Object -ComObject 'WScript.Shell'
- $paths = New-Object 'System.Collections.Specialized.StringCollection'
- $args | foreach {
- $file_str = $shell.CreateShortcut($_).TargetPath
- Write-Host $file_str
- [void]$paths.Add($file_str)
- }
- [System.Windows.Forms.Clipboard]::SetFileDropList($paths)
复制代码
作者: g495326 时间: 2022-10-15 15:02
回复 4# went
多谢,如果能把该脚本加入到 快捷方式 的右键菜单,就更方便使用了
作者: went 时间: 2022-10-15 17:35
test.bat 管理员运行- @echo off & cd /d "%~dp0"
- set "ps1=F:\Desktop\test.ps1"
- reg add "HKCR\lnkfile\shell\复制源到剪贴板\command" /ve /d "powershell \"%ps1%\" %%1" /f
- pause&exit
复制代码
F:\Desktop\test.ps1
只支持单个文件右键
作者: g495326 时间: 2022-10-15 19:03
回复 6# went
多文件选择,我使用 发送到 菜单 -> 脚本.ps1解决了
但框择多个文件时会夹杂着非lnk文件,这时脚本会报错。
能改成对于传递进来的非lnk文件正常复制吗?即:脚本.ps1 1.lnk 2.txt 3.lnk
复制1和3的源文件和2.txt到剪贴板
作者: went 时间: 2022-10-15 23:13
回复 7# g495326 - [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
- $shell = New-Object -ComObject 'WScript.Shell'
- $paths = New-Object 'System.Collections.Specialized.StringCollection'
- $args | foreach {
- if($_.EndsWith('.lnk')){
- $file_str = $shell.CreateShortcut($_).TargetPath
- } else {
- $file_str = $_
- }
- Write-Host $file_str
- [void]$paths.Add($file_str)
- }
- [System.Windows.Forms.Clipboard]::SetFileDropList($paths)
复制代码
作者: g495326 时间: 2022-10-16 08:52
回复 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
作者: went 时间: 2022-10-16 19:23
- using namespace 'Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes';cls
- [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
- Add-Type -Name 'WinApi' -MemberDefinition '[DllImport("user32.dll")]public static extern short GetKeyState(uint VK);'
- $shell = New-Object -ComObject 'WScript.Shell'
- $paths = New-Object 'System.Collections.Specialized.StringCollection'
- if([WinApi]::GetKeyState(16) -band 0x8000){ $paths = [System.Windows.Forms.Clipboard]::GetFileDropList() }
- $args | foreach { [void]$paths.Add($shell.CreateShortcut($_).TargetPath) }
- $paths = $paths | Select-Object -Unique | Where-Object {[System.IO.File]::Exists($_)}
- [System.Windows.Forms.Clipboard]::SetFileDropList($paths)
- $paths
复制代码
回复 9# g495326
作者: g495326 时间: 2022-10-16 22:31
本帖最后由 g495326 于 2022-10-16 22:34 编辑
回复 10# went
多谢。但还有些问题
链接的源文件位置变化,运行报错
链接的源文件是目录时,运行报错
对于非lnk文件,运行报错
作者: went 时间: 2022-10-17 20:23
本帖最后由 went 于 2022-10-19 16:04 编辑
- using namespace 'Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes'
- using namespace 'System.Windows.Forms'
- using namespace 'System.Collections.Specialized';cls
- [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
- Add-Type -Name 'WinApi' -MemberDefinition '[DllImport("user32.dll")]public static extern short GetKeyState(uint VK);'
- $shell = New-Object -ComObject 'WScript.Shell'
- $paths = New-Object 'StringCollection'
- $arr_err = New-Object 'System.Collections.ArrayList'
- if([WinApi]::GetKeyState(16) -band 0x8000){ write-host 'shift';$paths = [Clipboard]::GetFileDropList() }
- $args | foreach { [void]$paths.Add($_) }
- $paths = &{
- $paths | Select-Object -Unique | foreach {
- #目录
- if([System.IO.Directory]::Exists($_)){ return $_ }
- #文件
- if([System.IO.File]::Exists($_)){
- #lnk文件
- if($_.EndsWith('.lnk')){
- $p = $shell.CreateShortcut($_).TargetPath
- if([System.IO.File]::Exists($p)){ return $p }
- if([System.IO.Directory]::Exists($p)){ return $p }
- [void]$arr_err.Add(('{0} -> {1}' -f $_,$p))
- return $null
- }
- #其它文件
- return $_
- }
- } | Select-Object -Unique
- }
- if($paths.Count -gt 0){
- [Clipboard]::SetFileDropList($paths)
- 'ok'
- $paths
- '-----------'
- }
- if($arr_err.Count -gt 0){
- 'fail'
- $arr_err
- '-----------'
- pause
- }
复制代码
作者: g495326 时间: 2022-10-17 22:10
本帖最后由 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状态
作者: went 时间: 2022-10-18 13:04
源文件报错第28行改为- if($paths.Count -gt 0){ [Clipboard]::SetFileDropList($paths) }
复制代码
检测shift要加载dll耗时,只有多按一点时间 5-8行都是
作者: g495326 时间: 2022-10-18 14:23
回复 14# went
我的意思是,打印出链接失效的快捷方式的本身的路径,比如执行:脚本.ps1 1.lnk,1.lnk的源文件找不到,则打印1.lnk本身的路径并提示按任意键继续
还有1.lnk 链接的源文件位置变化后,执行:脚本.ps1 1.lnk后,仍能找到新的源文件,而不是以找不到源文件处理。(记事本程序可以在处理这种情况,我想脚本也会有办法吧)
论坛回复不及时,方便说下微信吗(可短消息回我)
作者: went 时间: 2022-10-18 20:12
回复 15# g495326
21行 return $null 改为- Write-Host ('未找到源 {0} -> {1}' -f $_,$p);pause
- return $null
复制代码
作者: g495326 时间: 2022-10-19 13:46
回复 16# went
不是每遇到一个找不到源文件,就暂停
而是把这些错误搜集起来,在脚本结束前一起显示
作者: went 时间: 2022-10-19 16:05
回复 17# g495326
12楼改了,你直接复制
作者: g495326 时间: 2022-10-19 23:03
回复 18# went
还是有之前提到的问题,源文件改名或移动位置,脚本无法获取新的位置,导致失败。而记事本可以。
作者: g495326 时间: 2022-10-21 18:53
回复 18# went
在文件对话框中使用,闪退。能解决下吗?谢谢了
作者: went 时间: 2022-10-21 21:50
回复 20# g495326
我win11,用不了发送到菜单
作者: g495326 时间: 2022-10-21 22:09
回复 21# went
win11有发送到菜单啊,真的,帮帮忙吧!
作者: went 时间: 2022-10-21 22:42
win11
作者: g495326 时间: 2022-10-21 23:00
回复 23# went
发送到 不支持文件的,可以创建快捷方式。C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -file <脚本全路径>
作者: went 时间: 2022-10-21 23:23
回复 24# g495326
对话框选择文件我测试是ok的
你在脚本最后添加一行 pause
看看是否有报错
作者: g495326 时间: 2022-10-22 11:59
本帖最后由 g495326 于 2022-10-22 12:01 编辑
回复 25# went
加入pause后仍闪退,我怀疑是ps版本的问题,你版本多少
作者: g495326 时间: 2022-10-24 11:59
回复 25# went
对于源文件改名的情况,我找到了两篇资料,你看一下
ShellLinkObject.Resolve 方法 (Shldisp.h) - Win32 apps | Microsoft Learn
https://learn.microsoft.com/zh-c ... redirectedfrom=MSDN
IShellLinkA::Resolve (shobjidl_core.h) - Win32 apps | Microsoft Learn
https://learn.microsoft.com/en-u ... ishelllinka-resolve
作者: went 时间: 2022-10-24 23:23
回复 27# g495326
目标都变了不可能还能定位到
上面的意思是lnk目标改变,还是能解析到lnk里原先保存的源目标,而不至于报错
作者: g495326 时间: 2022-10-25 22:41
回复 28# went
对于源文件改名的问题,我找到了一个命令行程序,与脚本放在同一目录。
能修改一下脚本,通过调用该程序获取源文件吗?获取到的路径仍需要判断存不存在。
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |