的控制檯版本Rar.exe
有命令l
到列表歸檔文件根據文本文件Rar.txt
的內容在的程序文件文件夾中WinRAR是控制檯版本的手冊。使用命令l
(或L
)運行Rar.exe
的列表輸出可以在批處理文件中進行處理,以確定RAR存檔文件是否在頂層僅包含單個目錄,而不包含其他任何內容。但Rar.exe
支持像免費UnRAR.exe
只是RAR檔案。
要支持ZIP存檔,則需要使用GUI版本WinRAR.exe
,該版本支持提取RAR和ZIP存檔以及其他存檔類型。
該手冊爲WinRAR.exe
是幫助WinRAR的它可以在點擊菜單幫助上的菜單項幫助主題上運行WinRAR的打開。在幫助選項卡內容有列表項目命令行模式與參考幫助頁面中的所有必要信息從命令行運行WinRAR.exe
。
它可以在看好命令列表是WinRAR.exe
不支持命令l
輸出檔案文件的內容,因爲是一個圖形用戶界面應用程序控制臺窗口中看到。
因此,從命令行或批處理文件中確定歸檔文件是否僅包含使用WinRAR.exe
時的單個目錄的最高級別是不可能的。
但是,這並不重要,因爲首先解析文件和目錄名稱的歸檔文件,然後使用相應的命令在命令行上或在命令行上指定額外的解壓縮文件夾的情況下解壓縮歸檔文件效率不高。
這是更有效的先提取所有的* .rar程序(後來也全部* .zip文件)只使用一個WinRAR的電話與開關-ad
文件到每個存檔文件解壓縮到一個子目錄與歸檔文件的名稱第二,刪除每個提取目錄不是必需的,因爲相應的存檔文件只包含頂級目錄中的單個目錄。
這種聰明的做法是在批處理文件中使用以下其中包含以下附加功能,使之成爲希望很多WinRAR的用戶有用:
的工作目錄可以被指定爲第一個參數上調用批文件甚至可以是UNC路徑。
批處理文件找出自動哪裏WinRAR.exe
安裝工作也不被安裝在默認的Program Files目錄中的用例與32位或64位的WinRAR(如在所有的我的電腦)。
注:註釋的批處理文件貼在下面,如果在當前或指定目錄中的現有檔案文件已被提取之前不檢查。因此,建議不要在一個目錄中多次運行該批處理文件,而該目錄的存檔文件一旦被處理時不會從該目錄中刪除。
@echo off
rem Change working directory if batch file was started with an argument.
if not "%~1" == "" (
pushd "%~1" 2>nul
if errorlevel 1 (
echo Specified directory "%~1" does not exist.
echo/
pause
goto :EOF
)
)
setlocal EnableExtensions DisableDelayedExpansion
rem Does WinRAR exist in default program files folder?
set "WinRAR=%ProgramFiles%\WinRAR\WinRAR.exe"
if exist "%WinRAR%" goto StartExtraction
rem Does WinRAR exist in default program files folder for x86 applications?
set "WinRAR=%ProgramFiles(x86%\WinRAR\WinRAR.exe"
if exist "%WinRAR%" goto StartExtraction
rem Try to determine installation location of WinRAR.exe from registry.
set "TypeToken=2"
goto GetPathFromRegistry
rem On Windows Vista and later REG.EXE outputs without version info:
rem HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe
rem (Default) REG_SZ Full path to WinRAR\WinRAR.exe
rem There are only spaces used to separate value name, value type and value string.
rem But REG.EXE version 3.0 outputs on Windows XP with version info:
rem ! REG.EXE VERSION 3.0
rem
rem HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe
rem <NO NAME> REG_SZ Full path to WinRAR\WinRAR.exe
rem NOTE: There are 4 indent spaces and 2 separating tabs in REG 3.0 output line.
rem So either token 2 or token 3 contains value type REG_SZ
rem used to identify the line with the wanted information.
:GetPathFromRegistry
for /F "skip=1 tokens=%TypeToken%*" %%A in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe" /ve 2^>nul') do (
if "%%A" == "REG_SZ" (
if exist "%%~fB" (
set "WinRAR=%%~fB"
goto StartExtraction
)
) else if "%%A" == "NAME>" (
set "TypeToken=3"
goto GetPathFromRegistry
)
)
endlocal
if not "%~1" == "" popd
echo Could not determine directory containing WinRAR.exe.
echo/
echo Please configure it manually in file: %~f0
echo/
pause
goto :EOF
rem WinRAR supports multiple archive types on extraction.
rem Specify here the archive file extensions for extraction.
:StartExtraction
for %%I in (rar zip) do call :ExtractArchives %%I
rem Restore previous command environment, restore previous current directory
rem and exit this batch file without fall through to the subroutines below.
endlocal
if not "%~1" == "" popd
goto :EOF
rem The subroutine ExtractArchives processes all archive files in current
rem directory with the file extension passed to subroutine as first argument.
rem WinRAR is called once to extract all files with specified file extension
rem for extraction into a subdirectory with name of the archive file.
rem Then one more subroutine is called for each archive file to determine
rem if it is safe to move the extracted archive file contents up one level.
:ExtractArchives
if not exist "*.%~1" goto :EOF
"%WinRAR%" x -ad -cfg- -ibck -y -- "*.%~1"
for %%A in ("*.%~1") do call :MoveUpExtracted "%%~nA"
goto :EOF
rem The subroutine MoveUpExtracted first checks if for the archive file
rem passed to the subroutine as first argument a subdirectory exists at
rem all, i.e. the extraction before was successful for that archive.
rem Next it counts the subdirectories in the archive extraction directory.
rem Nothing is moved up if there is more than 1 subdirectory in archive
rem extraction directory.
rem Also nothing is moved up if archive extraction directory contains
rem 1 or more files.
rem After verification of archive extraction directory really containing
rem only a single subdirectory and nothing else, the name of the archive
rem extraction directory is compared case-insensitive with the name of
rem the single subdirectory in archive extraction directory. On equal
rem directory names the archive extraction directory is renamed by
rem appending _tmp to make it possible to move the subdirectory with same
rem name up one level in directory hierarchy. There is hopefully by chance
rem never a directory present in current directory with name of an archive
rem file and _tmp appended.
rem Next it is checked if in current directory there is not already existing
rem a directory with name of the subdirectory from extracted archive in which
rem case it is also not possible to move the directory up one level. In this
rem special use case the archive extraction directory is kept containing just
rem a single subdirectory with restoring original directory name.
rem Then the single subdirectory in archive extraction directory is moved up
rem one level which is very fast as just the file allocation table is updated
rem and no data is really moved.
rem The directory movement could fail if the extracted directory has hidden
rem attribute set. In this case temporarily remove the hidden attribute,
rem move the directory up one level in directory hierarchy and set the
rem hidden attribute again on the directory.
rem On a succesful moving up of the extracted directory the (renamed)
rem extraction directory being now empty is deleted as not further needed.
:MoveUpExtracted
if not exist "%~1\" (
echo Error: No folder for archive %~1
goto :EOF
)
echo Processing archive folder "%~1"
set FolderCount=0
set "FolderName="
for /F "delims=" %%D in ('dir "%~1\*" /AD /B 2^>nul') do (
if defined FolderName goto :EOF
set /A FolderCount+=1
set "FolderName=%%D"
)
if not %FolderCount% == 1 goto :EOF
for /F "delims=" %%F in ('dir "%~1\*" /A-D /B 2^>nul') do goto :EOF
set "ParentRenamed=0"
set "ParentFolder=%~1"
if /I "%~1" == "%FolderName%" (
ren "%~1" "%~1_tmp" 2>nul
if errorlevel 1 (
echo Failed to rename "%~1" to "%~1_tmp".
goto :EOF
)
set "ParentFolder=%~1_tmp"
set "ParentRenamed=1"
)
if exist "%FolderName%" (
if %ParentRenamed% == 1 ren "%~1_tmp" "%~1"
echo Error: Folder exists "%FolderName%"
goto :EOF
)
move "%ParentFolder%\%FolderName%" "%FolderName%" >nul 2>nul
if not errorlevel 1 (
rd "%ParentFolder%"
goto :EOF
)
%SystemRoot%\System32\attrib.exe -h "%ParentFolder%\%FolderName%" >nul
move "%ParentFolder%\%FolderName%" "%FolderName%" >nul
if errorlevel 1 (
if %ParentRenamed% == 1 (
ren "%ParentFolder%" "%~1"
goto :EOF
)
)
%SystemRoot%\System32\attrib.exe +h "%FolderName%"
rd "%ParentFolder%"
goto :EOF
我使用的是32位Windows自Windows 95,但我跑我自己從來沒有進入MAX_PATH
限制,即絕對的文件/文件夾名稱長於259個字符。
因此,當歸檔文件名非常長時(例如,文件名+文件擴展名只有256個字符),重寫批處理文件以使其工作也非常有趣並且非常耗時。
在我下面的批處理文件的發展找到了以下內容:
像DIR,FOR,RD和REN支持短8.3路徑名稱和一些命令文件/文件夾名稱,而其他命令如ATTRIB和MOVE僅在路徑中支持它們,但不支持文件/文件夾名稱(至少在Windows XP上)。
所以無法使用其簡短的8.3名稱來移動文件夾或更改其屬性。
當包含完整路徑的文件夾名稱長於259個字符時,所有命令都無法使用相對文件夾路徑使用相對文件夾名稱。這意味着Windows命令解釋器在執行任何命令之前首先使用完整路徑確定文件夾名稱。所以當前目錄應該有一個很短的路徑來處理具有很長名稱或包含名稱很長的目錄的檔案。
我無法弄清楚如何獲得一個文件夾的短名稱或使用由for /?
解釋的時候只是一個相對的文件夾路徑是由Windows命令解釋器解析%~fs1
(批處理文件)由call /?
或%%~fsI
解釋其路徑,即只是沒有路徑的文件夾的長名稱。
在運行命令DIR與選項/X
獲取目錄的短名稱,第三列包含短名稱和第四列的長名稱。但是第三列中的短名稱可能會在很短的文件夾名稱中丟失。
Volume in drive C is System
Volume Serial Number is 7582-4210
Directory of C:\Temp\Test
29.04.2017 22:39 <DIR> .
29.04.2017 22:39 <DIR> ..
29.04.2017 22:39 <DIR> ARCHIV~1 archive_with_a_very_very_very_..._long_name_1
29.04.2017 22:39 <DIR> Batch
29.04.2017 22:39 <DIR> xyz
同一命令dir /AD /X
在德國的Windows XP SP3的x86執行:的dir /AD /X
英文版Windows 7 SP1 64位
輸出在NTFS分區上與德國執行在Windows區域和語言設置來設置
Datenträger in Laufwerk F: ist TEMP
Volumeseriennummer: CAA5-41AA
Verzeichnis von F:\Temp
29.04.2017 22:39 <DIR> .
29.04.2017 22:39 <DIR> ..
29.04.2017 22:39 <DIR> BATCH Batch
29.04.2017 22:39 <DIR> xxx
29.04.2017 22:39 <DIR> ARCHIV~1 archive_with_a_very_very_very_..._long_name_1
注:FAT32分區還與德國在Windows區域和語言設置來設置這個非常長的目錄名在我的名字中被截斷了...
。
爲什麼目錄Batch
在Windows XP計算機上有簡稱BATCH
但在Windows 7上沒有短名稱對我來說真的不能解釋。
下面是批處理腳本,只要當前目錄的路徑很短,就可以在歸檔中支持長歸檔名稱和長目錄名稱。
@echo off
rem Change working directory if batch file was started with an argument.
if not "%~1" == "" (
pushd "%~1" 2>nul
if errorlevel 1 (
echo Specified directory "%~1" does not exist.
echo/
pause
goto :EOF
)
)
setlocal EnableExtensions DisableDelayedExpansion
rem Does WinRAR exist in default program files folder?
set "WinRAR=%ProgramFiles%\WinRAR\WinRAR.exe"
if exist "%WinRAR%" goto StartExtraction
rem Does WinRAR exist in default program files folder for x86 applications?
set "WinRAR=%ProgramFiles(x86%\WinRAR\WinRAR.exe"
if exist "%WinRAR%" goto StartExtraction
rem Try to determine installation location of WinRAR.exe from registry.
set "TypeToken=2"
goto GetPathFromRegistry
rem On Windows Vista and later REG.EXE outputs without version info:
rem HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe
rem (Default) REG_SZ Full path to WinRAR\WinRAR.exe
rem There are only spaces used to separate value name, value type and value string.
rem But REG.EXE version 3.0 outputs on Windows XP with version info:
rem ! REG.EXE VERSION 3.0
rem
rem HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe
rem <NO NAME> REG_SZ Full path to WinRAR\WinRAR.exe
rem NOTE: There are 4 indent spaces and 2 separating tabs in REG 3.0 output line.
rem So either token 2 or token 3 contains value type REG_SZ
rem used to identify the line with the wanted information.
:GetPathFromRegistry
for /F "skip=1 tokens=%TypeToken%*" %%A in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe" /ve 2^>nul') do (
if "%%A" == "REG_SZ" (
if exist "%%~fB" (
set "WinRAR=%%~fB"
goto StartExtraction
)
) else if "%%A" == "NAME>" (
set "TypeToken=3"
goto GetPathFromRegistry
)
)
endlocal
if not "%~1" == "" popd
echo Could not determine directory containing WinRAR.exe.
echo/
echo Please configure it manually in file: %~f0
echo/
pause
goto :EOF
rem WinRAR supports multiple archive types on extraction.
rem Specify here the archive file extensions for extraction.
rem But first delete temporary folder from a previous breaked execution.
:StartExtraction
rd /Q /S # 2>nul
for %%I in (rar zip) do call :ExtractArchives %%I
rem Restore previous command environment, restore previous current directory
rem and exit this batch file without fall through to the subroutines below.
endlocal
if not "%~1" == "" popd
goto :EOF
rem The subroutine ExtractArchives processes all archive files in current
rem directory with the file extension passed to subroutine as first argument.
rem WinRAR is called once to extract all files with specified file extension
rem for extraction into a subdirectory with name of the archive file.
rem Then one more subroutine is called for each archive file to determine
rem if it is safe to move the extracted archive file contents up one level.
:ExtractArchives
if not exist "*.%~1" goto :EOF
"%WinRAR%" x -ad -cfg- -ibck -y -- "*.%~1"
for %%A in ("*.%~1") do call :MoveUpExtracted "%%~nA" %1
goto :EOF
rem The subroutine MoveUpExtracted first checks if for the archive file
rem passed to the subroutine as first argument a subdirectory exists at
rem all, i.e. the extraction before was successful for that archive, and
rem determines short 8.3 name of this directory.
rem Next it counts the subdirectories in the archive extraction directory
rem using short directory name. Nothing is moved up if there is more than
rem 1 subdirectory in archive extraction directory.
rem Also nothing is moved up if archive extraction directory contains
rem 1 or more files.
rem After verification of archive extraction directory really containing
rem only a single subdirectory and nothing else, the current archive folder
rem is renamed to # (single character folder name) using short folder name.
rem This folder rename should work in general. The current archive folder
rem is kept in case of this folder rename fails unexpected because it is
rem not yet known if the current directory does not already contain the
rem single directory extracted from current archive or rename failed
rem because of a permission or a directory sharing access restriction.
rem Next it is checked if in current directory there is not already existing
rem a directory with name of the subdirectory from extracted archive in which
rem case it is also not possible to move the directory up one level. In this
rem special use case the archive extraction directory is kept containing just
rem a single subdirectory with restoring original directory name. In case of
rem restoring archive directory fails unexpected, the directory with name #
rem is deleted and the archive is extracted once again into a directory with
rem name of archive file.
rem It is clear on this point that the single directory in archive extraction
rem directory can be moved up to current directory from directory wit having
rem now the temporary name #.
rem Moving a directory with command MOVE is not possible if hidden attribute
rem is set on directory. For that reason it is checked next if the directory
rem to move up has hidden attribute set using its short directory name.
rem In case of directory has hidden attribute is indeed set, it is removed
rem which is also verified. The verification can't be done with errorlevel
rem evaluation as external command ATTRIB does not set errorlevel on failed
rem attribute change. So the attribute check is done once again after the
rem hidden attribute is removed with ATTRIB.
rem ATTRIB also fails to change the attribute if absolute folder path is
rem longer than 259 characters. In this case the current extraction folder
rem with temporary name # is deleted completely and the current archive is
rem extracted once again to current directory without creation of an
rem additional directory with name of archive file.
rem Then the single subdirectory in archive extraction directory having
rem now name # is also renamed to # using short directory name to avoid
rem a problem on next command MOVE with an absolute folder path longer
rem than 259 characters as much as possible.
rem The directory extracted from archive with name # in directory # is
rem moved up to current directory with suppressing all errors which could
rem occur for example if path of current directory plus name of directory
rem as extracted from archive file is too long.
rem The directory # in current directory with its subdirectory # is deleted
rem on a moving error and the current archive file is extracted once again
rem into current directory without creation of an additional directory with
rem name of archive file.
rem But on successful movement of the folder with correct name to current
rem directory the hidden attribute is set on folder if the extracted folder
rem has it also set before moving the folder and the finally empty folder #
rem is deleted before exiting subroutine.
:MoveUpExtracted
set "FolderToCheck=%~f1"
set "FolderToCheck=%FolderToCheck:~0,258%"
for /F "skip=5 tokens=4*" %%X in ('dir "%FolderToCheck%*" /AD /X 2^>nul') do (
if "%%Y" == "%~1" set "ArchiveFolder=%%X" & goto Subfolders
if "%%Y" == "" if /I "%%X" == "%~1" set "ArchiveFolder=%%X" & goto Subfolders
)
echo Error: No folder for archive %~1
goto :EOF
:Subfolders
@echo off
echo Processing archive folder "%~1"
set FolderCount=0
set "FolderName="
for /F "delims=" %%D in ('dir "%ArchiveFolder%\*" /AD /B 2^>nul') do (
if defined FolderName goto :EOF
set /A FolderCount+=1
set "FolderName=%%D"
)
if not %FolderCount% == 1 goto :EOF
for /F "delims=" %%F in ('dir "%ArchiveFolder%\*" /A-D /B 2^>nul') do goto :EOF
ren "%ArchiveFolder%" # 2>nul
if errorlevel 1 (
echo Error: Failed to rename "%~1"
goto :EOF
)
set "FolderToCheck=%~dp1%FolderName%"
set "FolderToCheck=%FolderToCheck:~0,258%"
for /F "skip=5 tokens=4*" %%X in ('dir "%FolderToCheck%*" /AD /X 2^>nul') do (
if "%%Y" == "%FolderName%" goto FolderExist
if "%%Y" == "" if /I "%%X" == "%FolderName%" goto FolderExist
)
set "HiddenFolder=0"
set "FolderToCheck=%~dp1#\%FolderName%"
set "FolderToCheck=%FolderToCheck:~0,258%"
for /F "skip=5 tokens=4*" %%X in ('dir "%FolderToCheck%*" /AD /X 2^>nul') do (
if "%%Y" == "%FolderName%" set "FolderToMove=%%X" & goto CheckHidden
if "%%Y" == "" if /I "%%X" == "%FolderName%" set "FolderToMove=%%X" & goto CheckHidden
)
:CheckHidden
for %%X in ("#\%FolderToMove%") do (
for /F "tokens=2 delims=h" %%H in ("%%~aX") do (
if %HiddenFolder% == 1 goto ArchiveExtract
set "HiddenFolder=1"
%SystemRoot%\System32\attrib.exe -h "#\%FolderName%"
goto CheckHidden
)
)
ren "#\%FolderToMove%" # 2>nul
move #\# "%FolderName%" >nul 2>nul
if errorlevel 1 goto ArchiveExtract
if %HiddenFolder% == 1 %SystemRoot%\System32\attrib.exe +h "%FolderName%"
rd #
goto :EOF
:ArchiveExtract
rd /Q /S #
"%WinRAR%" x -cfg- -ibck -y -- "%~1.%~2"
goto :EOF
:FolderExist
echo Error: Folder exists "%FolderName%"
ren # "%~1" 2>nul
if not errorlevel 1 goto :EOF
rd /Q /S #
"%WinRAR%" x -ad -cfg- -ibck -y -- "%~1.%~2"
goto :EOF
這將是肯定更好地編寫C或C++以上批處理腳本控制檯應用程序或C#是長路徑意識到更換子程序MoveUpExtracted
。
在Windows 10版本1607(週年更新)或更高版本的Windows版本的MAX_PATH
限260個字符(259個字符加上終止空字節),可以通過組策略或通過添加註冊表值被禁用,請參閱
對於理解使用的命令以及它們如何工作,打開命令提示符窗口中,執行的有以下命令,並仔細閱讀爲每個命令顯示的所有幫助頁面。
attrib /?
call /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
move /?
pause /?
popd /?
pushd /?
rd /?
reg /?
reg query /?
rem /?
ren /?
set /?
setlocal /?
閱讀也是微軟的文章:
你是什麼意思「的意思,但不是如何創建它,只有當不存在?「 –
如果檔案是「案例01」,我不創建文件夾,如果「案例02」我創建了一個文件夾來提取所有文件。 –