Страница 2 из 6
Добавлено: Ср янв 24, 2018 15:50
Yura48745
Код: Выделить всё
'===================================================
' Копирование файлов\папок (в т.ч. из ярлыков)
'
' Параметры:
' {файл-список} {целевая папка}
'
' Пример параметров при вызове из TC:
' %L "%T"
'===================================================
Sub xCopy (Path, TargetPath)
Dim lnkName, xFolder, colFiles, objFile, colFolders, objFolder, res
if Canceled then Exit Sub
If LCase(FSO.GetExtensionName(Path)) = "lnk" Then
lnkName = Replace(FSO.GetFileName(Path), ".lnk", "")
Path = WSH.CreateShortcut(Path).TargetPath
If FSO.FileExists(Path) then lnkName = lnkName & "." & FSO.GetExtensionName(Path)
End If
If Right(Path, 1) = "\" Then Path = Left(Path, Len(Path) - 1)
If FSO.FileExists(Path) Then
if lnkName = "" then lnkName = FSO.GetFile(Path).Name
If FSO.FileExists(TargetPath & lnkName) and not ReplaceAll Then
res = msgbox ("File " & FSO.GetFile(Path).Name & " already exists", vbYesNoCancel, "Replase all")
Select Case res
Case 6 ' Yes
ReplaceAll = true
FSO.CopyFile Path, TargetPath & lnkName
Case 2 ' Cancel
Canceled = true
Exit Sub
End Select
else
FSO.CopyFile Path, TargetPath & lnkName
End If
End If
If FSO.FolderExists(Path) Then
Set xFolder = FSO.GetFolder(Path)
Set colFiles = xFolder.Files
Set colFolders = xFolder.subFolders
if lnkName = "" then lnkName = FSO.GetFolder(Path).Name & "\"
if Not FSO.FolderExists(TargetPath & lnkName) then FSO.CreateFolder(TargetPath & lnkName)
For Each objFolder in colFolders
xCopy objFolder, TargetPath & lnkName & "\"
Next
For Each objFile in colFiles
xCopy objFile, TargetPath & lnkName & "\"
Next
Set colFolders = Nothing
Set colFiles = Nothing
Set xFolder = Nothing
End If
End Sub
Dim WSH, FSO, FF, ReplaceAll, Canceled
if WScript.Arguments.count < 2 then WScript.Quit 1
Set FSO = CreateObject("Scripting.FileSystemObject")
Set WSH = CreateObject("WScript.Shell")
Set FF = FSO.OpenTextFile(WScript.Arguments(0), 1)
ReplaceAll = false
Canceled = false
Do While Not FF.AtEndOfStream
xCopy FF.ReadLine, WScript.Arguments(1)
Loop
FF.Close
Set FF = Nothing
Set WSH = Nothing
Set FSO = Nothing
WScript.Quit 0
Добавлено спустя 17 секунд:
Добавлено: Ср янв 24, 2018 21:29
Lisabon
Было бы хорошо, ещё добавить поддержку юникод.
Добавлено: Чт янв 25, 2018 09:37
Flasher
Lisabon
Не проблема. Но не лучше в контексте какого-то из скриптов со счётиком? В т. ч. нужно определиться, оставлять ли имена папок прежними при наличии одноимённых.
Что касаемо рекурсии, то я бы копировал папки как есть (с .lnk), а уже после производил бы замену в получателях.
Добавлено: Чт янв 25, 2018 11:37
Lisabon
Flasher
я бы копировал папки как есть (с .lnk), а уже после производил бы замену в получателях.
Можно и так.
со счётиком
Можно ещё добавить дополнительно параметр. Если надо, со счётчиком, то добавляем параметр. Если не надо, со счётчиком, то не добавляем параметр и перезаписываются файлы.
Было бы неплохо, если возможно, добавить индикацию процесса копирования или просто показать диалог при копировании, мол, идёт копирование ожидайте. Это будет полезно, когда копируется большой файл или папка.
Добавлено: Чт янв 25, 2018 12:32
Flasher
Lisabon
Опцию перезаписи/счётчика сделать можно. Но я писал о папках, а не файлах. Т.е. имена папок при совпадении трогать или как?
Lisabon писал(а):Было бы неплохо, если возможно, добавить индикацию процесса копирования или просто показать диалог при копировании, мол, идёт копирование ожидайте.
ОК. Можно сделать прогресс без lnk, а потом всплыв. окошко.
Добавлено: Чт янв 25, 2018 13:11
Lisabon
Flasher
имена папок при совпадении трогать или как?
Если со счётчиком, то трогать имена, если без счётчика, то не трогать имена.
Добавлено: Чт янв 25, 2018 13:47
Flasher
Lisabon
В ТС по умолчанию структура папок сохраняется, а заданное автопереименование работает только в отношении файлов. Т. е. получается, что вместо переименования одноимённых файлов будут переименованы только корневые папки. Это разве хорошо?
И если трогать имена папок, то системный прогресс (
напомню скрипт) не получится. Придётся отдельный рисовать.
Добавлено: Чт янв 25, 2018 14:40
Lisabon
Flasher
Сделай, как посчитаешь лучше, правильнее...
Добавлено: Чт янв 25, 2018 23:39
Flasher
Lisabon
Ошибся насчёт автопереименования файлов. Смотри, в общем:
Код: Выделить всё
'•••••••••••••••••••••••• VBS ••••••••••••••••••••••••
' Копирование/перемещение выбранного по заданному пути
' с последующей заменой lnk-ярлыков на целевые объекты
' Условие: путь запуска — пустой
' Примечание: в пути достаточно правильной буквы диска
'
' Параметры: %WF "<путь назначения>" <copy/move>
' Ключ системного автопереименования объектов: /r
' Примеры: %WF "%PMy Folder" copy /r
' %WF D:\New\New2\New3\New4\New5 move
'•••••••••••••••••••••••••••••••• Автор: Flasher © •••
Option Explicit : Dim A, FSO, REx, Rgx, T, Ren,_
D, Dic, Col, ShA, oFolder, oList, List, Folders,_
N, Items, F, Nm, Targ, Lnk, i, FPath, FlEx, FdEx
Set A = WSH.Arguments : If A.Count = 0 Then WSH.Quit
Set FSO = CreateObject("Scripting.FileSystemObject")
Set REx = New RegExp : REx.Pattern = "([.+[\(){$^])"
Set Rgx = New RegExp : Rgx.IgnoreCase = True
T = Timer: If A.Named.Exists("r") Then Ren = 8
REx.Global = True : D = FSO.GetDriveName(A(1))
Set Dic = CreateObject("Scripting.Dictionary")
Set Col = CreateObject("Scripting.Dictionary")
Set ShA = CreateObject("Shell.Application")
ShA.NameSpace(D).NewFolder Mid(A(1), Len(D) + 2)
Set oFolder = ShA.NameSpace(FSO.GetAbsolutePathName(""))
List = FSO.OpenTextFile(A(0),,,-1).ReadAll
oList = Split(List, vbNewLine)
For Each N in Filter(oList, ";")
Nm = N
If StrComp(FSO.GetExtensionName(N), "lnk", 1) _
= 0 Then N = oFolder.ParseName(N).GetLink.Target
Set Items = oFolder.Items
Items.Filter 78064, Replace(N, ";", "?")
Rgx.Pattern = "(^|\n)" & REx.Replace(N, "\$1") & "(\r|$)"
For Each F in Items
If Not F.IsLink Then N = "" Else N = F.GetLink.Path
F = FSO.GetFileName(F.Path)
If InStr(F, ";") Then Dic.Add F, N : Exit For
Next : List = Rgx.Replace(List, "$1")
Next
Rgx.Pattern = "\r\n$" : List = Rgx.Replace(List, "")
Folders = Left(List, InStrRev(List, "\"))
For Each N in Filter(oList, ".lnk", 1, 1)
If InStr(N, ";") = 0 Then
With oFolder.ParseName(N)
If .IsLink Then _
Col.Add N, .GetLink.Path : Rgx.Pattern = "(^|\n)" &_
REx.Replace(FSO.GetBaseName(N),"\$1") & "\.lnk(\r|$)":_
List = Rgx.Replace(List, "$1" & .GetLink.Target & "$2")
End With
End If
Next : Set Items = oFolder.Items
Rgx.Pattern = "(^|\n)" & FSO.GetFileName(A(1)) & "\\(\r|$)"
List = Rgx.Replace(List, "$1") : If List = "" Then WSH.Quit
Set Targ = ShA.NameSpace(A(1)) : Items.Filter 78064,_
Replace(Replace(List, "\", ""), vbCrLf, ";")
Execute "Targ." & A(2) & "Here Items, 4112 + Ren"
For Each D in Array(Dic, Col)
If D.Count Then
For Each F in D
FPath = D(F) : FlEx = FSO.FileExists(FPath)
FdEx = FSO.FolderExists(FPath)
If FlEx Or FdEx Then
If LCase(A(2)) = "move" Then _
If FlEx Then FSO.DeleteFile F, 1 Else FSO.DeleteFolder F, 1
Targ.CopyHere FPath, 4112 + Ren
End If
Next
End If : Set D = Nothing : i = 1
Next
For Each F in Split(Folders, vbCrLf) : FFolder FSO.BuildPath(A(1), F) : Next
T = Timer - T
If T > 3 Then
Dim Sec, Title : If T < 10 Then Sec = 2 Else If T < 30 Then Sec = 4
Title = "Копирование": If LCase(A(2)) = "move" Then Title = "Перемещение"
CreateObject("WScript.Shell").Popup "Выполнено!", Sec, " " & Title, 4160
End If
Sub FFolder(Folder)
Dim oFold, File, Fold
Set oFold = ShA.NameSpace(Folder)
Set Items = oFold.Items : Items.Filter 78032, "*"
For Each File in Items
If File.IsLink And LCase(FSO.GetExtensionName(File.Path)) <> "url" Then _
oFold.CopyHere File.GetLink.Path, 4112 + Ren : FSO.DeleteFile File.Path, 1
Next : Items.Filter 78000, "*"
For Each Fold in FSO.GetFolder(Folder).SubFolders
If FSO.FolderExists(Fold) Then FFolder Fold.Path
Next
End Sub
Добавлено: Пт янв 26, 2018 00:51
Lisabon
Flasher
Погонял немного... Нашёл пару багов.
Кнопка вот такая:
Код: Выделить всё
TOTALCMD#BAR#DATA
C:\ReadMe.vbs
%WF "%T" copy
C:\Windows\System32\WScript.exe,2
ReadMe
-1
Total Commander 9.12 32-bit, Windows 8.1 64-bit
1. При копировании с ярлыка файла/папки, так и не с ярлыка, а просто файл или папку, размер которых превышает 200 МБ , после операции копирования вылазит сообщение с ошибкой:
Код: Выделить всё
Сценарий: C:\ReadMe.vbs
Строка: 0
Символ: 1
Ошибка: Недопустимый вызов или аргумент процедуры
Код: 800A0005
Источник: Ошибка выполнения Microsoft VBScript
Сами файл/папка копируются в полном объёме.
2. Если ярлыки имеют имена:
Код: Выделить всё
1992.10 - Out Of Space (Elektra 2-66346).LNK
1992.11 - Out Of Space (XLS 35CD).LNK
2009.11 - Invaders Must Die (HOSPCDS06).LNK
2012.09.04 - 7th Mini Album - Mirage.LNK
то копирование с ярлыка, не происходит. Если произвести копирование папки с выше указанными именами, то копируются папки без проблем.
Добавлено: Пт янв 26, 2018 01:17
Flasher
Lisabon
1. Вряд ли это с размером связано. Я тестировал с большими файлами без бага, так что-то другое. Позже буду смотреть.
2. Поправил 31 строку.
Добавлено: Пт янв 26, 2018 10:57
Lisabon
Flasher
Ещё есть пожелание, если возможно...
Допустим есть кнопка:
Код: Выделить всё
TOTALCMD#BAR#DATA
C:\ReadMe.vbs
%WF "%T" copy /r
C:\Windows\System32\WScript.exe,2
ReadMe
-1
Есть ярлык на файл/папку. Путь источника равен получателю. При копировании с ярлыка, после копирования файла/папки, переименовывается ярлык, тобишь добавляется к имени ярлыка
. Так вот, можно ли ярлык не переименовывать ибо смысла нет никакого.
Ещё нашёл баг с использованием имени ярлыка:
01 mka dvd-audio araw;24bit,96000hz,4608kbs.lnk
При копировании с ярлыка, выдаёт ошибку:
Код: Выделить всё
Сценарий: C:\ReadMe.vbs
Строка: 33
Символ: 5
Ошибка: Требуется объект
Код: 800A01A8
Источник: Ошибка выполнения Microsoft VBScript
А при попытке копирования файла с именем:
Код: Выделить всё
01 mka dvd-audio araw;24bit,96000hz,4608kbs.mka
ничего не происходит.
Добавлено: Пт янв 26, 2018 12:46
Flasher
Lisabon писал(а):Так вот, можно ли ярлык не переименовывать ибо смысла нет никакого.
А зачем вообще пытаться копировать в ту же папку, если нет смысла? Тогда нужно вообще запрет на копирование при совпадении путей делать.
Lisabon писал(а):Ещё нашёл баг с использованием имени ярлыка:
Быстро же ты на эту ситуацию вышел. Тут дело в ";". Увы, но мелкомягкие выбрали разрешённый в именах делитель для масок. Что с них взять? Я могу заменять на ? и проверять, чтобы был только один такой файл в папке, а в случае нескольких отсяенные будут скопированны вне общей группы (без прогресса). Не сильно комильфо, но всё же.

Добавлено: Пт янв 26, 2018 15:15
Lisabon
Flasher
А зачем вообще пытаться копировать в ту же папку, если нет смысла?
Не очень понял... В общем, есть ярлык, он в по одному пути, файл на который ссылается ярлык, не находятся рядом.
Я выбираю ярлык, с которого надо скопировать файл. В левой и правой файловой панелях, пути одинаковы и там находится только ярлык:
После обработки, получаем вот такой результат:
Зачем копировать в папку, где находится сам ярлык? Ну, например, для получения копии файла, где находится ярлык.
Тогда нужно вообще запрет на копирование при совпадении путей делать.
Если используется кнопка
Код: Выделить всё
TOTALCMD#BAR#DATA
C:\ReadMe.vbs
%WF "%T" copy /r
C:\Windows\System32\WScript.exe,2
ReadMe
-1
, то зачем делать запрет.
Добавлено: Пт янв 26, 2018 15:50
Flasher
Lisabon писал(а):После обработки, получаем вот такой результат:
А. Т. е. замена не происходит. Так бы и писал. Ладно, поправимо, хотя и через ...
Lisabon писал(а):Ну, например, для получения копии файла, где находится ярлык.
А смысл в копиях в том же каталоге какой? Это же не
бэкапер или
размножитель. Цель такая не ставилась, вроде.
Lisabon писал(а):, то зачем делать запрет.
Так суть автопереименования не в создании дублей, а в предотвращении перезаписи и необходимости содержать потенциально разные по содержимому файлы.