I think so. Might doing it in this way:
Code: Select all
#NoEnv
SetWorkingDir %A_ScriptDir%
if (A_Args[1] != "<Fix>") {
Run, %A_ScriptFullPath% "<Fix>", % A_ScriptDir
ExitApp
}
global 7zipDll := (A_PtrSize=8) ? "7-zip64.dll" : "7-zip32.dll"
DllCall("LoadLibrary", "str", 7zipDll, "ptr")
for i, info in SevenZip_ExtractMemMulti("test.zip", "*.txt")
MsgBox % info.filename . "`n" . info.data
ExitApp
SevenZip_ExtractMemMulti(archive_name, file_name := "*") {
DllCall("CreatePipe", "ptr*", readTemp, "ptr*", writePipe, "ptr", 0, "uint", 0)
hcp := DllCall("GetCurrentProcess", "ptr")
DllCall("DuplicateHandle", "ptr", hcp, "ptr", readTemp, "ptr", hcp, "ptr*", readPipe, "uint", 0, "int", false, "uint", 2)
DllCall("CloseHandle", "ptr", readTemp)
DllCall("SetStdHandle", "uint", -11, "ptr", writePipe)
sCmdLine = x -so -hide "%archive_name%" "%file_name%"
DllCall(7zipDll . "\SevenZip", "ptr", 0, "astr", sCmdLine, "ptr", 0, "uint", 0)
if DllCall("PeekNamedPipe", "ptr", readPipe, "ptr", 0, "uint", 0, "ptr", 0, "uint*", availBytes, "ptr", 0)
&& availBytes
{
VarSetCapacity(_szBuffer, availBytes)
DllCall("ReadFile", "ptr", readPipe, "ptr", &_szBuffer, "uint", availBytes, "ptr*", readBytes, "ptr", 0)
; return StrGet(&_szBuffer, availBytes, "utf-8")
info := SevenZip_GetOriginalSizeMulti(archive_name, file_name)
offset := 0
for i, o in info
{
o.data := StrGet(&_szBuffer+offset, o.size, "utf-8")
offset += o.size
}
return info
}
}
SevenZip_GetOriginalSizeMulti(archive_name, file_name := "*") {
if !hArc := DllCall(7zipDll . "\SevenZipOpenArchive", "ptr", 0, "astr", archive_name, "int", 0)
throw "SevenZipOpenArchive fail"
VarSetCapacity(info, 558, 0)
ret := DllCall(7zipDll . "\SevenZipFindFirst", "ptr", hArc, "astr", file_name, "ptr", &info)
result := []
while (ret = 0) {
result[A_Index, "size" ] := NumGet(info, 0, "uint")
result[A_Index, "filename"] := StrGet(&info+26, 513, "cp0")
ret := DllCall(7zipDll . "\SevenZipFindNext", "ptr", hArc, "ptr", &info)
}
DllCall(7zipDll . "\SevenZipCloseArchive", "ptr", hArc)
return result.MaxIndex() ? result : ""
}