Понадобилось тут перехватить вызов 7zip. Из консольного юникодного приложения. Причём юникодность тут роли не играет. И 7zip это лишь как пример. И вот такие интересные вещи происходят
Код:
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
| EnableExplicit OpenConsole() Define x.i Define ArchFile.s = ProgramParameter() ;Define SevenZipExe.s = GetPathPart(ProgramFilename())+"7z.exe" Define SevenZipExe.s = "7z.exe" Define SevenZipCmd.s = "x -y -sccUTF-8 -- "+ArchFile Define SevenZipRet.i Define SevenZip.i Define SevenZipOut.s Define OutBytes.i, OutResult.i Define OutBufferSize.i = 4194304 Define OutBuffer.i = AllocateMemory(OutBufferSize,#PB_Memory_NoClear) Define LogH.i, LogFile.s = GetFilePart(ArchFile)+".log" SevenZip = RunProgram(SevenZipExe,SevenZipCmd,"",#PB_Program_Open|#PB_Program_Read) If SevenZip LogH = CreateFile(#PB_Any,LogFile) While ProgramRunning(SevenZip) OutBytes = AvailableProgramOutput(SevenZip) If OutBytes PrintN("Out bytes: "+Str(OutBytes)) WriteStringN(LogH,"Out bytes: "+Str(OutBytes)) If OutBytes > OutBufferSize OutBufferSize = OutBytes OutBuffer = ReAllocateMemory(OutBuffer,OutBufferSize,#PB_Memory_NoClear) EndIf OutResult = ReadProgramData(SevenZip,OutBuffer,OutBufferSize) PrintN("Out result: "+Str(OutResult)) WriteStringN(LogH,"Out result: "+Str(OutResult)) SevenZipOut = PeekS(OutBuffer,OutResult,#PB_UTF8) WriteString(LogH,SevenZipOut,#PB_UTF8) While Len(SevenZipOut)>0 x = FindString(SevenZipOut,#CRLF$) If x=0 : x=Len(SevenZipOut) : EndIf If Left(SevenZipOut,10) = "Extracting" ;PrintN("> "+Trim(Mid(SevenZipOut,11,x-11))) EndIf SevenZipOut = Mid(SevenZipOut,x+2) Wend EndIf Delay(1) Wend EndIf PrintN("") CloseFile(LogH) FreeMemory(OutBuffer) |
До какого-то момента всё нормально. Но по мере роста количества файлов в архиве, растёт, соответственно, объём выводимой информации.
Вообще, как в моём понимании, может быть неправильном, просходит получение данных при перехвате вывода - выводимые данные попадают в некий системный буфер и по мере заполнения буфера, отдаются вызывающей программе. Данные передаются небольшими "порциями", если их тут же выводить на экран, вывод будет идти рывками, по мере поступления данных. Вроде как тоже самое должно просходить и в PB. Но AvailableProgramOutput никогда не выдаёт число больше 4243. Это "магическое" число, возможно, и есть размер буфера. Но ReadProgramData возвращает совсем другое значение. С прилагаемым файлом 4243 и 290187 соответственно. Получается, AvailableProgramOutput врёт, а данные получаем не по мере заполнения буфера, а разом? И как тут понять, какой буфер для них нужно выделять?
П.С.
Почему-то не добавляются файлы 7z, глюк форума?