Войти

Показать полную графическую версию : [решено] архивация файлов, выбраных в ListBox


camope3
12-10-2011, 11:44
Доброго времени суток уважаемые форумчане. Помогите решить проблему:

Есть процедура для архивации файлов средствами ShellApi:
...
procedure PackFile(ArcName, FileName: string);
var
s: string;
begin
s := 'a -dh -ep ' + ArcName + ' ' + FileName;
ShellExecute(0, nil, 'winrar', PChar(s), nil, SW_SHOWNA);
end;
...

Есть ListBox, в который добавляются файлы для архивации
Есть обработчик событий:
...
procedure TfMore.Button3Click(Sender: TObject);
var
a:Byte;
begin
for a:= 0 to ListBox1.Items.Count - 1 do begin
PackFile('d:\Arhive\123456.rar', ListBox1.Items.Strings[a]);
end;
end;
...
Так вот в чем обстоит проблема: Если в "боксе" выбран один файл то естественно проблем нету. Если выбраны 2 и больше, а их нужно запаковать в один архив, WinRar начинает "ругаться" Процесс не может получить доступ к Файлу, так как зтот Файл занят другим процессом. WinRar не успел еще заархивировать первый файл как программа "подсовывает" ему следующий.

Можно ли как то решить этот вопрос по работе приведенной выше процедуры или может есть совет по иному способу архивации?
Заранее благодарен.
p.s. Вроде как и не логично "запихивать" в архив по одному файлу но другого ниче в голову не пришло.

ferget
12-10-2011, 14:15
надо сперва объединить выбранные в ListBox файлы в строку через пробел

а затем эту строку подставить в PackFile()

P.S. список передается через пробел

LilLoco
12-10-2011, 14:22
Вроде как и не логично "запихивать" в архив по одному файлу но другого ниче в голову не пришло. »

В WinRar можно упаковывать сразу целым списком файлов в один архив.

Общий синтаксис командной строки для архивации файлов таков:
WinRAR A [-ключи ] <Архив> [ Файлы ] [ @Файлы-списки ]

То есть вам нужно в цикле прохождения по выделенным итемам сформировать список файлов:

symbol = ' ';// символ для отделения файлов ( пробел )
for a:= 0 to ListBox1.Items.Count - 1 do begin
files = files + ListBox1.Items.Strings[a] + symbol; // хранит строку списка файлов
end;
PackFile('d:\Arhive\123456.rar', files); // вызываем один раз архивацию


Либо так:

Файлы для архивации можно также перечислить не в командной строке, а в текстовом файле. В этом случае в командной строке необходимо указать имя этого файла, причём перед ним должен стоять символ @.
WinRAR A TOOLS.ZIP @Binaries

Ну тут так же в цикле формируем файл со списком, ну а далее его передаем как параметр для архивации.

camope3
12-10-2011, 17:44
Благодарю всех откликнувшихся. LilLoco Немножко подправил Ваш код:
...
procedure TfMore.Button3Click(Sender: TObject);
var
a:Byte;
symbol,files:string;
begin
symbol:=' ';//здесь символ разделителя пробел
for a:= 0 to ListBox1.Items.Count - 1 do begin
files := files + ListBox1.Items.Strings[a] + symbol;
PackFile('d:\Arhive\123456.rar', files);
end;
end;
...
и все работает.
Еще раз всем спасибо!

camope3
17-10-2011, 16:23
Доброго времени! Возвращаюсь обратно к созданой теме.

Работает все нормально НО, если архивирую больше трех файлов выскакивает вся та же ошибка, отчет из лога WinRar:
17.10.2011 15:16:16 Невозможно открыть d:\Arhive\123456.rar
17.10.2011 15:16:16 Процесс не может получить доступ к файлу, так как этот файл занят другим процессом. причем файлы успешно упаковываются.

проблему "решил" отключив отчет об ошибках
s := 'a -inul -ilog.\ErrRar.txt -dh -ep -m5 ' + ArcName + ' ' + FileName;
ShellExecute(0, nil, 'winrar', PChar(s), nil, SW_SHOWNA);

Но все же не могу понять что не так. Именно до трех файлов пакует без ошибки, более трех с ошибкой но все равно пакует. Перепробовал разные манипуляции с ключами WinRar не помогло.

Iska
17-10-2011, 17:35
camope3, Вы всё же стали паковать файлы по-отдельности, а не списком?

camope3
18-10-2011, 00:22
camope3, Вы всё же стали паковать файлы по-отдельности, а не списком? »

Если я правильно Вас понял то, мне нужно добавить символ @ перед именем списка либо здесь:
PackFile('d:\Arhive\123456.rar', files); перед files

либо в процедуре
s := 'a -ilog.\ErrWinRar.txt -dh -ep -m5 ' + ArcName + ' ' + FileName; перед FileName???

но тогда WinRar снова выдает ошибку:
17.10.2011 22:27:11 Невозможно открыть d:\Arhive\123.doc d:\Arhive\122.doc
17.10.2011 22:27:11 Синтаксическая ошибка в имени файла, имени папки или метке тома.

Не могу додуматься никак, что к чему, помогите будьте добры.

p.s. Начал извращаться дальше, выгрузил список в файл spis.txt
написал батник
D:
cd d:\Arhive\
"c:\Program Files (x86)\WinRAR\WinRaR.exe" a -dh -ep 123456.rar @spis.txt
WinRaR упорно выдает ошибку
Синтаксическая ошибка в имени файла, имени папки или метке тома

текст файла spis.txt:
d:\Arhive\111.doc d:\Arhive\122.doc d:\Arhive\123.doc
Проверил - разделители пробелы. Выкидываю из списка 2 файла, оставляю один - архивирует.
Я уже и незнаю где, что и как искать, просто замкнутый круг какой то :(

Iska
18-10-2011, 02:53
camope3, попробуйте привести весь получившийся итоговый код, относящийся к формированию перечня файлов и упаковке файлов.

Список Вы формировали именно так:
Файл-список

Файлы-списки - это обычные текстовые файлы, содержащие имена файлов для обработки. Каждое имя файла должно быть указано на отдельной строке и начинаться с первой позиции строки. В файл-список допускается помещать комментарии, признак начала комментария - символы //. Например, для архивирования файлов *.txt из папки c:\work\doc, файлов *.bmp из папки c:\work\image и всех файлов из папки c:\work\misc можно создать backup.lst, содержащий следующие строки:
c:\work\doc\*.txt//резервная копия текстов

c:\work\image\*.bmp//резервная копия рисунков

c:\work\misc

После этого для архивирования достаточно будет выполнить команду:

winrar a backup @backup.lst

В одной командной строке разрешается указывать как обычные имена или группы файлов для обработки, так и файлы-списки. Если не указаны ни файлы, ни файлы-списки, то подразумевается шаблон *.* (т.е. WinRAR обработает все файлы).

camope3
18-10-2011, 15:19
Iska Спасибо!
....
ListBox1.Items.SaveToFile('spis.lst');
PackFile('d:\Arhive\123456.rar', '@spis.lst');
....

Все работает но как то немного не красиво. Файл список создается в той директории откуда выбираются файлы (файлы выбираются через Open.Execute) ,если же привязать к определенному пути скажем к папке с установленой прграммой тогда не работает.

ListBox1.Items.SaveToFile(ExtractFilePath(Application.ExeName) + 'spis.lst' //сохраняет файл список в директории с программой
PackFile (d:\Arhive\123456.rar,(ExtractFilePath(Application.ExeName)+'@spis.lst'); //выдает ошибку

Iska
18-10-2011, 18:06
camope3: во-первых, Вы напутали с количеством скобок и кавычками:
PackFile (d:\Arhive\123456.rar,(ExtractFilePath(Application.ExeName)+'@spis.lst');
во-вторых, попробуйте так (и убедитесь, что «\» правильно в итоге будут расставлены):
PackFile ('d:\Arhive\123456.rar', '@'+ExtractFilePath(Application.ExeName)+'spis.lst');
Вообще-то правильно будет получить незанятое имя во временной папке пользователя, создать файл-список там, подставлять его в командную строку архиватора с полным путём.

camope3
18-10-2011, 20:37
camope3: во-первых, Вы напутали с количеством скобок и кавычками: »

Прошу прощения, действительно напутал. Указаный Вами вариант был ранее опробован, но не дал результатов, потому как в названии директории, где размещался екзешник присутствовал пробел что сбило меня с толку и заставило отписаться выше.

Iska Еще раз спасибо Вам огромное за уделенное мне время.

Iska
19-10-2011, 01:27
в названии директории, где размещался екзешник присутствовал пробел что сбило меня с толку и заставило отписаться выше. »
Пробельные символы в пути обычно требуют обрамления пути двойными кавычками.




© OSzone.net 2001-2012