запрос на распаковку в архивный плагин

Только для тех, кто пишет плагины под Total Commander. Обмен опытом, решение проблем.

Модераторы: d-view, Моторокер, Avada, CaptainFlint, Nik

Ответить
vx2
Сообщения: 9
Зарегистрирован: Пт июл 09, 2010 16:58

запрос на распаковку в архивный плагин

Сообщение vx2 »

vb6 (не надо смеяться/плакать). вопрос немного "обратный" разделу но... проблема такая:
рисую програмулину, которая использует один из архивных плагинов тотал коммандера (в тотале плагин работает на ура).
архив читать научился, все нормально, список файлов выдает. проблема при попытке распаковать файлы. код:

Код: Выделить всё

Public ArcName As String ' задается при первом открытии архива в виде полного пути с именем до него

Function ExtractDir(ByVal eDir As String, ByVal dDir As String) As Boolean
 'dDir="C:\папка\папка"
 Dim opnArcData As TOpenArchiveData
 Dim hArcData As Long
 Dim HeaderData As tHeaderData
 
 opnArcData.ArcName = ArcName
 opnArcData.OpenMode = PK_OM_EXTRACT
 hArcData = OpenArchive(opnArcData)
 Do Until ReadHeader(hArcData, HeaderData) = E_END_ARCHIVE
  If [надо-ли файл распаковать] Then
   ProcessFile hArcData, PK_EXTRACT, vbNullString, dDir & "\" & HeaderData.FileName
   'четвертым параметром (DestName) пробовал просто "HeaderData.FileName" и еще так:
   'dDir & "\" & Left(HeaderData.FileName, InStr(1, HeaderData.FileName, Chr(0)) - 1)
  Else
   ProcessFile hArcData, PK_SKIP, vbNullString, vbNullString
  End If
 Loop
 CloseArchive hArcData
End Function
полный путь до конечного файла существует. сама функция ProcessFile выдает либо 16 ошибку (невозможно создать файл), либо файл распаковывает, но в папку проекта с корявым именем без расширения.
что именно и в каком виде должно отдаваться в DestName для нормальной работы?
Аватара пользователя
MVV
Сообщения: 4815
Зарегистрирован: Чт окт 15, 2009 10:58
Откуда: Ростов-Дон

Сообщение MVV »

А если попробовать добавить символ с кодом 0 в конец строки, передаваемой функции? Я не работал с убейсиком, и лень гуглить, но если его строки не содержат в конце нулевого байта, это будет приводить к непредсказуемым результатам.

А вообще, отвечая на конкретный вопрос, согласно документации по WCX:
Unlike PackFiles, ProcessFile is passed only one filename. Either DestName contains the full path and file name and DestPath is NULL, or DestName contains only the file name and DestPath the file path. This is done for compatibility with unrar.dll.
То есть,
В отличие от функции PackFiles, функция ProcessFile вызывается для каждого отдельного файла. Либо DestName содержит полный путь к файлу, а DestPath равен NULL, либо DestName содержит только имя файла, а DestPath - путь к нему. Это сделано для совместимости с unrar.dll.
vx2
Сообщения: 9
Зарегистрирован: Пт июл 09, 2010 16:58

Сообщение vx2 »

это-то я читал, просто думал может что-то не так понял...

хм. про ноль в конце я как-то не подумал... попробую в понедельник (все файлы на работе остались).
только вот теоретически, если расписать написанное в четвертом параметре:

Код: Выделить всё

dDir & "\" & HeaderData.FileName
:

Код: Выделить всё

dDir = "C:\dir\dir" 'длина = len(dDir)
HeaderData.FileName = "adir\adir\afile.ext" & chr(0) & ... 'длина = 260 байт
'получаем:
dDir & "\" & HeaderData.FileName = "C:\dir\dir\adir\adir\afile.ext" & chr(0) & ... 'длина = len(dDir) + 1 + 260 
по сути, это полный путь до файла с нулем на конце "полезной" строки, только вот "размер" может как-то сказываться...
вообще подозрения витали где-то на уровне кодировки, хотя опять непонятно, почему тогда получение информации по архивным файлам (пути с именами файлов в частности) проходят без проблем...

в любом случае спасибо за ответ, опробую в понедельник, отпишусь.
Аватара пользователя
Volniy
Сообщения: 585
Зарегистрирован: Ср дек 15, 2004 00:17
Откуда: Местный

Сообщение Volniy »

Не заморачивайся ты с этим дополнительным нулем в конце строк, будет там нуль (FileName As String * 260 у тебя в THeaderData?). Где-то, я думаю, у тебя ошибка в декларации функции, скорее всего ByVal пропустил. Я вот сейчас у себя попробовал и у меня все нормально распаковывается. Попробуй вот такое декларирование в модуле:

Код: Выделить всё

Private Declare Function ProcessFile& Lib "test.wcx" (ByVal hArcData&, ByVal Operation&, ByVal DestPath$, ByVal DestName$)
Соответственно, вызов делаем так:

Код: Выделить всё

ProcessFile(hArcData, PK_EXTRACT, vbNullString, eDir & "\" & HeaderData.FileName)
vx2
Сообщения: 9
Зарегистрирован: Пт июл 09, 2010 16:58

Сообщение vx2 »

о, и правда ByVal на два последних пораметра помог)) ни когда-бы на них не подумал. спасибо большое х))
Аватара пользователя
Volniy
Сообщения: 585
Зарегистрирован: Ср дек 15, 2004 00:17
Откуда: Местный

Сообщение Volniy »

vx2 писал(а):ни когда-бы на них не подумал
Ты шутишь? Передача строк через ByVal в API функцию в VB имеет абсолютно магический смысл. На самом деле при этом происходит хитрая цепочка действий: сначала конвертация внутренней бейсиковской юникод-строки в нультерминованную ANSI строку и передача ее в API-функцию, затем возвращенный результат обратно конвертируется во внутреннюю юникодную строку VB. "Вот такая вот загогулина" (с). Короче, без ByVal тут никак не обойтись.

Вот тут есть инфа на эту тему.
Ответить