Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/1: Рейтинг темы: голосов - 1, средняя оценка - 5.00
1399 / 857 / 92
Регистрация: 08.02.2017
Сообщений: 3,638
Записей в блоге: 2

Работа с zip архивами

29.10.2024, 02:49. Показов 19698. Ответов 283
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Из всего, что попадалось по теме сжатия/распаковки ZIP наиболее интересные были примеры с использованием библиотеки Zlib. Оригинальная zlib использует cdecl экспорт функций, но есть реализация zlibwapi.dll, которую можно использовать в VB. Вот хороший пример использования. Там можно увидеть как сжть/распаковать массив байтов, но вот беда, очень сложно найти пример под VB с более обширным использованием, способной на большее, данной либы, которая не есть простая, там есть функции с использованием множества параметров констант и длинных структур, которые чтобы узнать наверное надо долго копатся в сишных заголочниках. Но HackerVlad в личной беседе говорил, что у него есть исходники с использованием данной библиотеки, поэтому любезно прошу его поделиться данной информацией.

Добавлено через 1 минуту
кстати словосочетание zip-архивами в названии форум блочит почему-то )

Добавлено через 6 минут
На одном форуме есть хороший пример испльзования функций zlib для извлечения/распаковки отдельных файлов, там
Кликните здесь для просмотра всего текста
обсуждался какой-то экзотический ЯП Clarion, но очень наглядно
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
! Источнег: https://forum.clarionlife.net/viewtopic.php?t=2389
! Для добавления в архив PwlZip ваш пароль
ZipHandle = zipOpen(NEW_ZIPPACK, 0)
If EncryptFlag = 1
Res# = zipOpenNewFileInZip3(ZipHandle, PATH_CURZIP, Zinfo, 0, 0, 0, 0, Comment, Z_DEFLATED, CompressionFlag,0,-15,8,0,PwlZip,0)
Else
Res# = zipOpenNewFileInZip(ZipHandle, PATH_CURZIP, Zinfo, 0, 0, 0, 0, Comment, Z_DEFLATED, CompressionFlag)
.
 
!Для чтения из архива
ZipHandle = unzOpen(PATH_INFILE_PACK)
LocRes1=UnzGoToFirstFile(ZipHandle)
If unzGetCurrentFileInfo(ZipHandle,FinFo,PATH_NAMEUPD_TMP,Size(PATH_NAMEUPD_TMP),0,0,Comment,Size(Comment)).
If FinFo.Flag = 3 !признак шифрованного zip по крайней мере так я понял после мыкания с архивами
LocRes2 = unzOpenCurrentFilePassword(ZipHandle,PwlZip)
Else
LocRes2 = UnzOpenCurrentFile(ZipHandle)

Здесь подробное описание функций, структур и констант, однако я не нашел там unzGetCurrentFileInfo и т.п.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.10.2024, 02:49
Ответы с готовыми решениями:

Работа с ZIP-архивами - распаковка файлов
Привет, уважаемый ALL! Подскажите, как можно работать с zip архивами из VBA? Стоит задача: 1) прочитать из архива...

Автоматизировать заполнение "Графика выполненных работ по месяцам"
Используя готовую рабочую книгу Blank1.xls, автоматизировать заполнение "Графика выполненных работ по месяцам". Из диапазона дат в...

Задания из лаб.работ
Надоедаю наверное уже всем...

283
1399 / 857 / 92
Регистрация: 08.02.2017
Сообщений: 3,638
Записей в блоге: 2
05.11.2024, 18:13  [ТС]
Студворк — интернет-сервис помощи студентам
GetLastError возвращает код ошибки 13, надо смотреть, как получить описание ошибки
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
05.11.2024, 18:31
testuser2, скорее всего существует жёсткое ограничение, например 30 там мегабайт или сколько, но я нашёл флаг DELTA_FLAG_IGNORE_OPTIONS_SIZE_LIMIT (Разрешить буферу параметров или файлам превышать ограничение по размеру по умолчанию.) может его попробовать

Добавлено через 36 секунд
То есть существует "ограничение по размеру по умолчанию" понимаешь

Добавлено через 11 минут
Давай попробуем? DELTA_FLAG_IGNORE_OPTIONS_SIZE_LIMIT = (0x00040000)
1
1399 / 857 / 92
Регистрация: 08.02.2017
Сообщений: 3,638
Записей в блоге: 2
05.11.2024, 18:41  [ТС]
Да флаг сработал
Code
1
2
Размер файла:   71320546 
DeltaB:         6490422  67,5
Private Const DELTA_FLAG_IGNORE_FILE_SIZE_LIMIT@ = 131072 / 10000 '&H20000
Вызов функции:
Visual Basic
1
ret = CreateDeltaB(SetFlags:=DELTA_FLAG_IGNORE_FILE_SIZE_LIMIT, Trg_lpcStart:=bInp(0), Trg_uSize:=UBound(bInp) + 1, TrgOpt_Editable:=1, lpDelta:=DO_Res)
Добавлено через 3 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
TrgOpt_Editable:=1
можно не ставить, это просто разрешение использования функцией входного буфера для своей работы

Добавлено через 3 минуты
Code
1
2
Размер файла:   71320546 
Cabinet (LZMS): 9830436  21,375
1
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
05.11.2024, 18:41
Флаг-то сработал, я верно угадал значит, прочитав документацию, но вот скорость разочаровала

Упаковка 40 Мб: 23 секунды! жесть как медленно! Зато на выходе получилось всего 2 Мб! Сжало аж в 20 раз!
Распаковка обратно занимает 312 млск терпимо ещё кстати.
0
1399 / 857 / 92
Регистрация: 08.02.2017
Сообщений: 3,638
Записей в блоге: 2
05.11.2024, 18:44  [ТС]
У меня файл 68 мб сжался до 6,2 мб, кабом до 9,4 мб
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
05.11.2024, 21:48
testuser2, лучше чем CAB значит? а по скоростям что у тебя? отвратительно медленно сжимает тоже?
ну главное хотябы чтобы распаковка была более-ни-менее быстрой...

Добавлено через 59 минут
testuser2, у тебя кстати грамотическая ошибка в слове "Разкомментировать" правописание приставки рас, раз забыл из школьной программы что ли, рас пишется с глухими, раз с звонкими

Добавлено через 15 минут
Цитата Сообщение от testuser2 Посмотреть сообщение
Компрессия/декомпрессия буфера DeltaB
В твоём коде, после функции ApplyDeltaB не вызывается DeltaFree, согласно документации MSDN это так же необходимо и после распаковки.

Из документации:

Функция DeltaFree

Освобождает указанный блок памяти. Эту функцию необходимо вызвать после успешных вызовов CreateDeltaB и ApplyDeltaB , чтобы освободить буфер памяти, выделенный MSDelta.

Добавлено через 5 минут
testuser2, навёл красоту, вот окончательный вариант модуля:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Option Explicit
'////////////////////////////////////////////////////////////////////////////////////
'// Модуль для упаковки и распаковки буфера с помощью технологии Delta Compression //
'// Copyright (c) 05.11.2024 by HackerVlad & testuser2                             //
'// E-mail: vladislavpeshkov@yandex.ru                                             //
'// Обсуждение темы: https://www.cyberforum.ru/visual-basic/thread3183774.html     //
'// Версия: 1.0                                                                    //
'////////////////////////////////////////////////////////////////////////////////////
 
Private Const DELTA_FILE_TYPE_RAW@ = 1 / 10000
Private Const DELTA_FLAG_IGNORE_FILE_SIZE_LIMIT@ = 131072 / 10000 ' &H20000 (0x00020000)
 
Private Declare Function CreateDeltaB Lib "msdelta" (Optional ByVal FileTypeSet As Currency = DELTA_FILE_TYPE_RAW, Optional ByVal SetFlags As Currency, Optional ByVal ResetFlags As Currency, Optional ByVal Src_lpcStart As LongPtr, Optional ByVal Src_uSize As LongPtr, Optional ByVal Src_Editable As Long, Optional ByRef Trg_lpcStart As Any, Optional ByVal Trg_uSize As LongPtr, Optional ByVal Trg_Editable As Long, Optional ByVal SrcOpt_lpcStart As LongPtr, Optional ByVal SrcOpt_uSize As LongPtr, Optional ByVal SrcOpt_Editable As Long, Optional ByVal TrgOpt_lpcStart As LongPtr, Optional ByVal TrgOpt_uSize As LongPtr, Optional ByVal TrgOpt_Editable As Long, Optional ByVal GlbOpt_lpcStart As LongPtr, Optional ByVal GlbOpt_uSize As LongPtr, Optional ByVal GlbOpt_Editable As Long, Optional ByVal lpTargetFileTime As LongPtr, Optional ByVal HashAlgId As Long, Optional ByRef lpDelta As Any) As Long
Private Declare Function ApplyDeltaB Lib "msdelta" (ByVal ApplyFlags As Currency, ByVal Src_lpcStart As LongPtr, ByVal Src_uSize As LongPtr, ByVal Src_Editable As Long, ByRef Dlt_lpcStart As Any, ByVal Dlt_uSize As LongPtr, ByVal Dlt_Editable As Long, ByRef lpTarget As DELTA_OUTPUT) As Long
Private Declare Function DeltaFree Lib "msdelta" (ByVal lpMemory As LongPtr) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
 
'## Раскомментировать в VB6 ##
Private Enum LongPtr
    [_]
End Enum
'#############################
 
Private Type DELTA_OUTPUT
    lpStart As LongPtr
    uSize As LongPtr
End Type
 
' Упаковать (сжать) данные байтового массива
Public Function CompressDeltaB(byteArray() As Byte) As Boolean
    On Error GoTo Quit
    
    Dim DO_Res As DELTA_OUTPUT
    Dim ret As Long
    
    ret = CreateDeltaB(SetFlags:=DELTA_FLAG_IGNORE_FILE_SIZE_LIMIT, Trg_lpcStart:=byteArray(0), Trg_uSize:=UBound(byteArray) + 1, lpDelta:=DO_Res)
    
    If ret Then
        With DO_Res
            ReDim byteArray(.uSize - 1)
            CopyMemory byteArray(0), ByVal .lpStart, .uSize
            DeltaFree (.lpStart)
        End With
        
        CompressDeltaB = True
    End If
Quit:
End Function
 
' Распаковать (извлечь) данные байтового массива
Public Function DeCompressDeltaB(byteArray() As Byte) As Boolean
    On Error GoTo Quit
    
    Dim DO_Res As DELTA_OUTPUT
    Dim ret As Long
    
    ret = ApplyDeltaB(0, 0, 0, 0, byteArray(0), UBound(byteArray) + 1, 0, DO_Res)
    
    If ret Then
        With DO_Res
            If .lpStart Then
                ReDim byteArray(.uSize - 1)
                CopyMemory byteArray(0), ByVal .lpStart, .uSize
                DeltaFree (.lpStart)
            End If
        End With
        
        DeCompressDeltaB = True
    End If
Quit:
End Function
Добавлено через 47 минут
testuser2, выложил все труды в готовых решениях: Готовые решения и полезные коды на Visual Basic 6.0

Добавлено через 55 минут
testuser2, пытался сделать программу сейчас для извлечения из ресурсов буфера и распаковки для создания DLL но почему-то не работает, в IDE работает через F5 а вот в EXE не работает, ничего не могу понять, в полном шоке вообще, когда другая моя EXE работает прекрасно, это очень странно. Выскакивает ошибка 13. Что значит 13 ошибка, ты смотрел коды ошибок? В EXE только что самое смешное идёт Err.LastDllError будет 13 ничего не понимаю пока
1
Эксперт по электронике
6875 / 3298 / 340
Регистрация: 28.10.2011
Сообщений: 12,933
Записей в блоге: 7
05.11.2024, 22:16
Цитата Сообщение от HackerVlad Посмотреть сообщение
Что значит 13 ошибка
Если GetLastError() то
Недопустимые данные.
2
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
06.11.2024, 01:00
Было очень сложно конечно разбираться с моей ошибкой этой, особенно когда работало в IDE но не работало в EXE (ненавижу такие чудеса, сложно понять что к чему) технология моя неправильная короче. Буду переделывать модуль.

Добавлено через 8 минут
Какой-то глюк с ресурсами есть в VB6

Добавлено через 2 минуты
Так что может моя технология и правильная а вот что там за баг с ресурсами в VB6 это уже другое

Добавлено через 5 минут
Я вспомнил, мне и The Trick говорил, что в VB6 есть баг при компиляции EXE связанный с ресурсами там в конце ресурсов иногда почему пару байт каки-то зачем-то добавляется

Добавлено через 38 секунд
Зато я наконец-то понял почему у меня не работает в EXE, но работает в IDE VB6

Добавлено через 9 минут
По моему The Trick даже говорил, что нужно поставить SP6 тогда там этот глюк исправлен, а у меня SP5 стоит

Добавлено через 1 минуту
Суть в том что VB6 SP5 получается иногда изменяет данные в ресурсах в EXE - добавляет в конец лишние байты, это может быть один или два байта, или три или четыре лишних байта, это очень странно но это баг VB6 а не мой баг, а я целый час голову ломал думая почему у меня не работает мой модуль.

Добавлено через 1 минуту
Решение тут только одно буду отсекать лишние байты на конце, раз VB6 не умеет нормально компилировать EXE с ресурсами.

Добавлено через 57 минут
В моём проекте под названием "zlibwapi.dll from resources v.2" там тоже создан EXE с лишним одним байтом на конце, самое смешное, что там мы успешно скормили этот буфер NT-функциям и всё нормально было, функция RtlDecompressBuffer успешно схавала немного неправильный буфер (с лишним одним байтом на конце) и успешно вернуло идеально-правильный буфер, что самое смешное. А вот с дельта-функциями такое уже не пройдёт. Там требует идеально-правильный буфер изначально, иначе ошибка номер 13.

Добавлено через 1 час 0 минут
Ещё меня очень сильно удивило, что если создавать сжатые буфера из одного и того же файла с помощью CompressDeltaB то они всё время разные данные получаются... Из-за чего страдает CRC. 4 байта каких-то всё время отличаются. Неужели туда время записывается каждый раз новое, прям в буфер вшивается.
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
06.11.2024, 01:24
Ну наконец-таки, я сделал третью версию программки, для создания DLL из ресурсов.
Пришлось через CopyMemory насильно обрезать три байта в конце. Извините, это глюк майкрософта уже, я тут не при чём.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Option Explicit
Private Declare Function RtlComputeCrc32 Lib "ntdll.dll" (ByVal dwInitial As Long, ByVal pData As Long, ByVal iLen As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetTickCount Lib "kernel32" () As Long
 
Private Function Crc32Api(tBuff() As Byte) As Long
    Crc32Api = RtlComputeCrc32(0, VarPtr(tBuff(0)), UBound(tBuff) + 1)
End Function
 
Private Function CreatingDLL() As Boolean
    Dim FileNo As Integer
    Dim buf() As Byte
    Dim dll() As Byte
    
    buf = LoadResData(101, "DELTA") ' Загружаем буфер из ресурсов
    
    ReDim dll(88620)
    CopyMemory dll(0), buf(0), 88621 ' Копируем только 88621 байт
    
    If Crc32Api(dll) = &HF0E81CB6 Then ' Проверить CRC сжатого буфера
        If DeCompressDeltaB(dll) = True Then ' Распаковать буфер
            If Crc32Api(dll) = &HD3B58EB5 Then ' Проверить CRC распакованного буфера
                If UBound(dll) = 171007 Then ' Совпадает количество байт
                    On Error Resume Next
                    
                    Err.Clear
                    FileNo = FreeFile
                    
                    Open App.Path + "\zlibwapi.dll" For Binary As FileNo
                        Put #FileNo, , dll
                    Close FileNo
                    
                    If Err.Number = 0 Then CreatingDLL = True
                End If
            End If
        End If
    End If
End Function
 
Private Sub Command1_Click()
    Dim tick As Long
    Dim result As Boolean
    
    If IsDLLFunction("zlibwapi.dll", "zlibVersion") = False Then ' Не найдена библиотека либо функция в библиотеке
        tick = GetTickCount
        result = CreatingDLL ' Создать DLL
        Print GetTickCount - tick & " ml" ' Измерить время (у меня 0 млск)
        
        MsgBox "Создание библиотеки: " & result
    End If
End Sub
Теперь здесь в этом новом проекте размер EXE-файла уже всего 114Кб, не так уж и много, учитывая что мы вшиваем во внутрь DLL-библиотеку на 171Кб...
Вложения
Тип файла: zip zlibwapi.dll from resources v.3.zip (183.3 Кб, 4 просмотров)
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
06.11.2024, 01:50
А теперь вишинка на торте. Написал мини-версию этой программы для создания DLL. Здесь мы будем использовать чуть-чуть более старую версию DLL-библиотеки, которая занимаем всего 74Кб, версия 1.2.3, вместо 1.2.8, поэтому на выходе EXE теперь у нас получается всего 65536 байт! 65Кб! Это рекорд минимального размера EXE! Так как тут запакованный буфер занимает всего 39670 байт. Все контрольные суммы CRC32, мы конечно же, проверяем обязательно, чтобы исключить ошибки потери каких-то байтов. Мне итак приходится заниматься копированием через CopyMemory, ну а что поделаешь.. Ладно, вот новый код.

Код формы:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Option Explicit
Private Declare Function RtlComputeCrc32 Lib "ntdll.dll" (ByVal dwInitial As Long, ByVal pData As Long, ByVal iLen As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetTickCount Lib "kernel32" () As Long
 
Private Function Crc32Api(tBuff() As Byte) As Long
    Crc32Api = RtlComputeCrc32(0, VarPtr(tBuff(0)), UBound(tBuff) + 1)
End Function
 
Private Function CreatingDLL() As Boolean
    Dim FileNo As Integer
    Dim buf() As Byte
    Dim dll() As Byte
    
    buf = LoadResData(101, "DELTA") ' Загружаем буфер из ресурсов
    
    ReDim dll(39669)
    CopyMemory dll(0), buf(0), 39670 ' Копируем только 39670 байт
    
    If Crc32Api(dll) = &H4039D04F Then ' Проверить CRC сжатого буфера
        If DeCompressDeltaB(dll) = True Then ' Распаковать буфер
            If Crc32Api(dll) = &H5146E353 Then ' Проверить CRC распакованного буфера
                On Error Resume Next
                
                Err.Clear
                FileNo = FreeFile
                
                Open App.Path + "\zlibwapi.dll" For Binary As FileNo
                    Put #FileNo, , dll
                Close FileNo
                
                If Err.Number = 0 Then CreatingDLL = True
            End If
        End If
    End If
End Function
 
Private Sub Command1_Click()
    Dim tick As Long
    Dim result As Boolean
    
    ' Здесь производится поиск dll-библиотеки и в системных папках (C:\Windows\System32 и т. д.) и в папке с программой
    If IsDLLFunction("zlibwapi.dll", "zlibVersion") = False Then ' Не найдена библиотека либо функция в библиотеке
        tick = GetTickCount
        result = CreatingDLL ' Создать DLL
        Print GetTickCount - tick & " ml" ' Измерить время (у меня 0 млск)
        
        MsgBox "Создание библиотеки: " & result
    End If
End Sub
Проект в ZIP-архиве конечно же прилагается. Мини-версия.
Миниатюры
Работа с zip архивами  
Вложения
Тип файла: zip zlibwapi.dll from resources v.mini.zip (87.7 Кб, 5 просмотров)
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
06.11.2024, 02:17
А ещё можно знаешь как сделать? Можно например в папке вместе с программой распространять (копировать) самую новую библиотеку, а если этого файла вдруг не будет, то пусть тогда создаётся старая мини-версия 1.2.3 можно и так сделать, я только что подумал об этом. В любом случае в каталоге вместе с программой можно всегда распространять любую версию.

Добавлено через 30 секунд
А можно и не делать этого, уже всё равно. Тут на вкус и цвет как бы.

Добавлено через 56 секунд
Главная задача выполнена по упаковке и распаковке буферов. Кстати я заметил что дельты пакуют файлы даже лучше чем сам ZIP.

Добавлено через 24 секунды
Но тесты ещё можно проводить конечно.
0
1399 / 857 / 92
Регистрация: 08.02.2017
Сообщений: 3,638
Записей в блоге: 2
06.11.2024, 02:32  [ТС]
На x64 чудо-функции запустить не получилось. Не пойму почему. Там где Long, он автоматически должен выравниваться до LongLong хоть в структуре, хоть в стеке. Пока так.
Кликните здесь для просмотра всего текста
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Option Explicit
''##Разкомментировать в VB6 и удалить все PtrSafe##
'Private Enum LongPtr
'    [_]
'End Enum
''###########################
Enum DELTA_FLAG_TYPE
    DELTA_FLAG_NONE = 0
End Enum
Private Const DELTA_FILE_TYPE_RAW@ = 1 / 10000
Private Const DELTA_FILE_TYPE_SET_RAW_ONLY@ = DELTA_FILE_TYPE_RAW
Private Const DELTA_FLAG_IGNORE_FILE_SIZE_LIMIT@ = 131072 / 10000 '&H20000
Private Type DELTA_OUTPUT
    lpStart As LongPtr
    uSize As LongPtr
End Type
Private Declare PtrSafe Function CreateDeltaB Lib "msdelta" (Optional ByVal FileTypeSet As Currency = DELTA_FILE_TYPE_RAW, _
                                                     Optional ByVal SetFlags As Currency = DELTA_FLAG_IGNORE_FILE_SIZE_LIMIT, _
                                                     Optional ByVal ResetFlags As Currency, _
                                                     Optional ByVal Src_lpcStart As LongPtr, Optional ByVal Src_uSize As LongPtr, Optional ByVal Src_Editable As Long, _
                                                     Optional ByRef Trg_lpcStart As Any, Optional ByVal Trg_uSize As LongPtr, Optional ByVal Trg_Editable As Long, _
                                                     Optional ByVal SrcOpt_lpcStart As LongPtr, Optional ByVal SrcOpt_uSize As LongPtr, Optional ByVal SrcOpt_Editable As Long, _
                                                     Optional ByVal TrgOpt_lpcStart As LongPtr, Optional ByVal TrgOpt_uSize As LongPtr, Optional ByVal TrgOpt_Editable As Long, _
                                                     Optional ByVal GlbOpt_lpcStart As LongPtr, Optional ByVal GlbOpt_uSize As LongPtr, Optional ByVal GlbOpt_Editable As Long, _
                                                     Optional ByVal lpTargetFileTime As LongPtr, _
                                                     Optional ByVal HashAlgId As Long, _
                                                     Optional ByRef lpDelta As Any) As Long
Private Declare PtrSafe Function DeltaFree Lib "msdelta" (ByVal lpMemory As LongPtr) As Long
Private Declare PtrSafe Function ApplyDeltaB Lib "msdelta" (ByVal ApplyFlags As Currency, _
                                                     ByVal Src_lpcStart As LongPtr, ByVal Src_uSize As LongPtr, ByVal Src_Editable As Long, _
                                                     ByRef Dlt_lpcStart As Any, ByVal Dlt_uSize As LongPtr, ByVal Dlt_Editable As Long, _
                                                     ByRef lpTarget As DELTA_OUTPUT) As Long
Private Declare PtrSafe Function GetLastError Lib "kernel32.dll" () As Long
Private Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Dst As Any, Src As Any, ByVal Ln As LongPtr)
 
'В случае удачи функции возвращают ноль, если произошла ошибка, возвращается ответ функции GetLastError
Function CompressDeltaB(bInp() As Byte, bOut() As Byte, Optional ByVal EditableBuffer As Long) As Long
    Dim ret&, DO_Res As DELTA_OUTPUT
    
    ret = CreateDeltaB(Trg_lpcStart:=bInp(0), Trg_uSize:=UBound(bInp) + 1, TrgOpt_Editable:=EditableBuffer, lpDelta:=DO_Res)                                      'v3
    If ret Then
        With DO_Res
          ReDim bOut(CLng(.uSize - 1))
          CopyMemory bOut(0), ByVal .lpStart, .uSize
          DeltaFree (.lpStart)
        End With
    Else: CompressDeltaB = GetLastError()
    End If
End Function
Function DeCompressDeltaB(bInp() As Byte, bOut() As Byte, Optional ByVal EditableBuffer As Long) As Long
    Dim ret&, DO_Res As DELTA_OUTPUT
    
    ret = ApplyDeltaB(0, 0, 0, 0, bInp(0), UBound(bInp) + 1, EditableBuffer, DO_Res)
    If ret Then
        With DO_Res
          ReDim bOut(CLng(.uSize - 1))
          CopyMemory bOut(0), ByVal .lpStart, .uSize
          DeltaFree (.lpStart)
        End With
    Else: DeCompressDeltaB = GetLastError
    End If
End Function
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
06.11.2024, 02:45
Цитата Сообщение от testuser2 Посмотреть сообщение
В случае удачи функции возвращают ноль
Ты уверен? Я думал в случае удачи 1. Я помню что 0 у меня возвращало как раз в случае НЕудачи!

Добавлено через 2 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
CompressDeltaB = GetLastError()
Я тоже думал так делать кстати. Возвращать Long функции с кодом ошибки, но потом передумал ибо у меня ошибок теперь нет. И вместо GetLastError проще использовать Err.DllLastError
1
1399 / 857 / 92
Регистрация: 08.02.2017
Сообщений: 3,638
Записей в блоге: 2
06.11.2024, 02:45  [ТС]
Цитата Сообщение от HackerVlad Посмотреть сообщение
Ты уверен?
Также как в Minizip
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
06.11.2024, 02:49
Цитата Сообщение от testuser2 Посмотреть сообщение
Private Declare PtrSafe Function GetLastError Lib "kernel32.dll" () As Long
Объявлять тогда эту функцию не придётся. Я уже проверял. Работает возврат кода ошибки. Обычно это 13.

Добавлено через 1 минуту
Цитата Сообщение от testuser2 Посмотреть сообщение
Также как в Minizip
ААА понял ты про свою собственную функцию! а не про API'шную, да-да-да, я точно так же хотел делать!!!...

Добавлено через 1 минуту
Цитата Сообщение от testuser2 Посмотреть сообщение
DeltaFree (.lpStart)
Ещё хотел спросить зачем тут скобки? Я как дурак копировал твой код и у меня поэтому тоже скобки. Только потом понял что они так не к чему.

Добавлено через 55 секунд
Цитата Сообщение от testuser2 Посмотреть сообщение
x64
Это 64-битный офис твой?
0
1399 / 857 / 92
Регистрация: 08.02.2017
Сообщений: 3,638
Записей в блоге: 2
06.11.2024, 11:46  [ТС]
Vba x64. В данном случае проверял в Автокаде. Я примерно понимаю из-за чего не идет. Чуть позже, думаю будет решение для x64

Добавлено через 21 минуту
Ошибки можно по всякому выводить. Всегда есть вероятность порченного файла или еще чего. Лучше всего, наверное, когда функция сама определяет ошибку и еще выводит сообщение, чтобы не обрабатывать эту ошибку где-то во вне.

Добавлено через 4 часа 4 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
Чуть позже, думаю будет решение для x64
К сожалению этот вопрос пока остался загадкой

Добавлено через 2 минуты
На Твинбейсике, по моему, возможно передавать структуры ByVal.. Там должен работать этот вариант

Добавлено через 3 часа 50 минут
В TwinBasic увы:
TB5147: User defined types cannot be passed ByVal
No quick fixes available
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
06.11.2024, 15:34
Придумал новый вариант кода для моего проекта "zlibwapi.dll from resources v.mini". Теперь мы не будем использовать CopyMemory для отрезания последних байт. Я вспомнил, что это можно делать стандартными средствами на VB6 без API с помощью ReDim Preserve. Слово Preserve там обязательно, иначе не работает, если просто ReDim.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Option Explicit
Private Declare Function RtlComputeCrc32 Lib "ntdll.dll" (ByVal dwInitial As Long, ByVal pData As Long, ByVal iLen As Long) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
 
Private Function Crc32Api(tBuff() As Byte) As Long
    Crc32Api = RtlComputeCrc32(0, VarPtr(tBuff(0)), UBound(tBuff) + 1)
End Function
 
Private Function CreatingDLL() As Boolean
    Dim FileNo As Integer
    Dim buf() As Byte
    Dim dll() As Byte
    
    dll = LoadResData(101, "DELTA") ' Загружаем буфер из ресурсов
    ReDim Preserve dll(39669) ' Отрезать только 39670 байт (без Preserve не работает! сбвивается CRC)
    
    If Crc32Api(dll) = &H4039D04F Then ' Проверить CRC сжатого буфера
        If DeCompressDeltaB(dll) = True Then ' Распаковать буфер
            If Crc32Api(dll) = &H5146E353 Then ' Проверить CRC распакованного буфера
                On Error Resume Next
                
                Err.Clear
                FileNo = FreeFile
                
                Open App.Path + "\zlibwapi.dll" For Binary As FileNo
                    Put #FileNo, , dll
                Close FileNo
                
                If Err.Number = 0 Then CreatingDLL = True
            End If
        End If
    End If
End Function
 
Private Sub Command1_Click()
    Dim tick As Long
    Dim result As Boolean
    
    ' Здесь производится поиск dll-библиотеки и в системных папках (C:\Windows\System32 и т. д.) и в папке с программой
    If IsDLLFunction("zlibwapi.dll", "zlibVersion") = False Then ' Не найдена библиотека либо функция в библиотеке
        tick = GetTickCount
        result = CreatingDLL ' Создать DLL
        Print GetTickCount - tick & " ml" ' Измерить время (у меня 0 млск)
        
        MsgBox "Создание библиотеки: " & result
    End If
End Sub
Вложения
Тип файла: zip zlibwapi.dll from resources v.mini (2).zip (87.5 Кб, 2 просмотров)
1
1399 / 857 / 92
Регистрация: 08.02.2017
Сообщений: 3,638
Записей в блоге: 2
06.11.2024, 15:49  [ТС]
Цитата Сообщение от HackerVlad Посмотреть сообщение
IsDLLFunction
Небольшая ремарка, этой функции больше подходит название DllCheck или CheckDllExisting, IsDll это как если бы проверяло является ли объект DLL )
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,789
06.11.2024, 16:09
testuser2, эта функция проверяет существование функции внутри библиотеки DLL там "Is" надо потому что проверяется есть ли функция или нету функции, правда может надо было назвать IsFunctionDLL

Добавлено через 2 минуты
testuser2, что ты прицепился к словам. я же не англичанин чтобы знать правописание ну.

Добавлено через 1 минуту
Цитата Сообщение от testuser2 Посмотреть сообщение
DllCheck
совсем не походит. Функция не проверяет существует ли DLL. Функция проверяет существует ли функция внутри DLL и заодно уже проверяет существует ли DLL так как функция не будет найдена.

Добавлено через 4 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
ремарка
а вот что такое ремарка я не знаю. я такого слова не знаю. зачем вообще употреблять слова которые людям совсем не понятны. гуглить даже не собираюсь. просто буду злиться что говорят словами которые я не знаю и всё.

Добавлено через 4 минуты
testuser2, нужно говорить простыми и понятыми словами, чтобы люди понимали, а не всякие там врапперы и ремарки...
0
1399 / 857 / 92
Регистрация: 08.02.2017
Сообщений: 3,638
Записей в блоге: 2
06.11.2024, 16:17  [ТС]
Цитата Сообщение от HackerVlad Посмотреть сообщение
а вот что такое ремарка
Это также как "жюри, брощюра, паращют", "маэстро", "параграф", "сноска", "референс" и т.д.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
06.11.2024, 16:17
Помогаю со студенческими работами здесь

access и zip архив
Привет всем! Подскажите... если есть возможность сохранение файла в zip архив Dim FileHeder As String Dim filePath As String ...

Как распаковать ZIP-файл в 7z?
'При помощи VBA WinRAR распаковывает архив в папку … q = Адрес_сохранения_файла 'путь к каталогу, то есть к папке, в конце пути для...

ребята!завтра надо сдать работу,а без этих работ никак((
алгоритмы линейной структуры 1) СОСТАВИТЬ ПРОГРАММУ ВЫЧИСЛЕНИЯ СРЕДНЕГО ЗНАЧЕНИЯ ТРЕХ ВЕЛИЧИН 2) ПОДСЧИТАТЬ И ВЫВЕСТИ НА ЭКРАН СУММУ И...

Замена файла в zip архиве при совпадении имени
Есть несколько excel файлов. например, 1.xls, 2.xls, 3.xls Есть куча zip архивов. например, A (1.xls), B (1.xls,5.doc,3.doc), C (3.xls),...

Как сделать архив zip?
Как сделать архив zip? Какие нужны библиотеки и где их взять? заранее спасибо.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
160
Ответ Создать тему
Новые блоги и статьи
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru