Thanks. Much better in class form.teadrinker wrote: ↑13 Jan 2020, 05:40This is the solution:Code: Select all
#MaxMem 4095 SetBatchLines, -1 zipFile := A_ScriptDir . "\test.7z" pathInsideZip := "Folder\SubFolder\test.txt" 7ZipDLL := "7-zip" . A_PtrSize*8 . ".dll" 7zip := new 7zipToBuff(7ZipDLL, zipFile, pathInsideZip) 7zip.UnzipToBuff(buff) output := 7zip.output 7zip := "" MsgBox, % output MsgBox, % Clipboard := StrGet(&buff, "cp0") class 7zipToBuff { __New(7ZipDLL, zipFile, pathInsideZip) { static STD_OUTPUT_HANDLE := -11, DUPLICATE_SAME_ACCESS := 0x2 if !FileExist(7ZipDLL) throw 7ZipDLL . " not found" if !this.hModule := DllCall("LoadLibrary", "Str", 7ZipDLL, "Ptr") throw "LoadLibrary failed" this.7ZipDLL := 7ZipDLL this.zipFile := zipFile this.pathInsideZip := pathInsideZip this.savedStdOut := DllCall("GetStdHandle", "UInt", STD_OUTPUT_HANDLE, "Ptr") this.buffSize := this.GetBuffSize() DllCall("CreatePipe", "PtrP", hReadTemp, "PtrP", hPipeWrite, "Ptr", 0, "UInt", this.buffSize) hProc := DllCall("GetCurrentProcess") DllCall("DuplicateHandle", "Ptr", hProc, "Ptr", hReadTemp, "Ptr", hProc, "PtrP", hReadPipe, "UInt", 0, "UInt", false, "UInt", DUPLICATE_SAME_ACCESS) this.hReadPipe := hReadPipe DllCall("CloseHandle", "Ptr", hReadTemp) DllCall("SetStdHandle", "UInt", STD_OUTPUT_HANDLE, "Ptr", hPipeWrite) this.saved_stdout := DllCall("msvcrt\_dup", "Int", 1) this.fd := DllCall("msvcrt\_open_osfhandle", "Ptr", DllCall("GetStdHandle", "UInt", STD_OUTPUT_HANDLE, "Ptr"), "Int", 0) DllCall("msvcrt\_dup2", "Int", this.fd, "Int", 1) } __Delete() { DllCall("FreeLibrary", "Ptr", this.hModule) DllCall("msvcrt\_dup2", "Int", this.saved_stdout, "Int", 1) DllCall("msvcrt\_close", "Int", this.fd) DllCall("SetStdHandle", "UInt", STD_OUTPUT_HANDLE := -11, "Ptr", this.savedStdOut) } UnzipToBuff(ByRef buff) { VarSetCapacity(buff, this.buffSize) this.output := this.SevenZip("e -hide """ . this.zipFile . """ """ . this.pathInsideZip . """ -so") Loop { Sleep, 10 DllCall("PeekNamedPipe", "Ptr", this.hReadPipe, "Ptr", 0, "UInt", 0, "Ptr", 0, "UIntP", avail, "Ptr", 0) } until avail = this.buffSize || A_Index = 100 fullSize := 0 Loop { res := DllCall("ReadFile", "Ptr", this.hReadPipe, "Ptr", &buff + fullSize, "UInt", this.buffSize, "UIntP", nSize, "UInt", 0) fullSize += nSize } until !res || fullSize = this.buffSize } GetBuffSize() { hArc := DllCall(this.7ZipDLL . "\SevenZipOpenArchive", "Ptr", 0, "AStr", this.zipFile, "Int", 0) VarSetCapacity(INDIVIDUALINFO, 558, 0) DllCall(this.7ZipDLL . "\SevenZipFindFirst", "Ptr", hArc, "AStr", this.pathInsideZip, "Ptr", &INDIVIDUALINFO) DllCall(this.7ZipDLL . "\SevenZipCloseArchive", "Ptr", hArc) Return NumGet(INDIVIDUALINFO, "UInt") } SevenZip(sCommand) { VarSetCapacity(output, size := 1024) res := DllCall(this.7ZipDLL . "\SevenZip", "Ptr", 0, "AStr", sCommand, "Ptr", &output, "Int", size) return StrGet(&output, nSize, "CP0") } }
But I tested and failed. He never reacts. Ahk is freezing.