Niblob Posted January 15, 2009 Share Posted January 15, 2009 Hi there, There are those who may claim this is not an AutoIT question, but I am using AutoIT to code it so a really hope someone can provide a solution. I am trying to send screen captures at regular intervals from several PCs to a server. Because of firewall restrictions, I can only use port 80 - so it will have to be via HTTP. I have set up a CGI script on the server to handle the incoming jpegs. Here is the code for that: CODE #!/usr/bin/perl -w use strict; use CGI; use CGI::Carp qw ( fatalsToBrowser ); use File::Basename; $CGI::POST_MAX = 1024 * 5000; my $safe_filename_characters = "a-zA-Z0-9_.-"; my $query = new CGI; my $pc = $query->param("PC"); my $filename = "$pc.jpg"; my $upload_dir = 'C:/Inetpub/wwwroot/jpg'; my $upload_filehandle = $query->upload("TheFile"); open (UPLOADFILE, ">$upload_dir/$filename") or error("Can't open/create \"$upload_dir/$filename\": $!"); binmode UPLOADFILE; while ( <$upload_filehandle> ) { print UPLOADFILE; } close UPLOADFILE; print $query->header ( ); print <<END_HTML; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Thanks!</title> <style type="text/css"> img {border: none;} </style> </head> <body> <p>Thanks for uploading your file!</p> <p>Your photo:</p> <p><img src="/jpg/$filename" alt="Photo" /></p> </body> </html> END_HTML sub error { my $error = shift; print $query->header(), $query->start_html(-title=>'Error'), $error, $query->end_html; exit(0); } Now I need AutoIT to take the Screen capture and send it to the server. I am doing this using multi-part form data. The problem is I don't know how to encode the binary data of the jpeg. Here's what I have so far: CODE #Include <ScreenCapture.au3> ;Capture the screen _ScreenCapture_Capture("c:\temp\" & @ComputerName & ".jpg") ;set up the http object $Http = ObjCreate("MSXML2.ServerXMLHTTP") $url = "http://localhost/perlex/blob.pl" $Http.open("POST", $url, true) $Http.setRequestHeader ("Content-Type","multipart/form-data; boundary=---------------------------7d92383a340dea") ;open the jpeg as binary $jpeg = fileopen("c:\temp\" & @ComputerName & ".jpg",16) $strPost1="-----------------------------7d92383a340dea" & @crlf & _ "Content-Disposition: form-data; name=""PC""" & @crlf & _ "" & @crlf & _ @ComputerName & @crlf & _ "-----------------------------7d92383a340dea" & @crlf & _ "Content-Disposition: form-data; name=""TheFile""; filename=""c:\temp\" & @ComputerName & ".jpg""" & @crlf & _ "Content-Type: image/pjpeg" & @crlf & _ "" & @crlf $binJPG = FileRead($jpeg) $strPost2= @crlf & @crlf & "-----------------------------7d92383a340dea" & @crlf $binPost1=stringtobinary($strPost1) $binPost2=stringtobinary($strPost2) $binPost = $binPost1 & $binJPG & $binPost2 $strPost = binarytostring($binPost) msgbox("","",$strPost) $Http.send($strPost) $post = fileopen("c:\temp\post.txt",18) filewrite($post,$strPost) msgbox("","",$Http.responseText) fileclose($post) fileclose($jpeg) $Http.abort() $Http = 0 The string $strPost seems to be truncated when I use it. Strangely, when I display the length of the string it is very long, but the contents written to post.txt are very small. If I can get this working it will be a nice little function! Thanks in advance! Link to comment Share on other sites More sharing options...
evilertoaster Posted January 15, 2009 Share Posted January 15, 2009 ServerXMLHTTP has a .open() method...so maybe you should use that instead of autoit's FileOpen() function to get the binary data... Humm just a guess though, i didn't look into it very throughly Link to comment Share on other sites More sharing options...
Niblob Posted January 16, 2009 Author Share Posted January 16, 2009 Thanks, but the .open method is what is used to send the post data. Actually I should have specified the error I get. It is "Malformed Multipart POST". If I take the $binJPG and set it to some string (instead of the contents of the JPG file), then the string gets written to a jpg file on the server. So really seems like there's a problem handling the binary stuff. I've been scratching my head for two days now - I would really appreciate someone taking a look! Link to comment Share on other sites More sharing options...
weaponx Posted January 16, 2009 Share Posted January 16, 2009 From what I can tell, these objects need files to be written as Byte arrays. I'm not sure how this is applies to AutoIt."winhttp.winhttprequest.5.1""MSXML2.XMLHTTP""MSXML2.ServerXMLHTTP"http://www.vbforums.com/showthread.php?t=451836http://groups.google.com/group/microsoft.p...91c66d695823322http://www.ericphelps.com/scripting/sample...b/HTTP_POST.txt Link to comment Share on other sites More sharing options...
ptrex Posted January 17, 2009 Share Posted January 17, 2009 @AllHave a look at the ADO.Stream object..I hope this gets you going.Regardsptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
cheatera Posted January 17, 2009 Share Posted January 17, 2009 (edited) <snipped> Edited January 17, 2009 by SmOke_N Is There A Life BEFORE Death?im stupidSaved warn logs: cheateraSmOke_N Note Added 17 January 2009 - 02:54 PM Added to warn level Posting a way to hack the registry and force sending someones desktop via TCP. Jos Note Added 25 November 2008 - 02:52 PM Added to warn level for being an impolite rookie.once a year i go bad ... what will happen in 2010??[u]Its GOOD to be BAD ... (Warlock's Succubus - World of Warcraft)[/u] Link to comment Share on other sites More sharing options...
Niblob Posted January 18, 2009 Author Share Posted January 18, 2009 Thanks for the tips. I managed to get it working. Unfortunately only in VBScript. You really have to jump through some hoops to get the binary stuff working. The problem with using VBScript is it has no self contained screen capture. I could of course call an AutoIT script to capture the screen to a file and then run the VBScript to send it to the server, but it's a little long-winded. The problem seems to be converting a string to binary. The function in VBScript looks like this: Function StringToBinary(S) Dim i, ByteArray For i=1 To Len(S) ByteArray = ByteArray & ChrB(Asc(Mid(S,i,1))) Next StringToBinary = ByteArray End Function You would think the AutoIT equivalent would be: Func myStringToBinary($S) Dim $i, $ByteArray For $i=1 To stringLen($S) $ByteArray = $ByteArray & chr(Binary(Asc(stringMid($S,$i,1)))) Next return $ByteArray Endfunc or Func myStringToBinary($S) Dim $i, $ByteArray For $i=1 To stringLen($S) $ByteArray = $ByteArray & Binary(Asc(stringMid($S,$i,1))) Next return $ByteArray Endfunc or just the StringToBinary function, but they don't do the same. Has anyone got any ideas? In case anyone is interested, the VBScript code looks like this: expandcollapse popupConst adLongVarBinary = 205 dim adodb set adodb=WScript.CreateObject("ADODB.Connection") Set rs = WScript.CreateObject("ADODB.Recordset") set inStream=WScript.CreateObject("ADODB.Stream") inStream.Open inStream.type=1 inStream.LoadFromFile("C:\blob.jpg") binJPG=inStream.Read() set objHttp = CreateObject("MSXML2.ServerXMLHTTP") set fs = CreateObject("Scripting.FileSystemObject") url = "http://localhost/perlex/blob.pl" objHttp.open "POST", url, false objHttp.setRequestHeader "Content-Type","multipart/form-data; boundary=---------------------------7d92383a340dea" strPost1="-----------------------------7d92383a340dea" & vbcrlf & _ "Content-Disposition: form-data; name=""PC""" & vbcrlf & _ "" & vbcrlf & _ "Computer" & vbcrlf & _ "-----------------------------7d92383a340dea" & vbcrlf & _ "Content-Disposition: form-data; name=""TheFile""; filename=""c:\test.jpg""" & vbcrlf & _ "Content-Type: image/pjpeg" & vbcrlf & _ "Content-Transfer-Encoding: binary" & vbcrlf & _ "" & vbcrlf strPost2= vbcrlf & vbcrlf & "-----------------------------7d92383a340dea" & vbcrlf rs.Fields.Append "FormData", adLongVarBinary, Len(strPost1) + LenB(binJPG) + Len(strPost2) rs.Open rs.AddNew rs("FormData").AppendChunk StringToBinary(strPost1) & ChrB(0) binPost1 = rs("formData").GetChunk(Len(strPost1)) rs("FormData") = "" rs("FormData").AppendChunk StringToBinary(strPost2) & ChrB(0) binPost2 = rs("formData").GetChunk(Len(strPost2)) rs("FormData") = "" rs("FormData").AppendChunk binPost1 rs("FormData").AppendChunk binJPG rs("FormData").AppendChunk binPost2 binPost = rs("FormData") rs.Close 'strPost = StringToBinary(strPost1) & binJPG & StringToBinary(strPost2) 'msgbox(binPost) objHttp.send binPost msgbox(objHttp.responseText) objHttp.abort() set objHttp = nothing Function StringToBinary(S) Dim i, ByteArray For i=1 To Len(S) ByteArray = ByteArray & ChrB(Asc(Mid(S,i,1))) Next StringToBinary = ByteArray End Function Link to comment Share on other sites More sharing options...
weaponx Posted January 20, 2009 Share Posted January 20, 2009 I attempted to convert the VBS file but it still has errors. It works fine in VB: Line 96: No such interface supported expandcollapse popup$oMyError = ObjEvent("AutoIt.Error","ComErrHandler") $filename = "C:\picture.jpg" $result = upload('http://www.server.org/test.php', $filename, "uploaded_file") ConsoleWrite("responseText: " & $result) Func Upload($strUploadUrl, $strFilePath, $strFileField, $strDataPairs = "") ;Uses POST to upload a file and miscellaneous form data ;strUploadUrl is the URL (http://127.0.0.1/cgi-bin/upload.exe) ;strFilePath is the file to upload (C:\My Documents\test.zip) ;strFileField is the web page equivalent form field name for the file (File1) ;strDataPairs are pipe-delimited form data pairs (foo=bar|snap=crackle) Const $MULTIPART_BOUNDARY = "---------------------------0123456789012" Dim $ado, $rs Dim $lngCount Dim $bytFormData, $bytFormStart, $bytFormEnd, $bytFile Dim $strFormStart = "", $strFormEnd, $strDataPair Dim $web Const $adLongVarBinary = 205 ;Read the file into a byte array Local $ado = ObjCreate("ADODB.Stream") $ado.Type = 1 $ado.Open $ado.LoadFromFile ($strFilePath) $bytFile = $ado.Read $ado.Close ;Create the multipart form data. ;Define the end of form $strFormEnd = @CRLF & "--" & $MULTIPART_BOUNDARY & "--" & @CRLF ;First add any ordinary form data pairs If $strDataPairs <> "" Then For $strDataPair In StringSplit($strDataPairs, "|", 2) $strFormStart &= "--" & $MULTIPART_BOUNDARY & @CRLF $strFormStart &= "Content-Disposition: form-data; " $aTemp = StringSplit($strDataPair, "=", 2) $strFormStart &= 'name="' & $aTemp[0] & '"' $strFormStart &= @CRLF & @CRLF ;$aTemp = StringSplit($strDataPair, "=", 2) $strFormStart &= $aTemp[1] $strFormStart &= @CRLF Next EndIf ;Now add the header for the uploaded file $strFormStart &= "--" & $MULTIPART_BOUNDARY & @CRLF $strFormStart &= "Content-Disposition: form-data; " $strFormStart &= 'name="' & $strFileField & '"; ' $strFormStart &= 'filename="' & StringMid($strFilePath, StringInStr($strFilePath, "\",0,-1) + 1) & '"' $strFormStart &= @CRLF $strFormStart &= "Content-Type: application/upload" ;'bogus, but it works $strFormStart &= @CRLF & @CRLF ;Create a recordset large enough to hold everything Local $rs = ObjCreate("ADODB.Recordset") $rs.Fields.Append ("FormData", $adLongVarBinary, StringLen($strFormStart) + BinaryLen($bytFile) + StringLen($strFormEnd)) ;LenB FIXED $rs.Open $rs.AddNew ;Convert form data so far to zero-terminated byte array For $lngCount = 1 To StringLen($strFormStart) $bytFormStart &= ChrB(Asc(StringMid($strFormStart, $lngCount, 1))) ;ChrB Next $rs("FormData").AppendChunk ($bytFormStart & ChrB(0)) ;ChrB $bytFormStart = $rs("formData").GetChunk(StringLen($strFormStart)) $rs("FormData") = "" ;Get the end boundary as a zero-terminated byte array For $lngCount = 1 To StringLen($strFormEnd) $bytFormEnd &= ChrB(Asc(StringMid($strFormEnd, $lngCount, 1))) ;ChrB Next $rs("FormData").AppendChunk ($bytFormEnd & ChrB(0)) ;ChrB $bytFormEnd = $rs("formData").GetChunk(StringLen($strFormEnd)) $rs("FormData") = "" ;Now merge it all $rs("FormData").AppendChunk ($bytFormStart) $rs("FormData").AppendChunk ($bytFile) $rs("FormData").AppendChunk ($bytFormEnd) $bytFormData = $rs("FormData") $rs.Close ;ConsoleWrite($bytFormData) ;Return ;Upload it Local $web = ObjCreate("winhttp.winhttprequest.5.1") ;Local $web = ObjCreate("MSXML2.XMLHTTP") $web.Open ("POST", $strUploadUrl, false) $web.SetRequestHeader ("Content-Type", "multipart/form-data; boundary=" & $MULTIPART_BOUNDARY) $web.Send($bytFormData) ;FAILURE Return $web.ResponseText EndFunc Func ChrB($iCode) ;Return StringToBinary(Chr($iCode)) ;Return Binary(Chr($iCode)) Return Chr($iCode) EndFunc Func ComErrHandler() $HexNumber = Hex($oMyError.number, 8) MsgBox(0, "COM Error", "COM Error Details:" & @CRLF & @CRLF & _ "err.description is: " & @TAB & $oMyError.description & @CRLF & _ "err.windescription:" & @TAB & $oMyError.windescription & @CRLF & _ "err.number is: " & @TAB & $HexNumber & @CRLF & _ "err.lastdllerror is: " & @TAB & $oMyError.lastdllerror & @CRLF & _ "err.scriptline is: " & @TAB & $oMyError.scriptline & @CRLF & _ "err.source is: " & @TAB & $oMyError.source & @CRLF & _ "err.helpfile is: " & @TAB & $oMyError.helpfile & @CRLF & _ "err.helpcontext is: " & @TAB & $oMyError.helpcontext _ ) SetError(1) EndFunc ;==>ComErrHandler Link to comment Share on other sites More sharing options...
Niblob Posted January 21, 2009 Author Share Posted January 21, 2009 The same result as me. I really appreciate you having at look at it though. I was a bit surprised that when I put the following line in before the send: msgbox("","",BinaryLen($bytFormData)) I get zero returned. Could it be some kind of bug in the way AutoIT is handling the binary data? I'm not that up on binary stuff so it's a bit tricky for me to diagnose. Anyway, it looks as if I will install Snagit on all the PCs and run the VBScript version on them. Ho Hum! Thanks again for taking a look at it. Jean-Pierre Link to comment Share on other sites More sharing options...
weaponx Posted January 21, 2009 Share Posted January 21, 2009 You could always POST using the IE functions. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now