سؤال هل يمكنك ضغط ملف من موجه الأوامر باستخدام إمكانية Windows المضمنة فقط لملفات zip؟


لدي ملف دفعي يخرج ملف نصي. ظننت أنه سيكون من الرائع إذا تمكنت من الضغط عليه أيضًا.

سيتم استخدام هذا في بيئة غير خاضعة للتحكم ، لذلك لا يمكنني وضع افتراضات حول وجود منتجات برامج تابعة لجهات خارجية مثل 7 زيب، وهذا يحتاج إلى استخدام ويندوز 'المدمج الآن في القدرة على الملفات المضغوطة.


93
2018-02-19 19:46


الأصل


يمكنك استخدام Powershell أو WSH البرمجة؟ قد يكون هذا هو الطريقة الوحيدة لاستخدام Windows 'معالجة البريدي المضمنة من سطر الأوامر. خلاف ذلك ، كما تشير مولي ، تحتاج إلى أداة طرف ثالث. - quack quixote
حتى ترسل شخص ما ملف دفعي ولا يمكنك إرساله بعض gzip.exe مرتبطة بشكل ثابت صغير؟ - akira
سؤال OP هو سؤال ممتاز (على الرغم من الاتهام الغريب لـquackquixote). بما أن Windows توفر هذا كنقرة واحدة تحت SendTo ، هناك يجب ليكون أمرًا قابلاً للاستخدام في ملف BAT. هذا سؤال جيد حتى لو كان الجواب "لا" ويجب على المرء (يبعث على السخرية) اللجوء إلى استخدام أداة خارجية قد تكون أو لا تكون مكافئة. - Jon Coombs
هذا هو حلقة الوصل بواسطة Tomas يحتوي على برنامج نصي مكتوب بشكل جيد لمحتويات المجلد المضغوط. لجعلها تعمل فقط نسخ البرنامج النصي إلى ملف دفعي وتنفيذها عن طريق تحديد مجلد مضغوط (المصدر). لا داعي للإشارة إلى الدليل الوجهة كما هو الافتراضي في البرنامج النصي إلى سطح المكتب ("٪ USERPROFILE٪ \ Desktop") - Abhijeet
أبسط سيكون ، في موجه كمد: powershell.exe Compress-Archive file-to-zip.txt zippedfile.zip (يعمل مع مجلد أيضا) - ThomasGuenet


الأجوبة:


هنا هو كل حل ملف دفعي (شكلا من إجابتي الأخرى) التي من شأنها الرمز ملف مسمى 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 ملف وإعادة تسميته.


81
2018-02-22 17:28



quack كنت صامدة على أمل بعض الأوامر الغامضة التي لم أكن أعرف عنها. أستطيع أن أرى كيف يمكن أن تجد أن هناك متطلبًا صعبًا إذا لم يكن موجودًا ، لا يعني التخلص من أي شخص. - Aaron Bush
PeterMortensen: قد يكون أو لا يكون من المثير للاهتمام معرفة مدى تبسيط هذا الأمر مع Powershell. هنا مثال 5 خط، ولكن هناك أيضا موجود write-zip cmdlet التي يمكن تنزيلها من Pscx. - Tom Wijsman
لقد استخدمت zip.exe و cywin1.dll (3mb) لإرضاء الرمز البريدي والاستخدام هو سطر واحد ... من الرمز البريدي نفسه باستخدام بعض كود الدفعة. وأنا أعلم يمكن استخدام php bancompile'd مع argv وتمرير ملف إليها. يبدو جيدا. "A zip from windows command line" هو فيلم خيال علمي قديم ، أليس كذلك؟ - erm3nda
لماذا يتعين علينا استخدام مجلد مؤقت TEMPDIR؟ أعتقد أن نيتك هي لف الملف FILETOZIP عن طريق مجلد أليس كذلك؟ - Nam G VU
@ بيتر مورتنسن ، أعرف أن هذا خيط قديم ، وهذا هو ما أبحث عنه تقريبًا. هل هناك خيار لضغط ملف كبير واحد إلى قطع أصغر؟ - JohnG


هذا هو ممكن لملفات ZIP دون تركيب أي إضافية البرنامج (لقد اختبرت ذلك). الحل هو:

قم بتشغيل هذا في نافذة سطر الأوامر لإنشاء ملف 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 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 واجهات من ويندوز قذيفة ، EXPLORER.EXE - وهذا هو جزء "Shell.Application". يمكن استخدام واجهة COM هذه من فبسكريبت النصي ل مثل هذا البرنامج النصي يمكن الوصول إلى مكونات COM. لجعل البرنامج النصي مكتفية ذاتيا بالكامل فإنه يخلق ملف ZIP فارغ للبدء (يمكن أيضًا إنشاء ملف ZIP فارغ ونسخه إلى النظام المستهدف مع البرنامج النصي VBScript).

تم تثبيت VBScript بشكل افتراضي في كل سطح مكتب الافراج عن مايكروسوفت ويندوز منذ ويندوز 98.

CScript.exe جزء من Windows Script Host. يتم توزيع Windows Script Host وتثبيته افتراضيًا على نظام التشغيل Windows 98 والإصدارات الأحدث من Windows. يتم تثبيته أيضًا إذا تم تثبيت Internet Explorer 5 (أو إصدار أحدث).


35
2018-02-20 15:48



+1 حل جيد من شأنه أن "تشغيل فقط" ، لكنني اخترت BAT لعدة أسباب أخرى غير مدرجة. لذلك أفضل حل BAT. - Aaron Bush
@ آرون بوش: هذا البرنامج النصي و Beaner يوفران أمرًا يقوم بتنسيق ملف على سطر الأوامر ، وذلك باستخدام وظائف windows builtin ، كما هو مطلوب. يمكنك إضافة هذا الأمر إلى batchfile مثل أي شيء آخر. - quack quixote
لاحظ أن المسارات التي تم اجتيازها يجب أن تكون مطلقة وليست نسبية. اضطررت أيضا لاستخدام التقنيات في الإجابة هنا: stackoverflow.com/q/1645843/99640 - Chuck Wilbur
يجب أن تكون المسارات مطلقة ويبدو أنها تفشل بشكل عشوائي :( - kixorz
يجب اختيار هذا كإجابة. - The Duke Of Marshall שלום


إذا كنت مفتوحة على استخدام بوويرشيلتتوفر إمكانيات 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)}

11
2018-02-19 21:59



هذا هو في الأساس نفس الشيء مثل رمز CScript في إجابات أخرى. يتم استخدام أية ميزات .NET (ولا يحتوي .NET على دعم ZIP على أية حال). أظن أن هذا قد يكون أيضًا حساسًا لمشكلة التوقيت. - Robert Schmidt
تمت إضافة فئة .NET System.IO.Compression.ZipFile في الإصدار 4.5. - Concrete Gannet


يمكنك التخلص من مخاطر انتهاء المهلة أثناء الضغط عن طريق الاستقصاء لوجود نافذة حوار الضغط. تعالج هذه الطريقة أيضًا المستخدم بإلغاء الخروج من نافذة الضغط.

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

7
2017-11-23 00:47



+1. تلك رمز نمط القرد ".Sleep(whatever)"اجعلني مريضة. - ivan_pozdeev
إذا كنت أقوم بتشغيل vbs مع المنطق أعلاه للانتظار ، فكيف سيتم التعامل مع هذا إذا تم إطلاقه من خلال مهمة مجدولة (حيث لم يتم تسجيل دخول أي مستخدم فعليًا.) - Wes


إذا كنت قادراً على تثبيت أدوات أدوات الموارد، ستجد أداة سطر الأوامر تسمى 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.

4
2018-02-19 20:29



إجراء 1+ لا يحل الأشياء حقًا ، ولكن لا يزال من الجيد معرفة ذلك. - Aaron Bush


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

3
2017-08-07 07:46



بالضبط ما كنت أبحث عنه .. لكنه أعطني خطأ "مفقود في ملف مضغوط فارغة" - Sonic Soul
لسبب ما هذا لا يتزايد أبدا ، إذا كنت تطبع objShell.NameSpace( ZipFile ).Items.Count داخل الحلقة ، يكون الرقم 0 دائمًا على الرغم من إنشاء الملف المضغوط ويحتوي على المحتويات المتوقعة داخل ... - Thom Nichols


ملفات / أدلة متعددة مع رمز مبسط.

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
2017-11-05 21:06