Что нового

Архивация файлов с помощью 7zip, имена которых содержат пробел

MON@H Rasta

[Ganj@ $moker]
Сообщения
12
Репутация
0
Приветствую всех.
Задача проста, скрипт должен бесшумно архивировать все файлы в дирректории и удалять их после архивирования. Хорошо бы, конечно, по расширению определять и исключать архивы, но можно и без этого.
Написал, как смог, прошу сильно не пинать.

Код:
$K='"'
$DEL = "DEL /F /Q "
$7z = '7-Zip\7z.exe'
$ArchOptions = ' -mmt -ms=off'
$CurrentDir= @ScriptDir & '\'
$ProgramFilesDir = @ProgramFilesDir & '\'

$Search = FileFindFirstFile("*.*")
If $Search = -1 Then
	Exit
EndIf

While 1
	$File = FileFindNextFile($Search)

	If @error Then
		ExitLoop
	ElseIf $File = @ScriptName Then
		$File = FileFindNextFile($Search)
	EndIf

	$ArchiveName = $File & '.7z'
	$Archivate = $K & $ProgramFilesDir & $7z & $K & ' a -mx9 ' & $ArchiveName & ' ' & $File & $ArchOptions
	Archivate($File)
WEnd

Func Archivate($File)
	RunWait(@ComSpec & ' /c ' & $Archivate, "")
	RunWait(@ComSpec & ' /c ' & $DEL & $K & $CurrentDir & $File & $K, "")
EndFunc

FileClose($Search)

Сыроват, будет доработан, это всё понятно. Столкнулся с проблемой и не могу решить. Если имена файлов содержат пробелы, их необходимо заключать в кавычки. Ок, попробовал сделать вот так:

Код:
$K='"'
$DEL = "DEL /F /Q "
$7z = '7-Zip\7z.exe'
$ArchOptions = ' -mmt -ms=off'
$CurrentDir= @ScriptDir & '\'
$ProgramFilesDir = @ProgramFilesDir & '\'

$Search = FileFindFirstFile("*.*")
If $Search = -1 Then
	Exit
EndIf

While 1
	$File = FileFindNextFile($Search)

	If @error Then
		ExitLoop
	ElseIf $File = @ScriptName Then
		$File = FileFindNextFile($Search)
	EndIf

	$ArchiveName = $File & '.7z'
	$Archivate = $K & $ProgramFilesDir & $7z & $K & ' a -mx9 ' & $K & $ArchiveName & $K & ' ' & $K & $File & $K & $ArchOptions
	Archivate($File)
WEnd

Func Archivate($File)
	RunWait(@ComSpec & ' /c ' & $Archivate, "")
	RunWait(@ComSpec & ' /c ' & $DEL & $K & $CurrentDir & $File & $K, "")
EndFunc

FileClose($Search)

На что я получаю сообщение:

Код:
"C:\Program" не является внутренней или внешней командой, исполняемой программой или пакетным файлом.

D:\Program Files\AutoIt3\M\TMP>

Не совсем понимаю в чём проблема. Дописываю копирование в буфер комманды, которая отправляется скриптом в @ComSpec.

Код:
Func Archivate($File)
	ClipPut($Archivate)
	RunWait(@ComSpec & ' /k ' & $Archivate, "")
	RunWait(@ComSpec & ' /c ' & $DEL & $K & $CurrentDir & $File & $K, "")
EndFunc

Вот что в результате получаю в буфер:

Код:
"C:\Program Files\7-Zip\7z.exe" a -mx9 "TESTкопия.au3.7z" "TESTкопия.au3" -mmt -ms=off

Открываю cmd, ctrl+v -> enter. Всё ок, работает... :blink:

Код:
Microsoft Windows [Version 6.1.7601]
(c) Корпорация Майкрософт (Microsoft Corp.), 2009. Все права защищены.

d:\Program Files\AutoIt3\M\TMP>"C:\Program Files\7-Zip\7z.exe" a -mx9 "TESTкопия.au3.7z" "TESTкопия.au3" -mmt -ms=off

7-Zip [64] 9.22 beta  Copyright (c) 1999-2011 Igor Pavlov  2011-04-18
Scanning

Creating archive TESTкопия.au3.7z

Compressing  TESTкопия.au3

Everything is Ok

d:\Program Files\AutoIt3\M\TMP>


Прошу помощи...
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
MON@H Rasta
Может быть нужно заменить:
Код:
Archivate($File)


на:
Код:
Archivate($Archivate)
 
Автор
M

MON@H Rasta

[Ganj@ $moker]
Сообщения
12
Репутация
0
Код:
$K='"'
$DEL = "DEL /F /Q "
$7z = '7-Zip\7z.exe'
$ArchOptions = ' -mmt -ms=off'
$CurrentDir= @ScriptDir & '\'
$ProgramFilesDir = @ProgramFilesDir & '\'

$Search = FileFindFirstFile("*.*")
If $Search = -1 Then
    Exit
EndIf

While 1
    $File = FileFindNextFile($Search)

    If @error Then
        ExitLoop
    ElseIf $File = @ScriptName Then
        $File = FileFindNextFile($Search)
    EndIf

    $ArchiveName = $File & '.7z'
    $Archivate = $K & $ProgramFilesDir & $7z & $K & ' a -mx9 ' & $K & $ArchiveName & $K & ' ' & $K & $File & $K & $ArchOptions
    Archivate($Archivate)
WEnd

Func Archivate($Archivate)
    RunWait(@ComSpec & ' /c ' & $Archivate, "")
    RunWait(@ComSpec & ' /c ' & $DEL & $K & $CurrentDir & $File & $K, "")
EndFunc

FileClose($Search)

Код:
"C:\Program" не является внутренней или внешней командой, исполняемой программой или пакетным файлом.

D:\Program Files\AutoIt3\M\TMP>
+ Теперь скрипт и сам себя потёр :smile:
UPD: сам себя трёт в любом случае...
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
MON@H Rasta
Вот версия, только без удаления:

Код:
$K='"'
$DEL = "DEL /F /Q "
$7z = '7-Zip\7z.exe'
$ArchOptions = ' -mmt -ms=off'
$CurrentDir= @ScriptDir & '\'
$ProgramFilesDir = @ProgramFilesDir & '\'

$Search = FileFindFirstFile("*.*")
If $Search = -1 Then
    Exit
EndIf

While 1
    $File = FileFindNextFile($Search)

    If @error Then
        ExitLoop
    ElseIf $File = @ScriptName Then
        $File = FileFindNextFile($Search)
    EndIf

    $ArchiveName = $File & '.7z'

    Archivate($File)
WEnd

Func Archivate($File)
    RunWait($K & $ProgramFilesDir & $7z & $K & ' a -mx9 ' & $K & $ArchiveName & $K & ' ' & $K & $File & $K & $ArchOptions)
    ;RunWait(@ComSpec & ' /c ' & $DEL & $K & $CurrentDir & $File & $K, "")
EndFunc

FileClose($Search)
 
Автор
M

MON@H Rasta

[Ganj@ $moker]
Сообщения
12
Репутация
0
snoitaleR
да, так срабатывает, благодарю!
Всё же не понимаю, что ему не нравится в моей версии :(


Пока заюзаю этот подход, но если у кого будут идеи по поводу того, почему так происходит - пишите, буду рад!
 

gora

Знающий
Сообщения
315
Репутация
19
MON@H Rasta [?]
но если у кого будут идеи по поводу того, почему так происходит - пишите, буду рад
Поправьте одну строку в Вашем варианте, чтобы работало через cmd:
Код:
RunWait(@ComSpec & ' /c ' & $K & $Archivate & $K)
 
Автор
M

MON@H Rasta

[Ganj@ $moker]
Сообщения
12
Репутация
0
gora :beer:
Искренне благодарю! Всё заработало правильно.

Так же благодарю всех, кто откликнулся.

Подправил немного код, чтобы скрипт не удалял сам себя. Выкладываю, мож пригодится кому...

Код:
$K='"'
$DEL = "DEL /F /Q "
$7z = '7-Zip\7z.exe'
$ArchOptions = ' -mmt -ms=off'
$CurrentDir= @ScriptDir & '\'
$ProgramFilesDir = @ProgramFilesDir & '\'
$ArchiveName = '\/:*?"<>|'

$Search = FileFindFirstFile("*.*")

If $Search = -1 Then
	Exit
EndIf

While 1
	$File = FileFindNextFile($Search)

	If @error Or $File = "" Then
		ExitLoop
	ElseIf $File = @ScriptName Or $File = $ArchiveName Then
		$File = FileFindNextFile($Search)
		If @error Or $File = "" Then
			ExitLoop
		EndIf
	EndIf

	$ArchiveName = $File & '.7z'
	$Archivate = $K & $ProgramFilesDir & $7z & $K & ' a -mx9 ' & $K & $ArchiveName & $K & ' ' & $K & $File & $K & $ArchOptions

	Archivate($File)
WEnd

Func Archivate($File)
	RunWait(@ComSpec & ' /c ' & $K & $Archivate & $K, "", @SW_HIDE)
	RunWait(@ComSpec & ' /c ' & $DEL & $K & $CurrentDir & $File & $K, "", @SW_HIDE)
EndFunc

FileClose($Search)
 

gora

Знающий
Сообщения
315
Репутация
19
MON@H Rasta
1 Удаление без проверки корректного завершения процесса архивирования, шаг рискованный.
2 У меня на x64 путь к архиватору не совпадает с Вашим.
Попробуйте так:
Код:
#include <File.au3>

$CurrentDir= @ScriptDir
$ArchOptions = ' -mmt -ms=off'

$7z = StringReplace(RegRead('HKCU\Software\7-Zip','Path')&'\','\\','\') & '7z.exe'
$ver = StringReplace(FileGetVersion($7z),'.','')

If $ver > 92500 Then $ArchOptions &= ' -sdel'

$arrayFile=_FileListToArray($CurrentDir,'*',1)
If @Error Then Exit

For $a=1 To $arrayFile[0]
	If $arrayFile[$a] <> @ScriptName Then Archivate($arrayFile[$a])
Next

Func Archivate($File)
    $err = RunWait('"' & $7z & '" a -mx9 "' & $File & '.7z" "' & $File & '"' & $ArchOptions)
	If $err = 0 AND $ver <= 92500 Then FileDelete($File)
EndFunc
 
Автор
M

MON@H Rasta

[Ganj@ $moker]
Сообщения
12
Репутация
0
gora
Да, Ваш подход значительно "продвинутее" :smile:

Взял Ваш код за основу, немного подпилил, получилось очень даж. ничё так, как по мне 8)

"Финальная версия" на текущий момент такая:
Код:
#include <File.au3>

$CurrentDir= @ScriptDir
$ArchOptions = ' -mmt -ms=off'
$7z = StringReplace(RegRead('HKLM\Software\7-Zip','Path')&'\','\\','\') & '7z.exe'
If $7z = "\7z.exe" Then	$7z = StringReplace(RegRead('HKLM64\Software\7-Zip','Path')&'\','\\','\') & '7z.exe'

$ver = StringReplace(FileGetVersion($7z),'.','')
If $ver > 92500 Then $ArchOptions &= ' -sdel'

$arrayFile=_FileListToArray($CurrentDir,'*',1)
If @Error Then Exit

For $a=1 To $arrayFile[0]
	If $arrayFile[$a] <> @ScriptName AND _FileGetExt($arrayFile[$a]) <> ".7z" Then _Archivate($arrayFile[$a])
Next

Func _FileGetExt($sPath)
	Local $NULL, $sExt
	_PathSplit($sPath, $NULL, $NULL, $NULL, $sExt)
	Return $sExt
EndFunc

Func _Archivate($File)
    $err = RunWait('"' & $7z & '" a -mx9 "' & $File & '.7z" "' & $File & '"' & $ArchOptions)
    If $err = 0 AND $ver <= 92500 Then FileDelete($File)
EndFunc
можно компилить как x86 так и x64.
 
Верх