1

Тема: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Как упаковать файлы более 1Гб на ahk32 бит?
Например, так выводит ошибку:
0x8007000E - Not enough memory resources are available to complete this operation.

oADO := ComObjCreate("ADODB.Stream")
oADO.Type := 1 ; adTypeBinary
oADO.Open
oADO.LoadFromFile("D:\1gb.mp4")
oADO.Read
oADO.Close
msgbox ok

2 (изменено: YMP, 2019-08-04 17:03:11)

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Можно, в принципе, и вручную создать структуру SAFEARRAY, заполнить. Кажись я как-то делал. Хотя ведь и функции для этого есть в WinAPI, насколько помню, целый набор для работы с SAFEARRAY. Но с такими большими файлами я не пробовал.

3

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

А не может быть на 32 битах ограничениий по размеру, так как таким способом тоже не получается:

ByteArray(ByRef src, bytes, copy:=false)
{
	ByteArr := ComObjArray(0x11, bytes) ; VT_ARRAY|VT_UI1
	ComObjFlags(ByteArr, -1) ; Remove F_OWNVALUE flag
	NumPut(IsByRef(src) ? &src : src, ComObjValue(ByteArr) + 12 + (A_PtrSize==8 ? 4 : 0))
	return copy ? ByteArr.Clone() : ByteArr
}

Проверял через заливку на файлообменник файла более 1 гига.
На 64 битах работает, на 32 битах нет.

path := "D:\test.mp4"


HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
HTTP.Open("GET", "https://failiem.lv", true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko)")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.Send()
HTTP.WaitForResponse()
RegexMatch(HTTP.ResponseText, "s)PHPSESSID=(.+?)"".+?strCurrentUploadCallServer = '(.+?)\.", match)
phpsessid := match1, server := match2

HTTP.Open("GET", "https://failiem.lv/server_scripts/get_upload_id.php?show_add_key=1", true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko)")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.Send()
HTTP.WaitForResponse()
RegexMatch(HTTP.ResponseText, "s)(.+?),.+?,(.+?)$", match)
up_id := match1, key := match2

now := A_NowUTC
EnvSub, now,1970, seconds
now .= A_MSec
objParam := {file: [path]}
CreateFormData(PostData, hdr_ContentType, objParam)

HTTP.SetTimeouts(0, 0, 0, 0)
HTTP.Open("POST", "https://" server ".failiem.lv/save_file.php?PHPSESSID=" phpsessid "&up_id=" up_id "&ignore_user_abort=1&skip_update=1&key=" key "&v=" now, true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko)")
HTTP.SetRequestHeader("Content-Type", hdr_ContentType)
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.Send(PostData)
HTTP.WaitForResponse()
uploadedLink := "https://failiem.lv/u/" up_id

; проверка загрузки
HTTP.SetTimeouts(0, 60000, 30000, 30000)
HTTP.Open("GET", uploadedLink, true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko)")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.Send()
HTTP.WaitForResponse()
if InStr(HTTP.ResponseText, "tools_button_download")
   msgbox % clipboard := uploadedLink
else
   msgbox Error
return


; CreateFormData() by tmplinshi, AHK Topic: https://autohotkey.com/boards/viewtopic.php?t=7647
; Thanks to Coco: https://autohotkey.com/boards/viewtopic.php?p=41731#p41731
; Modified version by SKAN, 09/May/2016

CreateFormData(ByRef retData, ByRef retHeader, objParam) {
	New CreateFormData(retData, retHeader, objParam)
}

Class CreateFormData {

	__New(ByRef retData, ByRef retHeader, objParam) {

		Local CRLF := "`r`n", i, k, v, str, pvData
		; Create a random Boundary
		Local Boundary := this.RandomBoundary()
		Local BoundaryLine := "------------------------------" . Boundary

    this.Len := 0 ; GMEM_ZEROINIT|GMEM_FIXED = 0x40
    this.Ptr := DllCall( "GlobalAlloc", "UInt",0x40, "UInt",1, "Ptr"  )          ; allocate global memory

		; Loop input paramters
		For k, v in objParam
		{
			If IsObject(v) {
				For i, FileName in v
				{
					str := BoundaryLine . CRLF
					     . "Content-Disposition: form-data; name=""" . k . """; filename=""" . FileName . """" . CRLF
					     . "Content-Type: " . this.MimeType(FileName) . CRLF . CRLF
          this.StrPutUTF8( str )
          this.LoadFromFile( Filename )
          this.StrPutUTF8( CRLF )
				}
			} Else {
				str := BoundaryLine . CRLF
				     . "Content-Disposition: form-data; name=""" . k """" . CRLF . CRLF
				     . v . CRLF
        this.StrPutUTF8( str )
			}
		}

		this.StrPutUTF8( BoundaryLine . "--" . CRLF )

    ; Create a bytearray and copy data in to it.
    retData := ComObjArray( 0x11, this.Len ) ; Create SAFEARRAY = VT_ARRAY|VT_UI1
    pvData  := NumGet( ComObjValue( retData ) + 8 + A_PtrSize )
    DllCall( "RtlMoveMemory", "Ptr",pvData, "Ptr",this.Ptr, "Ptr",this.Len )

    this.Ptr := DllCall( "GlobalFree", "Ptr",this.Ptr, "Ptr" )                   ; free global memory 

    retHeader := "multipart/form-data; boundary=----------------------------" . Boundary
	}

  StrPutUTF8( str ) {
    Local ReqSz := StrPut( str, "utf-8" ) - 1
    this.Len += ReqSz                                  ; GMEM_ZEROINIT|GMEM_MOVEABLE = 0x42
    this.Ptr := DllCall( "GlobalReAlloc", "Ptr",this.Ptr, "UInt",this.len + 1, "UInt", 0x42 )   
    StrPut( str, this.Ptr + this.len - ReqSz, ReqSz, "utf-8" )
  }
  
  LoadFromFile( Filename ) {
    Local objFile := FileOpen( FileName, "r" )
    this.Len += objFile.Length                     ; GMEM_ZEROINIT|GMEM_MOVEABLE = 0x42 
    this.Ptr := DllCall( "GlobalReAlloc", "Ptr",this.Ptr, "UInt",this.len, "UInt", 0x42 )
    objFile.RawRead( this.Ptr + this.Len - objFile.length, objFile.length )
    objFile.Close()       
  }

	RandomBoundary() {
		str := "0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z"
		Sort, str, D| Random
		str := StrReplace(str, "|")
		Return SubStr(str, 1, 12)
	}

	MimeType(FileName) {
		n := FileOpen(FileName, "r").ReadUInt()
		Return (n        = 0x474E5089) ? "image/png"
		     : (n        = 0x38464947) ? "image/gif"
		     : (n&0xFFFF = 0x4D42    ) ? "image/bmp"
		     : (n&0xFFFF = 0xD8FF    ) ? "image/jpeg"
		     : (n&0xFFFF = 0x4949    ) ? "image/tiff"
		     : (n&0xFFFF = 0x4D4D    ) ? "image/tiff"
		     : "application/octet-stream"
	}

}

4 (изменено: YMP, 2019-08-04 18:24:45)

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Да, на 32 битах же процессу доступно 2 ГБ пользовательского адресного пространства. Я уже и забыл об этом. При каких-то там настройках можно расширить до 3 ГБ. Возможно, из-за этого проблемы. Для данных массива, по идее, нужен непрерывный блок. Может быть, уже не удаётся его получить.

https://docs.microsoft.com/en-us/window … s-releases

5

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Там пишется про 2 ГБ, а у меня почему-то не работает при файлах начиная с 800 МБ.

6

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Malcev, Windows 10 x32?

7

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Ну, 2 ГБ — это на всё про всё. Думаю, зависит от того, как там память выделяется.

8

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

ypppu, Windows 7 x64 и Windows 10 x64.

9

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

А под 32 битами имелось в виду AutoHotkey x32, запущенная на Windows7 x64 ?

10

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Тут что то про IMAGE_FILE_LARGE_ADDRESS_AWARE.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

11

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

ypppu пишет:

А под 32 битами имелось в виду AutoHotkey x32, запущенная на Windows7 x64 ?

Да.

serzh82saratov пишет:

Тут что то про IMAGE_FILE_LARGE_ADDRESS_AWARE.

После патча autohotkey.exe c 4gb_patch.exe читает до 1.7ГБ.

12

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

А смысл это пилить под AutoHotkey x32, если на Windows x86 оно всё равно не заработает?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

13

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Просто у меня стоит ahk32 - видно время переходить на ahk64.
Еще интересно, как в таком случае броузер заливает файл в 2 гб, там заливка происходит в 1 запрос:

HTTP.Open("POST", "https://" server ".failiem.lv/save_file.php?PHPSESSID=" phpsessid "&up_id=" up_id "&ignore_user_abort=1&skip_update=1&key=" key "&v=" now, true)

Получается, что AHK плохо распределяет память?

14

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Malcev пишет:

видно время переходить на ahk64

Зачем переходить, проще запускать редкие скрипты под х64, иначе начнут всплывать проблемы под х86 у других.

Malcev пишет:

заливка происходит в 1 запрос

А разве сами данные в самом запросе, то есть я видел что отправляются файлы в виде BASE64, а тут то как работает?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

15

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

Данные отправляются как SafeArray.

16

Re: AHK: Упаковка больших файлов (>1Gb) в COM bytearray на ahk32 bit

А, понял методом Send.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui