Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Calling 7zip through DllCall


  • Please log in to reply
10 replies to this topic
ahkguru
  • Members
  • 3 posts
  • Last active: Jan 26 2010 04:34 PM
  • Joined: 19 Dec 2006
Hi all!
I would like to use 7zip by calling its dll and not through the command line to avoid the dos window. I found the following implementation in Autoit :
<!-- m -->http://www.jak-softw... ... ZipCMD.au3<!-- m -->
Func _SevenZipCMD($sCMDLine, $hWnd = 0)
	$dll = DllOpen("7-zip32.dll")
	$result = DllCall($dll, "int", "SevenZip", "hwnd", $hWnd, "str", $sCMDLine, "str", 0)
	If @error Then
		SetError(1)
		Return 0
	EndIf
	DllClose($dll)
	Return 1
EndFunc   ;==>_SevenZipCMD

Can someone help me translating it to Autohotkey?
Thanks :-)

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
I don't have much time to work on this, but it is a good idea (although I just use the command line with Hide option, or not if I want to see the progression...).

I made a little search, and found surprisingly little reference on the API of this DLL. I guess that the DLL isn't even official: the one shipped with 7-Zip is named 7-zip.dll and is an ActiveX, not usable with AHK.
I found a 7-zip32.dll both in IZArc and TUGZip, with different size, so different versions.
I see, they come from the Common Archiver Project.
Cool (I explore as I write...), I found the original API description file: <!-- m -->http://www.csdinc.co...zip32api-en.txt<!-- m -->
And they have the 4.42.00.01 version.

It seems this DLL can be used to manipulate Z-Zip (of course) and regular Zip files.

I found a VB program (from a French site: LISTER ET EXTRAIRE UN FICHIER 7Z (FORMAT 7-ZIP)) having already encoded the API and showing off a little example of its use (list and extract). I give here an already pre-processed version, still far from being usable in AHK...
FNAME_MAX32 = 512
FNAME_MAX32PLUS1 = FNAME_MAX32 + 1

Type tagINDIVIDUALINFO
	dwOriginalSize As Long
	dwCompressedSize As Long
	dwCRC As Long
	uFlag As Long
	uOSType As Long
	wRatio As Integer
	wDate As Integer
	wTime As Integer
	szFilename As String * FNAME_MAX32PLUS1
	dummy1 As String * 3
	szAttribute As String * 8
	szMode As String * 8
End Type

SevenZipGetVersion() As Integer
SevenZipGetSubVersion() As Integer
SevenZipGetRunning() As Long
SevenZipGetBackGroundMode() As Long
SevenZipSetBackGroundMode(ByVal bBackGroundMode As Long) As Long
SevenZipGetCursorMode() As Long
SevenZipSetCursorMode(ByVal CursorMode As Long) As Long
SevenZipGetCursorInterval() As Integer
SevenZipSetCursorInterval(ByVal Interval As Integer) As Integer
SevenZip(ByVal hWnd As Long, ByVal szCmdLine As String, ByVal szOutPut As String, ByVal dwsize As Long) As Long
SevenZipCheckArchive(ByVal szFilename As String, ByVal imode As Long) As Long
SevenZipGetFileCount(ByVal szArcFile As String) As Long
SevenZipQueryFunctionList(ByVal iFunction As Long) As Long
SevenZipConfigDialog(ByVal hWnd As Long, ByVal szOptionBuffer As String, ByVal imode As Long) As Long
SevenZipExtractMem(ByVal hWnd As Long, ByVal szCmdLine As String, ByRef lpBuffer As Byte, ByVal dwsize As Long, lpTime As Long, lpwAttr As String, lpdwWriteSize As Long) As Long
SevenZipCompressMem(ByVal hWnd As Long, ByVal szCmdLine As String, ByRef lpBuffer As Byte, ByVal dwsize As Long, lpTime As Long, lpwAttr As String, lpdwWriteSize As Long) As Long
SevenZipOpenArchive(ByVal hWnd As Long, ByVal szFilename As String, ByVal dwsize As Long) As Long
SevenZipCloseArchive(ByVal hArc As Long) As Long
SevenZipFindFirst(ByVal hArc As Long, ByVal szWildName As String, lpSubInfo As tagINDIVIDUALINFO) As Long
SevenZipFindNext(ByVal hArc As Long, lpSubInfo As tagINDIVIDUALINFO) As Long
SevenZipGetArcFileName(ByVal hArc As Long, ByVal lpBuffer As String, nSize As Integer) As Long
SevenZipGetArcFileSize(ByVal hArc As Long) As Long
SevenZipGetArcFileSizeEx(ByVal hArc As Long, ByVal lpllsize As Currency) As Long
SevenZipGetArcOriginalSize(ByVal hArc As Long) As Long
SevenZipGetArcOriginalSizeEx(ByVal hArc As Long, ByVal lpllsize As Currency) As Long
SevenZipGetArcReadSize(ByVal hArc As Long) As Long
SevenZipGetArcReadSizeEx(ByVal hArc As Long, ByVal lpllsize As Currency) As Long
SevenZipGetArcCompressedSize(ByVal hArc As Long) As Long
SevenZipGetArcCompressedSizeEx(ByVal hArc As Long, ByVal lpllsize As Currency) As Long
SevenZipGetArcRatio(ByVal hArc As Long) As Long
SevenZipGetArcDate(ByVal hArc As Long) As Long
SevenZipGetArcTime(ByVal hArc As Long) As Long
SevenZipGetArcOSType(ByVal hArc As Long) As Long
SevenZipIsSFXFile(ByVal hArc As Long) As Long
SevenZipGetFileName(ByVal hArc As Long, ByVal lpBuffer As String, nSize As Integer) As Long
SevenZipGetMethod(ByVal hArc As Long, ByVal lpBuffer As String, nSize As Integer) As Long
SevenZipGetOriginalSize(ByVal hArc As Long) As Long
SevenZipGetOriginalSizeEx(ByVal hArc As Long, ByVal lpllsize As Currency) As Long
SevenZipGetCompressedSize(ByVal hArc As Long) As Long
SevenZipGetCompressedSizeEx(ByVal hArc As Long, ByVal lpllsize As Currency) As Long
SevenZipGetRatio(ByVal hArc As Long) As Long
SevenZipGetDate(ByVal hArc As Long) As Long
SevenZipGetTime(ByVal hArc As Long) As Long
SevenZipGetWriteTime(ByVal hArc As Long) As Long
SevenZipGetCreateTime(ByVal hArc As Long) As Long
SevenZipGetAccessTime(ByVal hArc As Long) As Long
SevenZipGetCRC(ByVal hArc As Long) As Long
SevenZipGetAttribute(ByVal hArc As Long) As Long
SevenZipGetOSType(ByVal hArc As Long) As Long
SevenZipSetOwnerWindow(ByVal hWnd As Long) As Long
SevenZipClearOwnerWindow() As Long
SevenZipKillOwnerWindowEx() As Long
SevenZipClearEnumMembersProc() As Long
SevenZipClearEnumMembersProc64() As Long

conDayZeroBios := 109205
conMillisecondPerDay := 10000000 * 60 * 60 * 24 / 10000
DosDateTimeToFileTime Lib "kernel32" (ByVal wFatDate As Long, ByVal wFatTime As Long, lpFileTime As Currency) As Long

Private udt7ZINDIVIDUALINFO As tagINDIVIDUALINFO
Private udtFILETIME As Currency

Public Function ListSevenZIP(ArchiveFile As String)
	If SevenZipCheckArchive(ArchiveFile, 1) = 0 Then Exit Function
	If SevenZipGetRunning <> 0 Then
		MsgBox "7-ZIP32.DLL is already running.", vbCritical, App.Title
		Exit Function
	Else
		lngResult = SevenZipSetBackGroundMode(0&)
		lngResult = SevenZipSetCursorMode(0&)
		lngArcHandle = SevenZipOpenArchive(Form1.hWnd, ArchiveFile, 0)
		If lngArcHandle <> 0 Then
			If SevenZipFindFirst(lngArcHandle, "*", udt7ZINDIVIDUALINFO) = 0 Then
				Do
					DoEvents
					lngResult = DosDateTimeToFileTime(CLng(udt7ZINDIVIDUALINFO.wDate), CLng(udt7ZINDIVIDUALINFO.wTime), udtFILETIME)
					Form1.List1.AddItem LCase(Left$(udt7ZINDIVIDUALINFO.szFilename, InStr(udt7ZINDIVIDUALINFO.szFilename, vbNullChar) - 1)) & ";" & ArchiveFile & "\;" & udt7ZINDIVIDUALINFO.dwOriginalSize & ";" & CDate((udtFILETIME / conMillisecondPerDay) - conDayZeroBios) & ";" & Left$(udt7ZINDIVIDUALINFO.szAttribute, InStr(udt7ZINDIVIDUALINFO.szAttribute, vbNullChar) - 1) & ";Archive 7-ZIP"
				Loop While SevenZipFindNext(lngArcHandle, udt7ZINDIVIDUALINFO) = 0
			End If
			lngResult = SevenZipCloseArchive(lngArcHandle)
		End If
	End If
	Call ListerArchive
End Function

Public Sub Extract(Archive As String, ToExtract As String)
	If SevenZipCheckArchive(Archive, 1) = 0 Then Exit Sub
	Dim cmdlin As String
	Dim Ret As Long
	cmdlin = MakeCommandLine("x", Archive, App.Path & "\", ToExtract)
	Ret = SevenZip(Form1.hWnd, cmdlin, "", 0)
End Sub

Public Function MakeCommandLine(ByVal SwitchAndOptions As String, ByVal ArcFileName As String, ByVal DirName As String, ByVal TargetFileName As String) As String
	MakeCommandLine = SwitchAndOptions & " " & AddQuotes(ArcFileName) & " " & AddQuotes(DirName) & " " & TargetFileName
	Debug.Print MakeCommandLine
End Function
Public Function AddQuotes(Fichier As String) As String
	If InStr(Fichier, " ") Then
		AddQuotes = """" & Fichier & """"
	Else
		AddQuotes = Fichier
	End If
End Function
There are probably missing bits, see the above link for more...
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

PaTaTe
  • Guests
  • Last active:
  • Joined: --
Je vois que mon code est utile :)

trik
  • Members
  • 1317 posts
  • Last active: Jun 11 2010 11:48 PM
  • Joined: 15 Jul 2007
I don't know much about dll and all, but this seems right to me:

SevenZipCMD(sCMDLine, hWnd = 0)
   result := DllCall(7-zip32.dll, "int", "SevenZip", "hwnd", %hWnd%, "str", %sCMDLine%, "str", 0)
   If errorlevel
      Return 0
   ExitApp
   else
   Return 1
ExitApp


STEPHANVS
  • Members
  • 14 posts
  • Last active: Apr 25 2009 10:56 AM
  • Joined: 03 Mar 2007

... (although I just use the command line with Hide option, or not if I want to see the progression...)


Is it posible? Please share...

(As far as I tried with 7z.exe or 7zG.exe the Hide option does nothing when decompressing...)

Regards,
STEPHANVS

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

I don't know much about dll and all, but this seems right to me:

SevenZipCMD(sCMDLine, hWnd = 0)
   result := DllCall(7-zip32.dll, "int", "SevenZip", "hwnd", %hWnd%, "str", %sCMDLine%, "str", 0)
   If errorlevel
      Return 0
   ExitApp
   else
   Return 1
ExitApp

There are various errors in the above. The least obvious of which is that DllCall accepts different parameters in AutoIt3:
DllCall ( "dll", "return type", "function" [, "type1", param1 [, "type n", param n]] )
AutoHotkey:
Result := DllCall("[DllFile\]Function" [, Type1, Arg1, Type2, Arg2, "Cdecl ReturnType"])
Directly translating the AutoIt3 function to AutoHotkey results in:
_SevenZipCMD(sCMDLine, hWnd = 0)
{
    dll := DllCall("LoadLibrary", "str", "7-zip32.dll")
    result := DllCall("7-zip32.dll\SevenZip", "uint", hWnd, "str", sCMDLine, "str", 0, "int")
    if ErrorLevel
    {
        ErrorLevel = 1
        return 0
    }
    DllCall("FreeLibrary", "uint", dll)
    return 1
}
However,[*:y8ns7hgz]The DllOpen/DllClose/LoadLibrary/FreeLibrary calls are superfluous since DllCall will automatically do this (in both languages.)
[*:y8ns7hgz]The ErrorLevel checks seem unnecessary, and if the DllCall fails, the DLL is not unloaded! (until the script exits.)
[*:y8ns7hgz]I'm assuming "str",0 in AutoIt3 passes a valid pointer to a string of characters (containing the character '0'). That is what AutoHotkey does, but for all I know AutoIt3 might pass a NULL pointer instead.
_SevenZipCMD(sCMDLine, hWnd = 0) {
    return DllCall("7-zip32.dll\SevenZip", "uint", hWnd, "str", sCMDLine, "str", 0)
}
Now the question is whether the AutoIt3 function had the usage correct...

The "original API description file" PhiLho linked to has this:
-----------------------------------------------------------------------
int WINAPI SevenZip(const HWND _hwnd, LPCSTR _szCmdLine,
                    LPSTR _szOutput, const DWORD _dwSize)
-----------------------------------------------------------------------
Number  1
Function
    Compression thawing and the like is done.

Argument
    _hwnd       The window handle of the application which calls 7-zip32.dll.
                7-zip32.dll EnableWindow () executes the execution time vis-a-vis this window and controls the operation of the window.
                It is the console application where the window does not exist when and, when it is not necessary to appoint, NULL is transferred.
    _szCmdLine  The command character string which transfers to 7-zip32.dll.
    _szOutput   The buffer because 7-zip32.dll returns the result.
                When it is global memory or like that, it is necessary to be locked.
    _dwSize     Größe des Puffers.
                When the result exceeds designated size, it is economized in this size.
                If size is 1 or more, always NULL letter is added lastly.
So it appears SevenZip() has an extra parameter that the AutoIt3 function omitted! You could try:
_SevenZipCMD(sCMDLine, hWnd = 0) {
    return DllCall("7-zip32.dll\SevenZip", "uint", hWnd, "str", sCMDLine, "uint", 0, "uint", 0)
}
This passes a NULL pointer as _szOutput and zero for _dwSize. I'm guessing SevenZip() ignores the output buffer if it is a NULL pointer. If not, you'll need to provide a buffer of sufficient size for the output. (I'm not sure what the output would be.)
_SevenZipCMD(sCMDLine, hWnd = 0) {
    buffer_size := VarSetCapacity(buffer, 1024**2) ; how to decide how big it should be?
    return DllCall("7-zip32.dll\SevenZip", "uint", hWnd, "str", sCMDLine, "str", buffer, "uint", buffer_size)
}
Obviously untested...

Maybe _szOutput is for statistics/operational information rather than the resulting compressed data? If that is the case, it is likely optional (i.e. may be "uint",0,"uint",0.)

Obi-Wahn
  • Members
  • 77 posts
  • Last active: Oct 29 2012 05:55 PM
  • Joined: 20 Apr 2006
Hi!

Ive read the entire Topic over and over again, but came nowhere.
I try to extract all files and folders from a .iso Image with 7zip which is possible (at least with the gui from 7zip), but I wasn't successfull with the .dll and the funktions.

I've tried every funktion in this thread (except the autoit :D ) but none worked.

Could someone help me please?!?
Thanks

VBdeveloper
  • Guests
  • Last active:
  • Joined: --
Could anyone take a stab at the argument definitions for these two functions
FUNCTION SevenZipExtractMem ( BYVAL hWnd AS LONG, BYVAL szCmdLine AS STRING, BYREF lpBuffer AS BYTE, BYVAL dwsize AS LONG, _
                              lpTime AS LONG, lpwAttr AS STRING, lpdwWriteSize AS LONG) AS LONG  

FUNCTION SevenZipCompressMem ( BYVAL hWnd AS LONG, BYVAL szCmdLine AS STRING, BYREF lpBuffer AS BYTE, BYVAL dwsize AS LONG, _
                                       lpTime AS LONG, lpwAttr AS STRING, lpdwWriteSize AS LONG) AS LONG

hWnd = handle to parent dialog
szCmdLine = command line
lpBuffer = buffer of file to be compressed
dwsize = Size of the buffer in bytes
lpTime = ???
lpwAttr = ???
lpdwWriteSize = Compressed size returned in buffer?
(implies 'in place' compression)

maximina
  • Members
  • 17 posts
  • Last active: Nov 04 2008 08:20 PM
  • Joined: 17 Oct 2007
Sorry for pulling up an old thread, but has anyone had any success with this?

I'd like to include 7z abilities with a distributable script, but would like to exclude the exe for the sake of filesize, and call the Dll directly.

tehrani20
  • Members
  • 10 posts
  • Last active: Sep 13 2010 11:53 AM
  • Joined: 23 Mar 2009
I couldn't unzip any file with calling 7-zip32.dll , could you please help me unzipping files with calling this dll

  • Guests
  • Last active:
  • Joined: --
7-zip32.dl works like the stand alone version of 7z (7za.exe), which is limited to a couple of formats. I've had the same problem trying to extract .gz files.
I can do it with 7z.exe, but not with the dll.