Я пытаюсь закрепить папку, содержащую вложенные папки и элементы, используя команду оболочки Windows CopyHere
:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb787866(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms723207(v=vs.85).aspx
Обновление: Примечание. Предпочитайте собственное решение - это для распределенного инструмента Excel VBA, поэтому объединение сторонних файлов не является идеальным. И, требуется синхронное сжатие.
Я могу легко добавить папку и ее содержимое в zip:
oShell.Namespace(sZipPath).CopyHere "C:\My Folder"
Итак, мы знаем, что CopyHere может обрабатывать несколько объектов внутри папки в 1 инструкции.
Проблема заключается в том, что вышеприведенная команда помещает содержащую папку в корень zip, а содержимое внутри нее. Но я не хочу содержать папку - просто ее содержимое.
В документе упоминается шаблон (опция 128), но когда я использую подстановочный знак, я получаю сообщение об ошибке:
oShell.Namespace(sZipPath).CopyHere "C:\My Folder\*"
Указанное имя файла недействительно или слишком длинное.
Возможно, есть способ использовать мою первую команду выше, а затем переместить элементы в zip в корень zip?
Было бы приемлемо прокручивать каждый элемент в исходной папке, добавляя по одному к zip файлу. Но, поскольку CopyHere является асинхронным, каждый последующий экземпляр CopyHere завершается с ошибкой, если предыдущее CopyHere не завершено. Ни одна из исправлений не работает для этой проблемы:
-
Сравнение количества элементов в папке source-folder и destination-zip не выполняется, потому что если zip содержит папку, то считается, что только один элемент (элементы, которые он содержит, не учитываются. qaru.site/info/30054/...
-
Время ожидания между каждым элементом работает, но таймер неприемлем: он произвольный. Я не могу заранее предположить размер или время сжатия каждого объекта.
-
Проверка того, что zip заблокирован для доступа, не удалось мне. Если я заблокирую цикл до тех пор, пока файл не будет заблокирован, я все равно получаю ошибку доступа к файлу. qaru.site/info/30055/...
Function FileIsOpen(sPathname As String) As Boolean ' true if file is open
Dim lFileNum As Long
lFileNum = FreeFile
Dim lErr As Long
On Error Resume Next
Open sPathname For Binary Access Read Write Lock Read Write As #lFileNum
lErr = Err
Close #lFileNum
On Error GoTo 0
FileIsOpen = (lErr <> 0)
End Function
Обновление: VBA может синхронно вызывать команды оболочки (вместо создания объекта shell32.shell
в VBA), поэтому, если CopyHere работает в командной строке или PowerShell, это может быть решением. Исследуя...