By
mLipok
In the past there was many questions about how to: "Automatic file upload using without user interaction"
https://www.autoitscript.com/forum/topic/92907-ie-8-input-namenomfic-typefile-idnomfic/
https://www.autoitscript.com/forum/topic/116899-cant-automate-input-typefile-tag-in-ie/?tab=comments#comment-815478
https://www.autoitscript.com/forum/topic/14883-input-typefile/
https://www.autoitscript.com/forum/topic/188708-how-to-set-the-value-of-an-input-typefile-element/
https://www.autoitscript.com/forum/topic/91513-how-can-i-auto-set-file-path-for-input-file-in-ie/
https://www.autoitscript.com/forum/topic/116899-cant-automate-input-typefile-tag-in-ie/
https://www.autoitscript.com/forum/topic/169190-how-to-script-file-upload-button/
https://www.autoitscript.com/forum/topic/145327-how-to-deal-with-ie-window-for-upload-a-fileinput-typefile/
https://www.autoitscript.com/forum/topic/140482-internet-explorer-input-file-problem/
I found solution here:
https://stackoverflow.com/questions/33253517/upload-a-file-via-input-input-in-html-form-with-vba
and:
https://www.motobit.com/tips/detpg_uploadvbsie/
And I translate this code to AutoIt3 code:
; Upload file using http protocol And multipart/form-data
; v1.01
; 2001 Antonin Foller, PSTRUH Software
Global $oErrorHandler = ObjEvent("AutoIt.Error", _ErrFunc)
do_vbsUpload()
Func do_vbsUpload()
#cs
; We need at least two arguments (File & URL)
ConsoleWrite('- ' & @ScriptLineNumber & @CRLF)
If $CmdLine[0] < 2 Then InfoEcho()
ConsoleWrite('- ' & @ScriptLineNumber & @CRLF)
; Are some required objects missing?
If StringInStr(CheckRequirements(), "Error") > 0 Then InfoEcho()
ConsoleWrite('- ' & @ScriptLineNumber & @CRLF)
Local $s_FileName, $s_DestURL, $s_FieldName
$s_FieldName = "FileField" ; Default field name
For $i_argCounter = 1 To $CmdLine[0]
ConsoleWrite('+ '& $i_argCounter& ' >> ' & $CmdLine[$i_argCounter] & @CRLF)
Select
Case $i_argCounter = 1
;~ $s_FileName = $CmdLine[$i_argCounter]
$s_FileName = @ScriptFullPath
Case $i_argCounter = 2
$s_DestURL = $CmdLine[$i_argCounter]
Case $i_argCounter = 3
$s_FieldName = $CmdLine[$i_argCounter]
EndSelect
Next
UploadFile($s_DestURL, $s_FileName, $s_FieldName)
#ce
UploadFile('http://www.dobeash.com/test.html', @ScriptFullPath, 'fileExample')
EndFunc ;==>do_vbsUpload
; ******************* upload - begin
; Upload file using input type=file
Func UploadFile($s_DestURL, $s_FileName, $s_FieldName)
; Boundary of fields.
; Be sure this string is Not In the source file
Const $Boundary = "---------------------------0123456789012"
; Get source file As a binary data.
Local $d_FileContents = GetFile($s_FileName)
; Build multipart/form-data document
Local $s_FormData = BuildFormData($d_FileContents, $Boundary, $s_FileName, $s_FieldName)
; Post the data To the destination URL
IEPostBinaryRequest($s_DestURL, $s_FormData, $Boundary)
EndFunc ;==>UploadFile
; Build multipart/form-data document with file contents And header info
Func BuildFormData($d_FileContents, $Boundary, $s_FileName, $s_FieldName)
Const $s_ContentType = "application/upload"
; The two parts around file contents In the multipart-form data.
Local $s_Pre = "--" & $Boundary & @CRLF & mpFields($s_FieldName, $s_FileName, $s_ContentType)
Local $s_Po = @CRLF & "--" & $Boundary & "--" & @CRLF
; Build form data using recordset binary field
Const $i_adLongVarBinary = 205
Local $oRS = ObjCreate("ADODB.Recordset")
; https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/append-method-ado?view=sql-server-ver15
$oRS.Fields.Append("b", $i_adLongVarBinary, StringLen($s_Pre) + BinaryLen($d_FileContents) + StringLen($s_Po))
$oRS.Open()
$oRS.AddNew()
; Convert Pre string value To a binary data
Local $i_LenData = StringLen($s_Pre)
$oRS("b").AppendChunk(StringToMB($s_Pre) & StringToBinary(Chr(0)))
$s_Pre = $oRS("b").GetChunk($i_LenData)
$oRS("b") = ""
; Convert Po string value To a binary data
$i_LenData = StringLen($s_Po)
$oRS("b").AppendChunk(StringToMB($s_Po) & StringToBinary(Chr(0)))
$s_Po = $oRS("b").GetChunk($i_LenData)
$oRS("b") = ""
; Join Pre & $d_FileContents & Po binary data
$oRS("b").AppendChunk($s_Pre)
$oRS("b").AppendChunk($d_FileContents)
$oRS("b").AppendChunk($s_Po)
$oRS.Update()
Local $s_FormData = $oRS("b")
$oRS.Close()
Return $s_FormData
EndFunc ;==>BuildFormData
; sends multipart/form-data To the URL using IE
Func IEPostBinaryRequest($s_URL, $s_FormData, $Boundary)
; Create InternetExplorer
Local $oIE = ObjCreate("InternetExplorer.Application")
; You can uncoment Next line To see form results
$oIE.Visible = True
; Send the form data To $s_URL As POST multipart/form-data request
$oIE.Navigate($s_URL, '', '', $s_FormData, _
"Content-Type: multipart/form-data; boundary=" & $Boundary & @CRLF)
While $oIE.Busy
Wait(1, "Upload To " & $s_URL)
WEnd
; Get a result of the script which has received upload
;~ On Error Resume Next
Local $s_IE_InnerHTML = $oIE.Document.body.innerHTML
MsgBox(0, 'TEST #' & @CRLF & @ScriptLineNumber, $s_IE_InnerHTML)
$oIE.Quit()
Return $s_IE_InnerHTML
EndFunc ;==>IEPostBinaryRequest
; Infrormations In form field header.
Func mpFields($s_FieldName, $s_FileName, $s_ContentType)
Local $s_MPTemplate = _ ; template For multipart header
'Content-Disposition: form-data; name="{field}";' & _
'FileName="{file}"' & @CRLF & _
'Content-Type: {ct}' & @CRLF & @CRLF & _
''
Local $s_Out
$s_Out = StringReplace($s_MPTemplate, "{field}", $s_FieldName)
$s_Out = StringReplace($s_Out, "{file}", $s_FileName)
$s_Out = StringReplace($s_Out, "{ct}", $s_ContentType)
Return $s_Out
EndFunc ;==>mpFields
Func Wait($i_Seconds, $s_Message)
MsgBox(64, '', $s_Message, $i_Seconds)
EndFunc ;==>Wait
; Returns file contents As a binary data
Func GetFile($s_FileName)
Local $oStream = ObjCreate("ADODB.Stream")
$oStream.Type = 1 ; Binary
$oStream.Open()
$oStream.LoadFromFile($s_FileName)
Local $d_GetFile = $oStream.Read()
$oStream.Close()
Return $d_GetFile
EndFunc ;==>GetFile
; Converts OLE string To multibyte string
Func StringToMB($S)
Local $I, $B
For $I = 1 To StringLen($S)
$B &= StringToBinary(Asc(StringMid($S, $I, 1)))
Next
Return $B
EndFunc ;==>StringToMB
; ******************* upload - end
; ******************* Support
; Basic script info
Func InfoEcho()
Local $sMsg = _
"Upload file using http And multipart/form-data" & @CRLF & _
"Copyright (C) 2001 Antonin Foller, PSTRUH Software" & @CRLF & _
"use" & @CRLF & _
"[cscript|wscript] fupload.vbs file $s_URL [fieldname]" & @CRLF & _
" file ... Local file To upload" & @CRLF & _
" $s_URL ... $s_URL which can accept uploaded data" & @CRLF & _
" fieldname ... Name of the source form field." & @CRLF & _
@CRLF & CheckRequirements() & @CRLF & _
""
ConsoleWrite('! ' & $sMsg & @CRLF)
EndFunc ;==>InfoEcho
; Checks If all of required objects are installed
Func CheckRequirements()
Local $sMsg = _
"This script requires some objects installed To run properly." & @CRLF & _
CheckOneObject("ADODB.Recordset") & @CRLF & _
CheckOneObject("ADODB.Stream") & @CRLF & _
CheckOneObject("InternetExplorer.Application") & @CRLF & _
""
Return $sMsg
; $sMsgBox $sMsg
EndFunc ;==>CheckRequirements
; Checks If the one object is installed.
Func CheckOneObject($sClassName)
Local $sMsg
ObjCreate($sClassName)
If @error = 0 Then
$sMsg = "OK"
Else
$sMsg = "Error:" & @error
EndIf
Return $sClassName & " - " & $sMsg
EndFunc ;==>CheckOneObject
; ******************* Support - end
; User's COM error function. Will be called if COM error occurs
Func _ErrFunc(ByRef $oError)
; Do anything here.
ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _
@TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _
@TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
@TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _
@TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _
@TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
@TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
@TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
@TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
@TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc ;==>_ErrFunc
But I miss something and the code not works as intendend.
Please join and contribute, in solving this issue, as this will be handy for entire community.
@mLipok
btw.
I think that this may be realated to ChrB() which I simply translate to StringToBinary()
Especialy this :
StringToBinary(Chr(0)))
could be the main issue.
But for now I'm tired and going to sleep.
Hope maybe tomorrow somebody solve this issue.