在批处理脚本中可以“Windows资源管理器样式”复制&粘贴使用?
例如
copy example.exe
some arbitrary commands
paste example.exe
更新:复制到剪贴板可以通过cmd完成,但
答案 0 :(得分:0)
您可以使用powershell
阅读剪贴板内容@echo off
set "myText=This is my text"
rem copy variable content to clipboard
set /p"=%myText%"<nul|clip
rem get clipboard content into variable
set "psCmd=powershell -Command "add-type -an system.windows.forms; [System.Windows.Forms.Clipboard]::GetText()""
for /F "usebackq delims=" %%# in (`%psCmd%`) do set "clipContent=%%#"
echo %clipContent%
exit/B
答案 1 :(得分:0)
使用PowerShell可以将文件和文件夹列表复制到[Windows.Forms.Clipboard]::SetFileDropList($collection)
,并使用[Windows.Forms.Clipboard]::GetFileDropList()
粘贴以及标准文件复制或流读取器/写入器方法。这些方法真正使用剪贴板,因此通过资源管理器复制的文件可以从控制台粘贴,反之亦然。作为奖励,使用脚本来操作剪贴板FileDropList允许您从多个位置将文件追加到列表中 - 这是GUI界面不允许的。
PowerShell脚本可以创建为Batch + PowerShell polyglots。所以问题的答案是,是的,可以用.bat脚本做你想做的事。
<强> fcopy.bat:强>
用法:
fcopy.bat [switch] filemask [filemask [filemask [etc.]]]
fcopy.bat /?
代码:
<# : fcopy.bat -- https://stackoverflow.com/a/43924711/1683264
@echo off & setlocal
if "%~1"=="" ( goto usage ) else if "%~1"=="/?" goto usage
set args=%*
rem // kludge for PowerShell's reluctance to start in a dir containing []
set "wd=%CD%"
powershell -STA -noprofile "iex (${%~f0} | out-string)"
goto :EOF
:usage
echo Usage: %~nx0 [switch] filemask [filemask [filemask [...]]]
echo example: %~nx0 *.jpg *.gif *.bmp
echo;
echo Switches:
echo /L list current contents of clipboard file droplist
echo /C clear clipboard
echo /X cut files (Without this switch, the action is copy.)
echo /A append files to existing clipboard file droplist
goto :EOF
: end batch / begin powershell #>
$col = new-object Collections.Specialized.StringCollection
Add-Type -AssemblyName System.Windows.Forms
$files = $()
$switches = @{}
# work around PowerShell's inability to start in a directory containing brackets
cd -PSPath $env:wd
# cmd calling PowerShell calling cmd. Awesome. Tokenization of arguments and
# expansion of wildcards is profoundly simpler when using a cmd.exe for loop.
$argv = @(
cmd /c "for %I in ($env:args) do @echo(%~I"
cmd /c "for /D %I in ($env:args) do @echo(%~I"
) -replace "([\[\]])", "```$1"
$argv | ?{$_.length -gt 3 -and (test-path $_)} | %{ $files += ,(gi -force $_).FullName }
$argv | ?{$_ -match "^[/-]\w\W*$"} | %{
switch -wildcard ($_) {
"?a" { $switches["append"] = $true; break }
"?c" { $switches["clear"] = $true; break }
"?l" { $switches["list"] = $true; break }
"?x" { $switches["cut"] = $true; break }
default { "Unrecognized option: $_"; exit 1 }
}
}
if ($switches["clear"]) {
[Windows.Forms.Clipboard]::Clear()
"<empty>"
exit
}
if ($switches["list"] -and [Windows.Forms.Clipboard]::ContainsFileDropList()) {
$cut = [windows.forms.clipboard]::GetData("Preferred DropEffect").ReadByte() -eq 2
[Windows.Forms.Clipboard]::GetFileDropList() | %{
if ($cut) { write-host -f DarkGray $_ } else { $_ }
}
}
if ($files.Length) {
$data = new-object Windows.Forms.DataObject
if ($switches["cut"]) { $action = 2 } else { $action = 5 }
$effect = [byte[]]($action, 0, 0, 0)
$drop = new-object IO.MemoryStream
$drop.Write($effect, 0, $effect.Length)
if ($switches["append"] -and [Windows.Forms.Clipboard]::ContainsFileDropList()) {
[Windows.Forms.Clipboard]::GetFileDropList() | %{ $files += ,$_ }
}
$color = ("DarkGray","Gray")[!$switches["cut"]]
$files | select -uniq | %{ write-host -f $color $col[$col.Add($_)] }
$data.SetFileDropList($col)
$data.SetData("Preferred DropEffect", $drop)
[Windows.Forms.Clipboard]::Clear()
[Windows.Forms.Clipboard]::SetDataObject($data, $true)
$drop.Close()
}
<强> paste.bat:强>
用法:
paste.bat [destination]
代码:
<# : paste.bat -- https://stackoverflow.com/a/43924711/1683264
@echo off & setlocal
set args=%*
set "wd=%CD%"
powershell -STA -noprofile "iex (${%~f0} | out-string)"
goto :EOF
: end batch / begin powershell #>
$files = @()
[uint64]$totalbytes = 0
# kludge for PowerShell's reluctance to start in a path containing []
cd -PSPath $env:wd
Add-Type -AssemblyName System.Windows.Forms
if (-not [Windows.Forms.Clipboard]::ContainsFileDropList()) { exit }
# cut = 2; copy = 5
$de = [Windows.Forms.Clipboard]::GetData("Preferred DropEffect")
if ($de) {$cut = $de.ReadByte() -eq 2} else {$cut = $false}
function newdir ([string]$dir) {
[void](md $dir)
write-host -nonewline "* " -f cyan
write-host -nonewline "Created "
write-host $dir -f white
}
if ($env:args) {
[string[]]$argv = cmd /c "for %I in ($env:args) do @echo(%~I"
if (test-path -PSPath $argv[0] -type Container) {
try { cd -PSPath $argv[0] }
catch { write-host -f red "* Unable to change directory to $($argv[0])"; exit 1 }
} else {
try { newdir $argv[0] }
catch { write-host -f red "* Unable to create $($argv[0])"; exit 1 }
cd -PSPath $argv[0]
}
}
Add-Type @'
using System;
using System.Runtime.InteropServices;
namespace shlwapi {
public static class dll {
[DllImport("shlwapi.dll")]
public static extern long StrFormatByteSize64(ulong fileSize,
System.Text.StringBuilder buffer, int bufferSize);
}
}
'@
function num2size ($num) {
$sb = new-object Text.StringBuilder 16
[void][shlwapi.dll]::StrFormatByteSize64($num, $sb, $sb.Capacity)
$sb.ToString()
}
# returns the true drive letter, even if the supplied path contains a junction / symlink
function Resolve-Drive ([string]$path) {
while ($path.Length -gt 3) {
$dir = gi -force -PSPath $path
if ($dir.Attributes -band [IO.FileAttributes]::ReparsePoint) {
$path = $dir.Target
if ($path.Length -eq 3) { break }
}
$path = (resolve-path "$path\..").Path
}
$path
}
function Move-File ([string]$from, [string]$to) {
$srcdrive = Resolve-Drive $from
$destdrive = Resolve-Drive (Convert-Path .)
if ($srcdrive -eq $destdrive) {
Move-Item $from $to -force
write-host -n -f green "* "
write-host -n -f white (gi -force -PSPath $to).Name
write-host " moved."
} else {
Copy-File $from $to "Moving"
gi -force -PSPath $from | Remove-Item -force
}
}
# based on https://stackoverflow.com/a/13658936/1683264
function Copy-File {
param([string]$from, [string]$to, [string]$action = "Copying")
if (test-path -type leaf -PSPath $to) { gi -force -PSPath $to | Remove-Item -force }
$ffile = [io.file]::OpenRead($from)
$tofile = [io.file]::OpenWrite($to)
$fileobj = gi -force -PSPath $tofile.Name
$filesize = $ffile.length
$size = num2size $filesize
try {
if ($filesize -ge 16*1024*1024) {
$buffersize = 16*1024*1024
} else { $buffersize = $filesize }
Write-Progress `
-Id 1 `
-Activity "0% $action $size file" `
-status $fileobj.Name `
-PercentComplete 0
$sw = [System.Diagnostics.Stopwatch]::StartNew();
[byte[]]$buff = new-object byte[] $buffersize
[uint64]$total = [uint64]$count = 0
do {
$count = $ffile.Read($buff, 0, $buff.Length)
$tofile.Write($buff, 0, $count)
$total += $count
if (!$ffile.Length) {
$pctcomp = 0
} else {
[int]$pctcomp = ([int]($total/$ffile.Length* 100))
}
[int]$secselapsed = [int]($sw.elapsedmilliseconds.ToString())/1000
if ( $secselapsed -ne 0 ) {
[single]$xferrate = (($total/$secselapsed)/1mb)
} else {
[single]$xferrate = 0.0
}
if ($total % 1mb -eq 0) {
if ($pctcomp -gt 0) {
[int]$secsleft = ((($secselapsed/$pctcomp)* 100)-$secselapsed)
} else {
[int]$secsleft = 0
}
Write-Progress `
-Id 1 `
-Activity ($pctcomp.ToString() + "% $action $size file @ " + `
"{0:n2}" -f $xferrate + " MB/s") `
-status $fileobj.Name `
-PercentComplete $pctcomp `
-SecondsRemaining $secsleft
}
} while ($count -gt 0)
$sw.Stop()
$sw.Reset()
}
finally {
$tofile.Close()
$ffile.Close()
$ffile = gi -force -PSPath $from
$fileobj.CreationTime = $ffile.CreationTime
$fileobj.LastWriteTime = $ffile.LastWriteTime
if ( $secselapsed -ne 0 ) {
[string]$xferrate = "{0:n2} MB" -f (($total/$secselapsed)/1mb)
} else {
[string]$xferrate = num2size $fileobj.Length
}
write-host -nonewline "* " -f green
write-host -nonewline $fileobj.Name -f white
write-host (" written in $secselapsed second{0} at $xferrate/s." -f (`
"s" * ($secselapsed -ne 1)));
}
}
[Windows.Forms.Clipboard]::GetFileDropList() | %{
if (test-path -PSPath $_ -Type Leaf) {
$add = @($_.Trim(), ((Convert-Path .) + "\" + (gi -force -PSPath $_).Name))
if ($files -notcontains $add) {
$totalbytes += (gi -force -PSPath $_).Length
$files += ,$add
}
} else {
if (test-path -PSPath $_ -Type Container) {
$src = (Convert-Path -PSPath $_).Trim()
$dest = (Convert-Path .) + "\" + (gi -force -PSPath $src).Name
if (!(test-path -PSPath $dest)) { newdir $dest }
gci -PSPath $src -recurse -force | %{
$dest1 = $dest + $_.FullName.Replace($src, '')
if ((test-path -PSPath $_.FullName -Type Container) -and !(test-path -PSPath $dest1)) {
newdir $dest1
}
if (test-path -PSPath $_.FullName -Type Leaf) {
$add = @($_.FullName.Trim(), $dest1)
if ($files -notcontains $add) {
$totalbytes += $_.Length
$files += ,$add
}
}
}
}
}
}
[string]$totalsize = num2size $totalbytes
$destdrive = resolve-drive (Convert-Path .)
$capacity = (Get-PSDrive ($destdrive -split ':')[0]).Free
if ($totalbytes -gt $capacity) {
write-host -f red "* Not enough space on $destdrive"
exit 1
}
for ($i=0; $i -lt $files.length; $i++) {
Write-Progress `
-Activity "Pasting to $(Convert-Path .)" `
-Status ("Total Progress {0}/{1} files {2} total" `
-f ($i + 1), $files.length, $totalsize) `
-PercentComplete ($i / $files.length * 100)
if ($cut) {
Move-File $files[$i][0] $files[$i][1]
} else {
Copy-File $files[$i][0] $files[$i][1]
}
}
if ($cut) {
[Windows.Forms.Clipboard]::GetFileDropList() | %{
if (test-path -PSPath $_ -type Container) {
gi -force -PSPath $_ | Remove-Item -force -recurse
}
}
[Windows.Forms.Clipboard]::Clear()
}