Sign in to follow this  
Followers 0
erifash

Download Manager

8 posts in this topic

I got tired of all the other download managers I have found so I decided to write my own. I have the GUI completely done and a couple of other functions too. The only problem I am having is with incomplete downloads. I would like to be able to start a download on my thumb drive, pause the download, then complete it on a different computer. In other words, how can I handle incomplete downloads? Here is the GUI:

#NoTrayIcon
#include <GUIConstants.au3>
#include <GUIListView.au3>

Global Const $WM_NOTIFY = 0x004E
Global Const $NM_DBLCLK = -3

Opt("GUIResizeMode", 1)
Opt("GUIOnEventMode", 1)

_Exist("Download Manager")

Global $oErr = ObjEvent("AutoIt.Error", "_ErrorHandler")
$shell32 = @SystemDir & "\shell32.dll"

$gui = GUICreate("Download Manager", 540, 160, Default, Default, $WS_OVERLAPPEDWINDOW)

$start = GUICtrlCreateButton("Start", 0, 0, 20, 20, $BS_ICON)
GUICtrlSetImage(-1, $shell32, 176, 0)
GUICtrlSetTip(-1, "Start download")
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetOnEvent(-1, "_EventHandler")

$pause = GUICtrlCreateButton("Pause", 20, 0, 20, 20, $BS_ICON)
GUICtrlSetImage(-1, $shell32, 112, 0)
GUICtrlSetTip(-1, "Pause download")
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetOnEvent(-1, "_EventHandler")

$add = GUICtrlCreateButton("Add", 40, 0, 20, 20, $BS_ICON)
GUICtrlSetImage(-1, $shell32, 155, 0)
GUICtrlSetTip(-1, "Add new download")
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetOnEvent(-1, "_EventHandler")

$remove = GUICtrlCreateButton("Remove", 60, 0, 20, 20, $BS_ICON)
GUICtrlSetImage(-1, $shell32, 109, 0)
GUICtrlSetTip(-1, "Remove selected download")
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetOnEvent(-1, "_EventHandler")

$prefs = GUICtrlCreateButton("Preferences", 80, 0, 20, 20, $BS_ICON)
GUICtrlSetImage(-1, $shell32, 126, 0)
GUICtrlSetTip(-1, "Edit preferences")
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetOnEvent(-1, "_EventHandler")

$progress = GUICtrlCreateProgress(100, 0, 440, 20)
GUICtrlSetResizing(-1, $GUI_DOCKHEIGHT + $GUI_DOCKLEFT + $GUI_DOCKRIGHT)

$list = GUICtrlCreateListView("Name|Status|Remaining|Speed", 0, 20, 540, 120, $LVS_SHOWSELALWAYS, $LVS_EX_GRIDLINES)
GUICtrlSetResizing(-1, $GUI_DOCKBORDERS)
_GUICtrlListViewSetColumnWidth(-1, 0, 240)
_GUICtrlListViewSetColumnWidth(-1, 1, 80)
_GUICtrlListViewSetColumnWidth(-1, 2, 105)
_GUICtrlListViewSetColumnWidth(-1, 3, 90)

$status = GUICtrlCreateInput("0 downloading; 0 files; 0 KB/s total", 0, 140, 540, 20)
GUICtrlSetResizing(-1, $GUI_DOCKHEIGHT + $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM)

GUISetOnEvent($GUI_EVENT_CLOSE, "_EventHandler", $gui)
GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")

GUICtrlSetState($status, $GUI_DISABLE)
GUICtrlSetState($list, $GUI_FOCUS)
GUISetState()

While 1
   _ReduceMemory()
   Sleep(5000)
WEnd

Func WM_Notify_Events( $hWndGUI, $MsgID, $wParam, $lParam )
   #forceref $hWndGUI, $MsgID, $wParam
   Local $tagNMHDR, $event, $hwndFrom, $code
   $tagNMHDR = DllStructCreate("int;int;int", $lParam)
   If @error Then Return
   $event = DllStructGetData($tagNMHDR, 3)
   Select
      Case $wParam = $list
         Select
            Case $event = $NM_DBLCLK
               _ListEventHandler(_GUICtrlListViewGetItemText($list, _GUICtrlListViewGetSelectedIndices($list)))
         EndSelect
   EndSelect
   $tagNMHDR = 0
   $event = 0
   $lParam = 0
EndFunc

Func _EventHandler()
   Switch @GUI_CtrlId
      Case $GUI_EVENT_CLOSE
         Exit
      Case $start
         MsgBox(0, "Event", GUICtrlRead(@GUI_CtrlId))
      Case $pause
         MsgBox(0, "Event", GUICtrlRead(@GUI_CtrlId))
      Case $add
         MsgBox(0, "Event", GUICtrlRead(@GUI_CtrlId))
      Case $remove
         MsgBox(0, "Event", GUICtrlRead(@GUI_CtrlId))
      Case $prefs
         MsgBox(0, "Event", GUICtrlRead(@GUI_CtrlId))
   EndSwitch
EndFunc

Func _ListEventHandler( $text )
   $text = StringSplit($text, "|")
   If @error or $text[1] = "" Then Return
   MsgBox(0, "Event", $text[1])
EndFunc

Func _ErrorHandler()
   MsgBox(0x41030, "COM Error", "Intercepted COM Error :" & @CRLF & @CRLF & _
      "err.description is: " & @TAB & $oErr.description & @CRLF & _
      "err.windescription:" & @TAB & $oErr.windescription & @CRLF & _
      "err.number is: " & @TAB & Hex($oErr.number, 8) & @CRLF & _
      "err.lastdllerror is: " & @TAB & $oErr.lastdllerror & @CRLF & _
      "err.scriptline is: " & @TAB & $oErr.scriptline & @CRLF & _
      "err.source is: " & @TAB & $oErr.source & @CRLF & _
      "err.helpfile is: " & @TAB & $oErr.helpfile & @CRLF & _
      "err.helpcontext is: " & @TAB & $oErr.helpcontext _
   )
   SetError(1)
EndFunc

Func _Exist( $str, $fatal = 1 )
   Local $h = DllCall("kernel32.dll", "int", "CreateMutex", "int", 0, "long", 1, "str", StringReplace($str, "\", "..")), $l = DllCall("kernel32.dll", "int", "GetLastError")
   If $l[0] = 183 and $fatal Then Exit
   SetError($l[0])
   Return $h[0]
EndFunc

Func _Error( $sText, $iFatal = 0, $sTitle = "Error", $iOpt = 0x41030 )
   Local $ret = MsgBox($iOpt, $sTitle, $sText)
   If $iFatal Then Exit
   Return SetError(1, 0, $ret)
EndFunc

Func _ReduceMemory( $pid = -1, $psapi = "psapi.dll", $kernel32 = "kernel32.dll" )
   If $pid = -1 Then
      Local $ret = DllCall($psapi, "int", "EmptyWorkingSet", "long", -1)
   Else
      Local $hwnd = DllCall($kernel32, "int", "OpenProcess", "int", 0x1F0FFF, "int", 0, "int", $pid)
      Local $ret = DllCall($psapi, "int", "EmptyWorkingSet", "long", $hwnd[0])
      DllCall($kernel32, "int", "CloseHandle", "int", $hwnd[0])
   EndIf
   Return $ret[0]
EndFunc

Func _ByteFormat( $bytes, $decimal = 0 )
   Local $i = 0, $word[5] = [" B", " KB", " MB", " GB", " TB"]
   While $bytes < 1024
      $bytes /= 1024
   WEnd
   Return Round($bytes, $decimal) & $word[$i]
EndFunc

Thanks! :whistle:

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

@lod3n: Thanks for that bit of information, it helped a lot. :lmao:

I wanted to do it in pure AutoIt so I discovered that "partial content" is already built into the HTTP protocol. I scripted a small tcp listener set to port 80 and used a download manager to try and download an imaginary "file" off my imaginary "server." Here is the header that it sent:

GET /woot.txt HTTP/1.0

Referer: http://x.x.x.x/woot.txt

Range: bytes=0-

User-Agent: Web Download

Host: x.x.x.x

Pragma: no-cache

I decided to give this header a test run so I wrote a script to start/resume a download of a large file (123 MB). Here it is:

; try to start (or resume) the download of
; http://61.74.68.173/GIS/Gunbound_GIS_WC_545.exe
; which is 123 MB in size so it should be good for testing

$file = @ScriptDir & "\Gunbound_GIS_WC_545.exe"
If FileExists($file) Then
    $bytes = FileGetSize($file)
Else
    $bytes = 0
EndIf

TCPStartup()

$conn = TCPConnect("61.74.68.173", 80)
If $conn = -1 or @error Then Exit

$h  = "GET /GIS/Gunbound_GIS_WC_545.exe HTTP/1.0" & @CRLF
$h &= "Referer: http://61.74.68.173/GIS/Gunbound_GIS_WC_545.exe" & @CRLF
$h &= "Range: bytes=" & $bytes & "-" & @CRLF
$h &= "User-Agent: AutoIt3" & @CRLF
$h &= "Host: " & @IPAddress1 & @CRLF
$h &= "Pragma: no-cache" & @CRLF
$h &= @CRLF
TCPSend($conn, $h)

$listen = TCPListen(@IPAddress1, 80)

While 1
    $sock = TCPAccept($listen)
    If $sock > -1 Then
        $data = ""
        While not @error
            FileWrite($file, $data)
            $data = TCPRecv($sock, 2048)
        WEnd
        TCPCloseSocket($sock)
    EndIf
    Sleep(50)
WEnd

... and it doesn't work :evil:

If anyone would care to try and help me fix this it would be great! ;)

EDIT: Nevermind, I figured it out.

Edited by erifash

Share this post


Link to post
Share on other sites

EDIT: Nevermind, I figured it out.

Hi erifash,

If you are done with the project, can you please post the script so that I can use it, if you don't mind?

Thanks and Regards,

Vinod Kumar

Share this post


Link to post
Share on other sites

Hi your Downloadmanager looks very nice :)

I was wondering if you ever finished your functions like pause & resume?

If yes could you share it with us all?

thx alot

Share this post


Link to post
Share on other sites

I got tired of all the other download managers I have found so I decided to write my own.

I guess you got tired of this one as well?

Share this post


Link to post
Share on other sites

EDIT: Nevermind, I figured it out.

I know this was a while ago, but what was fixed to make this work?

Thanks

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0