Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] архивация файлов, выбраных в ListBox (http://forum.oszone.net/showthread.php?t=217761)

camope3 12-10-2011 11:44 1771656

архивация файлов, выбраных в ListBox
 
Доброго времени суток уважаемые форумчане. Помогите решить проблему:

Есть процедура для архивации файлов средствами 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 1771770

надо сперва объединить выбранные в ListBox файлы в строку через пробел

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

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

LilLoco 12-10-2011 14:22 1771777

Цитата:

Цитата camope3
Вроде как и не логично "запихивать" в архив по одному файлу но другого ниче в голову не пришло. »

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

Цитата:

Цитата Справка 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
Файлы для архивации можно также перечислить не в командной строке, а в текстовом файле. В этом случае в командной строке необходимо указать имя этого файла, причём перед ним должен стоять символ @.
WinRAR A TOOLS.ZIP @Binaries

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

camope3 12-10-2011 17:44 1771920

Благодарю всех откликнувшихся. 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 1775348

Доброго времени! Возвращаюсь обратно к созданой теме.

Работает все нормально НО, если архивирую больше трех файлов выскакивает вся та же ошибка, отчет из лога 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 1775405

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

camope3 18-10-2011 00:22 1775754

Цитата:

Цитата Iska
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 1775810

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 1776143

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 1776263

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 1776359

Цитата:

Цитата Iska
camope3: во-первых, Вы напутали с количеством скобок и кавычками: »

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

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

Iska 19-10-2011 01:27 1776531

Цитата:

Цитата camope3
в названии директории, где размещался екзешник присутствовал пробел что сбило меня с толку и заставило отписаться выше. »

Пробельные символы в пути обычно требуют обрамления пути двойными кавычками.


Время: 16:01.

Время: 16:01.
© OSzone.net 2001-