Чи можете ви скопіювати файл із командного рядка, використовуючи ТІЛЬКІ вбудовані можливості Windows для копіювання файлів?


111

У мене є пакетний файл, який виводить текстовий файл. Я думав, що було б добре, якби я міг також застебнути його.

Це використовуватиметься в неконтрольованому середовищі, тому я не можу робити припущення щодо наявності сторонніх програмних продуктів, таких як 7-Zip і т. Д. Для цього потрібно використовувати вбудовану можливість Windows для копіювання файлів.


1
Ви можете використовувати сценарії Powershell або WSH? це може бути єдиним способом використання вбудованого Windows-zip обробки з командного рядка. інакше, як вказує Моллі, вам потрібен сторонній інструмент.
шарлатаний кіхот

1
ви надсилаєте комусь пакетний файл, і ви не можете надіслати йому якийсь крихітний статично пов'язаний gzip.exe?
акіра

Питання ОП - чудове (незважаючи на дивне звинувачення @quackquixote). Оскільки Windows надає це як один клік у SendTo, у файлі BAT повинна бути команда, яка може бути використана. Тож добре питання, навіть якщо відповідь "Ні", і доводиться (смішно) вдаватися до використання стороннього інструменту, який може бути або не бути рівнозначним.
Джон Кумбс

Це посилання від Tomas має добре написаний сценарій для поштового вмісту папки. Щоб змусити його працювати, просто скопіюйте скрипт у пакетний файл та виконайте його, вказавши папку, яку потрібно блискавити (джерело). Не потрібно згадувати каталог призначення, оскільки він за замовчуванням у сценарії до Desktop ("% USERPROFILE% \ Desktop")
Abhijeet

3
Найпростішим було б у підказці cmd: powershell.exe Compress-Archive file-to-zip.txt zippedfile.zip(вона працює і з папкою)
ThomasGuenet

Відповіді:


85

Ось все рішення пакетного файлу (варіація моєї іншої відповіді), яке зіштовхне файл з назвою c:\ue_english.txtта помістить його C:\someArchive.zip:

set FILETOZIP=c:\ue_english.txt

set TEMPDIR=C:\temp738
rmdir %TEMPDIR%
mkdir %TEMPDIR%
xcopy /s %FILETOZIP% %TEMPDIR%

echo Set objArgs = WScript.Arguments > _zipIt.vbs
echo InputFolder = objArgs(0) >> _zipIt.vbs
echo ZipFile = objArgs(1) >> _zipIt.vbs
echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
echo Set objShell = CreateObject("Shell.Application") >> _zipIt.vbs
echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipIt.vbs
echo wScript.Sleep 2000 >> _zipIt.vbs

CScript  _zipIt.vbs  %TEMPDIR%  C:\someArchive.zip

pause

Доступ для запису потрібен батькові папки, що зберігається TEMPDIR. Оскільки це часто не відбувається для кореня накопичувача C, TEMPDIRможливо, доведеться змінити.

Доступ для запису також необхідний для папки, в якій .batзнаходиться сценарій (оскільки вона створює файл там).

Також зауважте, що для стисненого файлу повинно бути розширення .zip. Спроба використовувати інше розширення може призвести до помилки сценарію. Натомість генеруйте .zipфайл та перейменуйте його.


3
@quack Я тримав надію на якусь незрозумілу команду, про яку я не знав. Я бачу, як ви можете виявити, що складна вимога, якщо такої не існує, не означала нікого виводити з ладу.
Аарон Буш

@PeterMortensen: Може бути, а може і не цікаво побачити, наскільки це спрощено за допомогою Powershell. Ось приклад з 5 рядків , але також існує write-zipкомандлет, який можна завантажити з Pscx .
Тамара Війсман

Я використовував zip.exe і cywin1.dll (3mb), щоб задовольнити ZIP-код, а використання - це один рядок ... від самого zip використання деякого пакетного коду. Я знаю, що можна використовувати php bancompile'd з argv та передати файл до нього. Звучить круто. "Колір з командного рядка Windows" - це старий науково-фантастичний фільм, правда?
erm3nda

Чому нам потрібно використовувати папку temp TEMPDIR? Я думаю, що ваш намір полягає в тому, щоб обернути файл FILETOZIPу папку, правильно?
Нам Г ВУ

@ Peter Mortensen, я знаю, що це стара тема, і це майже те, що я шукаю. Чи є можливість стиснути один великий файл на менші шматки?
JohnG

38

Це є можливість промайнути файлами без встановлення будь - якого додаткового програмного забезпечення (я тестував). Рішення таке:

Запустіть це у вікні командного рядка, щоб створити ZIP-файл, який C:\someArchive.zipмістить усі файли в папці C:\test3:

CScript  zip.vbs  C:\test3  C:\someArchive.zip

Де файл zip.vbsмістить:

' Get command-line arguments.
Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))

' Create an empty ZIP file.
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)

Set objShell = CreateObject("Shell.Application")

Set source = objShell.NameSpace(InputFolder).Items

objShell.NameSpace(ZipFile).CopyHere(source)

' Required to let the ZIP command execute
' If this script randomly fails or the ZIP file is not complete,
' just increase to more than 2 seconds
wScript.Sleep 2000

Я не перевіряв це на шляхи та назви файлів, що містять пробіли. Це може спрацювати, якщо лапки ставитимуться навколо параметрів командного рядка.


Як це працює: вбудована функція zip в Windows (Windows XP та новіших версій?) Відкривається через COM- інтерфейси із оболонки Windows, explorer.exe - це частина "Shell.Application". Цей COM-інтерфейс можна використовувати із сценарію VBScript, оскільки такий сценарій може отримати доступ до компонентів COM. Щоб зробити скрипт повністю автономним, він створить порожній ZIP-файл для початку роботи (можна також створити порожній ZIP-файл і скопіювати його в цільову систему разом із сценарієм VBScript).

VBScript встановлений за замовчуванням у кожному випуску робочого столу Microsoft Windows з Windows 98.

CScript.exeє частиною хоста сценарію Windows . Хост сценаріїв Windows розповсюджується та встановлюється за замовчуванням у Windows 98 та новіших версіях Windows. Він також встановлюється, якщо встановлено Internet Explorer 5 (або більш пізню версію).


1
+1 Гарне рішення, яке буде "Просто запустити", але я вибираю BAT з кількох інших причин, які не перераховані. Тому я вважаю за краще рішення БАТ.
Аарон Буш

4
@Aaron Bush: і цей сценарій, і Beaner обидва надають команду, яка зберігає файл в командному рядку, використовуючи вбудовані функції Windows, як вимагається. Ви можете додати цю команду до пакетного файлу, як і будь-який інший.
кихат шарлатан

Зауважте, що пройдені шляхи повинні бути абсолютними, а не відносними. Мені довелося також використовувати методики у відповіді тут: stackoverflow.com/q/1645843/99640
Чак Вільбур

Шляхи повинні бути абсолютними, і, здається, випадковим чином не
виходить

Це слід вибрати як відповідь.
Герцог Маршалл

12

Якщо ви відкриті для використання PowerShell , можливості zip доступні в .NET 2.0 (PowerShell - це .NET). Ось приклад ( джерело ) кредиту Майка Ходніка :

########################################################
# out-zip.ps1
#
# Usage:
#    To zip up some files:
#       ls c:\source\*.txt | out-zip c:\target\archive.zip $_
#
#    To zip up a folder:
#       gi c:\source | out-zip c:\target\archive.zip $_
########################################################

$path = $args[0]
$files = $input

if (-not $path.EndsWith('.zip')) {$path += '.zip'} 

if (-not (test-path $path)) { 
  set-content $path ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
} 

$ZipFile = (new-object -com shell.application).NameSpace($path) 
$files | foreach {$zipfile.CopyHere($_.fullname)}

Це в основному те саме, що і код CScript в інших відповідях. Не використовуються функції .NET (і .NET так і не має підтримки ZIP). Я підозрюю, що це також може бути чутливим до питання про терміни.
Роберт Шмідт

2
У версії 4.5 додано клас .NET System.IO.Compression.ZipFile.
Бетон Ганне

7

Ви можете усунути ризик вичерпання часу під час стиснення, опитуючи наявність діалогового вікна стиснення. Цей метод також обробляє скасування користувача з вікна стиснення.

objShell.NameSpace(ZipFile).CopyHere(source)

' Wait for compression window to open
set scriptShell = CreateObject("Wscript.Shell")
Do While scriptShell.AppActivate("Compressing...") = FALSE   
   WScript.Sleep 500 ' Arbitrary polling delay
Loop  

' Wait for compression to complete before exiting script
Do While scriptShell.AppActivate("Compressing...") = TRUE   
   WScript.Sleep 500 ' Arbitrary polling delay
Loop

1
+1. Ці кодучі мавпи в стилі " .Sleep(whatever)" роблять мене хворими.
ivan_pozdeev

1
Якщо я запускаю vbs із вищезазначеною логікою для очікування, як це буде оброблятися, якщо його запускати за допомогою запланованого завдання (де фізично не ввійшов жоден користувач.)
Уес,

5

Якщо ви зможете встановити Інструменти набору ресурсів , ви знайдете інструмент командного рядка під назвою COMPRESS, який може створювати стислі файли архіву, такі як zip.

Microsoft (R) File Compression Utility  Version 5.00.2134.1
Copyright (C) Microsoft Corp. 1990-1999.  All rights reserved.

Compresses one or more files.

COMPRESS [-r] [-d] [-z] Source Destination
COMPRESS -r [-d] [-z] Source [Destination]

  -r            Rename compressed files.
  -d            Update compressed files only if out of date.
  -zx           LZX compression.
  -z            MS-ZIP compression.
  -zq[n]        Quantum compression and optional level
                (in range 1-7, default is 4).
  Source        Source file specification.  Wildcards may be used.
  Destination   Destination file | path specification.
                Destination may be a directory.
                If Source is multiple files and -r is not specified,
                Destination must be a directory.

3
+1 насправді не вирішує речі, але все-таки добре знати про них.
Аарон Буш

3
'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop

саме те, що я шукав .. але це робить мені помилку "відсутній у порожньому Zip-файлі"
Sonic Soul

Чомусь це ніколи не збільшується, якщо я друкую objShell.NameSpace( ZipFile ).Items.Countвсередині циклу, це завжди 0, навіть якщо створений zip-файл, і він має очікуваний вміст всередині ...
Том Ніколс,

2

Кілька файлів / каталогів зі спрощеним кодом.

cscript zip.vbs target.zip sourceFile1 sourceDir2 ... sourceObjN

файл zip.vbs

Set objArgs = WScript.Arguments
ZipFile = objArgs(0)

' Create empty ZIP file and open for adding
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set zip = CreateObject("Shell.Application").NameSpace(ZipFile)

' Add all files/directories to the .zip file
For i = 1 To objArgs.count-1
  zip.CopyHere(objArgs(i))
  WScript.Sleep 10000 'REQUIRED!! (Depending on file/dir size)
Next

2

Це мутація прийнятої відповіді. Я виконую безліч завдань з автоматизації на тисячах файлів одночасно, тому не можу просто спати дві секунди і не піклуватися про це. Я доклав вирішення цього питання , що також схоже на відповідь Іржі Кокара тут .

Це призведе до того, що папка призначення пінг буде кожні 200 мс, що приблизно так швидко, як Microsoft каже, щоб перевірити наявність оновлень FS.

Set parameters = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
SourceDir = FS.GetAbsolutePathName(parameters(0))
ZipFile = FS.GetAbsolutePathName(parameters(1))
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set shell = CreateObject("Shell.Application")
Set source_objects = shell.NameSpace(SourceDir).Items
Set ZipDest = shell.NameSpace(ZipFile)
Count=ZipDest.Items().Count
shell.NameSpace(ZipFile).CopyHere(source_objects)
Do While Count = ZipDest.Items().Count
    wScript.Sleep 200
Loop

1

Ось моя спроба узагальнити вікна вбудованих можливостей для стиснення та стискання - https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folders -із-партія-ф

з кількома заданими рішеннями, які повинні працювати майже на кожній машині Windows.

Що стосується shell.application та WSH, я віддав перевагу jscript, оскільки він дозволяє гібридний пакетний / jscript-файл (з розширенням .bat), який не вимагає тимчасових файлів. Я вклав функції розпакування та zip в один файл плюс ще кілька функцій .


0

Якщо в Windows 8 або Windows Server 2012 у вас будуть PowerShell і .NET 4.5, тож ви можете зробити це:

zip.ps1 (використання :)-directory <directory to zip up> -name <zip name> :

param (
    [string]$directory,
    [string]$name
)

Add-Type -Assembly System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory($directory, $name, [System.IO.Compression.CompressionLevel]::Optimal, $false)

zip.bat (якщо вам потрібен помічник для виклику PowerShell для вас, каталог - це перший аргумент, а ім'я zip - друге):

@Echo Off
powershell -ExecutionPolicy ByPass -Command "& '%~dpn0.ps1' -directory '%1' -name '%2'"

0

Windows 10 build 17063 або пізнішої версії постачається з tar.exe, який може працювати з zip з командного рядка.

tar.exe -xf archive.zip

або створити архів

tar.exe -cf Test.zip Test

-5

Тепер командний рядок Windows надає компактну команду, яка, наскільки я можу сказати, є власною для Windows. Це повинно відповідати вимогам, якщо я щось не пропустив.


9
compactіснує з XP і є інструментом для управління стисненням NTFS
Der Hochstapler
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.