Что нового

Нужен набор-аналог к Inet* функциям

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Основная потребность таких функции, заключается в том, чтобы иметь возможность ставить на паузу список закачек (естественно с выводом прогресса).

Кто то видел что то подобное? :scratch:

Рассмотрю как вариант - временный запрет на выход в сеть для своего приложения (правда не уверен как оно скажется на возобновление закачек).
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR,
ИМХО, можно написать UDF с таким функционалом на основе WinHttp.au3 (на оф.форуме тема: WinHTTP functions).
Или на основе TCP* функций?
 

Naisho

Знающий
Сообщения
86
Репутация
12
На оффоруме есть FF.au3 с дополнениями _FF_DM.au3 и FFF.au3 - в сумме позволяют делать всё обозначенное, разве что индивидуальный прогресс остаётся за кадром.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
madmasles [?]
Или на основе TCP* функций?
Вот всё пытаюсь...
Пока остановился на сложности определить метод записи в файл (бинарный или нет, кодировка и т.д.)...
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Докачка возможна если сервер её позволяет. Вот пример получения файла с помощью TCP*. Вроде реализуемо.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
sngr [?]
Докачка возможна если сервер её позволяет
Это из наименьших трудностей.
Получать файлы у меня получилось, вот трудность в их сохранении, в определений кодировки и типа содержимого...
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
В общем вот что пока получилось...

Набросок библиотеки (TCPInet.au3):
Код:
#include-once
#include <FileConstants.au3>
#include <InetConstants.au3>
#include <WinAPIEx.au3>

Global $bTCPINET_INITIALIZED		= False
Global $iTCPINET_OPTTTO				= 100
Global $aTCPINET_DATA[1][1]
Global Enum _
	$iTI_DATA_iSOCKET, $iTI_DATA_hFILE, $iTI_DATA_sFILE, $iTI_DATA_iREAD, $iTI_DATA_iSIZE, $iTI_DATA_bCOMPLETE, $iTI_DATA_bPAUSED, _
	$iTI_DATA_iTOTAL

Global Const $INET_DOWNLOADPAUSED 	= 3

Global Const $sTCPINET_UA			= 'Mozilla/5.0 (Windows NT 6.1; rv:27.0) Gecko/20100101 Firefox/27.0'
Global Const $iTCPINET_MAXBYTES		= 1024
Global Const $iTCPINET_TIMEOUT		= 10000
Global Const $iTCPINET_PORT			= 80

Func _TCPInet_GetFile($sURL, $sFile, $iBackground = $INET_DOWNLOADWAIT)
	__TCPInet_Init()
	
	Local $aHostPage = __TCPInet_SplitURL($sURL)
	Local $sHost = $aHostPage[0], $sPage = $aHostPage[1]
	Local $iSocket = __TCPInet_Connect($sHost)
	
	If @error Then
		Return SetError(1, 0, 0)
	EndIf
	
	__TCPInet_Request($sHost, $sPage, $iSocket, 'GET')
	
	If @error Then
		TCPCloseSocket($iSocket)
		Return SetError(2, 0, 0)
	EndIf
	
	Local $iFO_Flags = $FO_OVERWRITE
	Local $sHeader = __TCPInet_GetHeader($sHost, $sPage)
	Local $sContent_Type = __TCPInet_GetTagHeader($sHeader, 'Content-Type')
	Local $iContent_Length = Number(__TCPInet_GetTagHeader($sHeader, 'Content-Length'))
	
	If _WinAPI_PathIsDirectory($sFile) Then
		$sFile &= '\' & __TCPInet_GetValidFileName(StringRegExpReplace($sURL, '^.*/', ''))
	ElseIf _WinAPI_PathIsFileSpec($sFile) Then
		$sFile = __TCPInet_GetValidFileName(StringRegExpReplace($sURL, '^.*/', ''))
	EndIf
	
	If Not StringRegExp($sHeader, '(?i)^HTTP/\d.\d 200 OK') Then
		Return SetError(3, 0, 0)
	EndIf
	
	If StringInStr($sContent_Type, 'charset=UTF-8') Then
		$iFO_Flags = BitOR($iFO_Flags, $FO_UTF8)
	EndIf
	
	Local $sData, $hFile = FileOpen($sFile, $iFO_Flags)
	
	If $iBackground = $INET_DOWNLOADBACKGROUND Then
		$aTCPINET_DATA[0][0] += 1
		ReDim $aTCPINET_DATA[$aTCPINET_DATA[0][0] + 1][$iTI_DATA_iTOTAL]
		
		$aTCPINET_DATA[$aTCPINET_DATA[0][0]][$iTI_DATA_iSOCKET] = $iSocket
		$aTCPINET_DATA[$aTCPINET_DATA[0][0]][$iTI_DATA_hFILE] = $hFile
		$aTCPINET_DATA[$aTCPINET_DATA[0][0]][$iTI_DATA_sFILE] = $sFile
		$aTCPINET_DATA[$aTCPINET_DATA[0][0]][$iTI_DATA_iSIZE] = $iContent_Length
		$aTCPINET_DATA[$aTCPINET_DATA[0][0]][$iTI_DATA_bCOMPLETE] = False
		$aTCPINET_DATA[$aTCPINET_DATA[0][0]][$iTI_DATA_bPAUSED] = False
		
		AdlibRegister('__TCPInet_SetDataProc', 1)
		Return $aTCPINET_DATA[0][0]
	EndIf
	
	While 1
		$sData = TCPRecv($iSocket, $iTCPINET_MAXBYTES)
		
		If @error <> 0 Then
			ExitLoop
		EndIf
		
		FileWrite($hFile, $sData)
	WEnd
	
	TCPCloseSocket($iSocket)
	FileClose($hFile)
	
	$sRead = StringRegExpReplace(FileRead($sFile), '(?s)^.*?\r\n\r\n', '')
	
	$hFile = FileOpen($sFile, 2 + FileGetEncoding($sFile))
	FileWrite($hFile, $sRead)
	FileClose($hFile)
	
	Return 1
EndFunc

Func _TCPInet_GetSize($sURL)
	__TCPInet_Init()
	
	Local $aHostPage = __TCPInet_SplitURL($sURL)
	Local $sHost = $aHostPage[0], $sPage = $aHostPage[1]
	Local $sHeader = __TCPInet_GetHeader($sHost, $sPage)
	
	If @error Then
		Return SetError(1, 0, 0)
	EndIf
	
	Local $iContent_Lenght = __TCPInet_GetTagHeader($sHeader, 'Content-Length')
	
	If @error Then
		Return SetError(2, 0, 0)
	EndIf
	
	Return Number($iContent_Lenght)
EndFunc

Func _TCPInet_GetInfo($hTCPInet, $iIndex = -1)
	If $hTCPInet > $aTCPINET_DATA[0][0] Or $hTCPInet < 1 Then
		Return SetError(1, 0, '')
	EndIf
	
	Local $aRet[4] = [$aTCPINET_DATA[$hTCPInet][$iTI_DATA_iREAD], $aTCPINET_DATA[$hTCPInet][$iTI_DATA_iSIZE], $aTCPINET_DATA[$hTCPInet][$iTI_DATA_bCOMPLETE], $aTCPINET_DATA[$hTCPInet][$iTI_DATA_bPAUSED]]
	
	If $iIndex = -1 Then
		Return $aRet
	Else
		If $iIndex >= 0 And $iIndex <= 4 Then
			Return $aRet[$iIndex]
		EndIf
	EndIf
	
	Return SetError(2, 0, '')
EndFunc

Func _TCPInet_Close($hTCPInet)
	Local $aTmp[1][1]
	
	For $i = 1 To $aTCPINET_DATA[0][0]
		If $i <> $hTCPInet Then
			$aTmp[0][0] += 1
			ReDim $aTmp[$aTmp[0][0] + 1][$iTI_DATA_iTOTAL]
			
			$aTmp[$aTmp[0][0]][$iTI_DATA_iSOCKET] = $aTCPINET_DATA[$i][$iTI_DATA_iSOCKET]
			$aTmp[$aTmp[0][0]][$iTI_DATA_hFILE] = $aTCPINET_DATA[$i][$iTI_DATA_hFILE]
			$aTmp[$aTmp[0][0]][$iTI_DATA_sFILE] = $aTCPINET_DATA[$i][$iTI_DATA_sFILE]
			$aTmp[$aTmp[0][0]][$iTI_DATA_iREAD] = $aTCPINET_DATA[$i][$iTI_DATA_iREAD]
			$aTmp[$aTmp[0][0]][$iTI_DATA_iSIZE] = $aTCPINET_DATA[$i][$iTI_DATA_iSIZE]
			$aTmp[$aTmp[0][0]][$iTI_DATA_bCOMPLETE] = $aTCPINET_DATA[$i][$iTI_DATA_bCOMPLETE]
			$aTmp[$aTmp[0][0]][$iTI_DATA_bPAUSED] = $aTCPINET_DATA[$i][$iTI_DATA_bPAUSED]
		Else
			TCPCloseSocket($aTCPINET_DATA[$i][$iTI_DATA_iSOCKET])
			FileClose($aTCPINET_DATA[$i][$iTI_DATA_hFILE])
		EndIf
	Next
	
	If $aTmp[0][0] = 0 Then
		AdlibUnRegister('__TCPInet_SetDataProc')
		__TCPInet_UnInit()
	EndIf
	
	$aTCPINET_DATA = $aTmp
EndFunc

Func _TCPInet_SetPause($hTCPInet, $bPause = True)
	If $hTCPInet > $aTCPINET_DATA[0][0] Or $hTCPInet < 1 Then
		Return SetError(1, 0, '')
	EndIf
	
	$aTCPINET_DATA[$hTCPInet][$iTI_DATA_bPAUSED] = $bPause
EndFunc

Func __TCPInet_Init()
	If Not $bTCPINET_INITIALIZED Then
		$bTCPINET_INITIALIZED = True
		$iTCPINET_OPTTTO = Opt('TCPTimeOut', $iTCPINET_TIMEOUT)
		TCPStartup()
	EndIf
EndFunc

Func __TCPInet_UnInit()
	If $bTCPINET_INITIALIZED Then
		$bTCPINET_INITIALIZED = False
		Opt('TCPTimeOut', $iTCPINET_OPTTTO)
		TCPShutdown()
	EndIf
EndFunc

Func __TCPInet_SetDataProc()
	For $i = 1 To $aTCPINET_DATA[0][0]
		If $aTCPINET_DATA[$i][$iTI_DATA_bCOMPLETE] Or $aTCPINET_DATA[$i][$iTI_DATA_bPAUSED] Then
			ContinueLoop
		EndIf
		
		$iSocket = $aTCPINET_DATA[$i][$iTI_DATA_iSOCKET]
		$hFile = $aTCPINET_DATA[$i][$iTI_DATA_hFILE]
		$sFile = $aTCPINET_DATA[$i][$iTI_DATA_sFILE]
		
		$sData = TCPRecv($iSocket, $iTCPINET_MAXBYTES)
		
		If @error <> 0 Then
			$aTCPINET_DATA[$i][$iTI_DATA_bCOMPLETE] = True
			TCPCloseSocket($iSocket)
			FileClose($hFile)
			
			$sRead = StringRegExpReplace(FileRead($sFile), '(?s)^.*?\r\n\r\n', '', 1)
			
			$hFile = FileOpen($sFile, 2 + FileGetEncoding($sFile))
			FileWrite($hFile, $sRead)
			FileClose($hFile)
			
			ContinueLoop
		EndIf
		
		$aTCPINET_DATA[$i][$iTI_DATA_iREAD] += $iTCPINET_MAXBYTES
		
		If $aTCPINET_DATA[$i][$iTI_DATA_iSIZE] > 0 And $aTCPINET_DATA[$i][$iTI_DATA_iREAD] > $aTCPINET_DATA[$i][$iTI_DATA_iSIZE] Then
			$aTCPINET_DATA[$i][$iTI_DATA_iREAD] = $aTCPINET_DATA[$i][$iTI_DATA_iSIZE]
		EndIf
		
		FileWrite($hFile, $sData)
	Next
EndFunc

Func __TCPInet_Connect($sHost)
	Local $sName_To_IP = TCPNameToIP($sHost)
	Local $iSocket = TCPConnect($sName_To_IP, $iTCPINET_PORT)
	
	If $iSocket = -1 Then
		TCPCloseSocket($iSocket)
		Return SetError(1, 0, '')
	EndIf
	
	Return $iSocket
EndFunc

Func __TCPInet_Request($sHost, $sPage, $iSocket, $sRequest = 'GET', $sReferrer = '')
	Local $sCommand = ''
	
	$sCommand &= $sRequest & ' ' & $sPage & ' HTTP/1.0' & @CRLF
	$sCommand &= 'Host: ' & $sHost & @CRLF
	$sCommand &= 'User-Agent: ' & $sTCPINET_UA & @CRLF
	$sCommand &= 'Referer: ' & $sReferrer & @CRLF
	$sCommand &= 'Connection: close' & @CRLF & @CRLF
	
	Local $iBytesSent = TCPSend($iSocket, $sCommand)
	
	If $iBytesSent = 0 Then
		Return SetError(1, @error, 0)
	EndIf
	
	Return $iBytesSent
EndFunc

Func __TCPInet_GetHeader($sHost, $sPage)
	Local $sData, $iSocket = __TCPInet_Connect($sHost)
	
	If @error Then
		Return SetError(1, 0, '')
	EndIf
	
	__TCPInet_Request($sHost, $sPage, $iSocket, 'HEAD')
	
	If @error Then
		Return SetError(2, 0, '')
	EndIf
	
	While 1
		$sData &= TCPRecv($iSocket, $iTCPINET_MAXBYTES)
		
		If @error <> 0 Then
			ExitLoop
		EndIf
	WEnd
	
	TCPCloseSocket($iSocket)
	
	Return $sData
EndFunc

Func __TCPInet_GetTagHeader($sHeader, $sTag)
	Local $aRet = StringRegExp($sHeader, '(?i)' & $sTag & ': ([^\r\n]+)', 3)
	
	If @error Or Not IsArray($aRet) Then
		Return SetError(1, 0, '')
	EndIf
	
	Return $aRet[0]
EndFunc

Func __TCPInet_SplitURL($sURL)
	Local $aHostPage[2]
	
	$aHostPage[0] = _WinAPI_UrlGetPart($sURL, $URL_PART_HOSTNAME)
	$aHostPage[1] = StringRegExpReplace($sURL, '(?is).*?' & $aHostPage[0] & '(.*?)$', '\1')
	$aHostPage[1] = '/' & StringRegExpReplace($aHostPage[1], '^/+', '')
	
	Return $aHostPage
EndFunc

Func __TCPInet_GetValidFileName($sString, $sPattern = '[*?\\/|:<>"]', $sReplace = '_')
	If StringStripWS($sString, 8) = '' Then Return $sString
	
	$sString = StringRegExpReplace($sString, $sPattern, $sReplace)
	Return SetExtended(@extended, StringRegExpReplace($sString, '(' & $sReplace & '+)', $sReplace))
EndFunc

Пример:
Код:
#include <GUIConstantsEx.au3>
#include 'TCPInet.au3'

Global $iPause1_Bttn, $iPause2_Bttn, $hTCPInet1, $hTCPInet2

$sURL1 = 'http://creator-lab.ucoz.ru/Music/bolot.mp3'
$sURL2 = 'http://creator-lab.ucoz.ru/Testing_Zone/Gulietta_Drama.7z'

$hGUI = GUICreate('_TCPInet Example', 500, 220)

GUICtrlCreateLabel('URL #1:', 20, 20)
$iURL1_Input = GUICtrlCreateInput($sURL1, 20, 40, 290, 20)
$iProgress1_Label = GUICtrlCreateLabel('0%', 320, 43, 170, 15)
$iPause1_Bttn = GUICtrlCreateButton('Pause', 20, 60, 60, 20)

GUICtrlCreateLabel('URL #2:', 20, 100)
$iURL2_Input = GUICtrlCreateInput($sURL2, 20, 120, 290, 20)
$iProgress2_Label = GUICtrlCreateLabel('0%', 320, 123, 170, 15)
$iPause2_Bttn = GUICtrlCreateButton('Pause', 20, 140, 60, 20)

$iDownload_Bttn = GUICtrlCreateButton('Download', 20, 190, 70, 20)

GUISetState(@SW_SHOW, $hGUI)

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $iDownload_Bttn
			$sPath = FileSelectFolder('Save to...', '', 0, @DesktopDir, $hGUI)
			If @error Then ContinueLoop
			
			Opt('GUIOnEventMode', 1)
			
			GUICtrlSetOnEvent($iPause1_Bttn, '_Pause_Events')
			GUICtrlSetOnEvent($iPause2_Bttn, '_Pause_Events')
			
			GUICtrlSetState($iURL1_Input, $GUI_DISABLE)
			GUICtrlSetState($iURL2_Input, $GUI_DISABLE)
			GUICtrlSetState($iDownload_Bttn, $GUI_DISABLE)
			
			$hTCPInet1 = _TCPInet_GetFile($sURL1, $sPath, $INET_DOWNLOADBACKGROUND)
			$hTCPInet2 = _TCPInet_GetFile($sURL2, $sPath, $INET_DOWNLOADBACKGROUND)
			
			While 1
				$aInfo1 = _TCPInet_GetInfo($hTCPInet1, -1)
				$aInfo2 = _TCPInet_GetInfo($hTCPInet2, -1)
				
				If $aInfo1[$INET_DOWNLOADCOMPLETE] And $aInfo2[$INET_DOWNLOADCOMPLETE] Then
					ExitLoop
				EndIf
				
				If Not $aInfo1[$INET_DOWNLOADCOMPLETE] And Not $aInfo1[$INET_DOWNLOADPAUSED] Then
					_GUICtrlSetData($iProgress1_Label, StringFormat('%i% (%i/%i)', (100 / ($aInfo1[$INET_DOWNLOADSIZE] / $aInfo1[$INET_DOWNLOADREAD])), $aInfo1[$INET_DOWNLOADREAD], $aInfo1[$INET_DOWNLOADSIZE]))
				EndIf
				
				If Not $aInfo2[$INET_DOWNLOADCOMPLETE] And Not $aInfo2[$INET_DOWNLOADPAUSED] Then
					_GUICtrlSetData($iProgress2_Label, StringFormat('%i% (%i/%i)', (100 / ($aInfo2[$INET_DOWNLOADSIZE] / $aInfo2[$INET_DOWNLOADREAD])), $aInfo2[$INET_DOWNLOADREAD], $aInfo2[$INET_DOWNLOADSIZE]))
				EndIf
			WEnd
			
			_TCPInet_Close($hTCPInet1)
			_TCPInet_Close($hTCPInet2)
			
			GUICtrlSetState($iURL1_Input, $GUI_ENABLE)
			GUICtrlSetState($iURL2_Input, $GUI_ENABLE)
			GUICtrlSetState($iDownload_Bttn, $GUI_ENABLE)
			
			GUICtrlSetData($iPause1_Bttn, 'Pause')
			GUICtrlSetData($iPause2_Bttn, 'Pause')
			
			Opt('GUIOnEventMode', 0)
	EndSwitch
WEnd

Func _Pause_Events()
	Switch @GUI_CtrlId
		Case $iPause1_Bttn
			If _TCPInet_GetInfo($hTCPInet1, $INET_DOWNLOADPAUSED) Then
				_TCPInet_SetPause($hTCPInet1, False)
				GUICtrlSetData($iPause1_Bttn, 'Pause')
			Else
				_TCPInet_SetPause($hTCPInet1, True)
				GUICtrlSetData($iPause1_Bttn, 'Resume')
			EndIf
		Case $iPause2_Bttn
			If _TCPInet_GetInfo($hTCPInet2, $INET_DOWNLOADPAUSED) Then
				_TCPInet_SetPause($hTCPInet2, False)
				GUICtrlSetData($iPause2_Bttn, 'Pause')
			Else
				_TCPInet_SetPause($hTCPInet2, True)
				GUICtrlSetData($iPause2_Bttn, 'Resume')
			EndIf
	EndSwitch
EndFunc

Func _GUICtrlSetData($iCtrlID, $sData)
	If GUICtrlRead($iCtrlID) <> $sData Then
		GUICtrlSetData($iCtrlID, $sData)
	EndIf
EndFunc

Работает корректно только с бинарными файлами, по крайней мере с теми что я проверял.
Также хотелось бы найти способ получше для предотвращения записи заголовка (header) в файл, чем его жёсткое удаление после записи.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Никто не хочет протестировать? :whistle:
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Сделал из этого библиотеку, но её нужно протестировать.

Пример:

Код:
#include <GUIConstantsEx.au3>
#include <GUIListView.au3>
#include 'TCPInet.au3'

Global $iGUI_WIDTH = 500
Global $iGUI_HEIGHT = 300

Global $bDownloading = False
Global $ahTCPInet[1][2]
Global $aURLs

_Set_URLs_GUI()

$hGUI = GUICreate('TCPInet.au3 Example', $iGUI_WIDTH, $iGUI_HEIGHT)

$iListView = GUICtrlCreateListView('URL|Progress', 20, 20, $iGUI_WIDTH - 40, $iGUI_HEIGHT - 100, $LVS_SHOWSELALWAYS)

For $i = 1 To $aURLs[0]
	GUICtrlCreateListViewItem($aURLs[$i], $iListView)
Next

_GUICtrlListView_SetColumnWidth($iListView, 0, -1)
_GUICtrlListView_SetColumnWidth($iListView, 1, 120)
_GUICtrlListView_SetExtendedListViewStyle($iListView, $LVS_EX_DOUBLEBUFFER, $LVS_EX_DOUBLEBUFFER)

$iPauseResume_Bttn = GUICtrlCreateButton('Pause / Resume', 20, $iGUI_HEIGHT - 70, 100, 20)
$iStop_Bttn = GUICtrlCreateButton('Stop', 140, $iGUI_HEIGHT - 70, 60, 20)

$iDownload_Bttn = GUICtrlCreateButton('Download', 20, $iGUI_HEIGHT - 30, 70, 20)

GUISetState(@SW_SHOW, $hGUI)

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			If _TCPInet_GetActiveDownloads() > 0 And MsgBox(52, 'Attention', 'Are you sure, stop all downloads?', 0, $hGUI) <> 6 Then
				For $i = 1 To $ahTCPInet[0][0]
					_TCPInet_Close($ahTCPInet[$i][1])
				Next
			EndIf
			
			If _TCPInet_GetActiveDownloads() = 0 Then
				Exit
			EndIf
		Case $iPauseResume_Bttn
			$aSel_Indices = _Check_Sel_Proc()
			If @error Then ContinueLoop
			
			If _TCPInet_GetActiveDownloads() = 0 Then
				ContinueLoop
			EndIf
			
			For $i = 1 To $aSel_Indices[0]
				For $j = 1 To $ahTCPInet[0][0]
					If $ahTCPInet[$j][0] = $aSel_Indices[$i] Then
						If Not _TCPInet_GetInfo($ahTCPInet[$j][1], $INET_DOWNLOADCOMPLETE) Then
							$bPause = Not _TCPInet_GetInfo($ahTCPInet[$j][1], $INET_DOWNLOADPAUSED)
							_TCPInet_SetPause($ahTCPInet[$j][1], $bPause)
							_GUICtrlListView_SetItemText($iListView, $aSel_Indices[$i], ($bPause ? 'Paused' : ''), 1)
						EndIf
						
						ExitLoop
					EndIf
				Next
			Next
		Case $iStop_Bttn
			$aSel_Indices = _Check_Sel_Proc()
			If @error Then ContinueLoop
			
			If _TCPInet_GetActiveDownloads() = 0 Then
				ContinueLoop
			EndIf
			
			For $i = 1 To $aSel_Indices[0]
				For $j = 1 To $ahTCPInet[0][0]
					If $ahTCPInet[$j][0] = $aSel_Indices[$i] Then
						If Not _TCPInet_GetInfo($ahTCPInet[$j][1], $INET_DOWNLOADCOMPLETE) Then
							_TCPInet_Close($ahTCPInet[$j][1])
							_GUICtrlListView_SetItemText($iListView, $aSel_Indices[$i], 'Stopped', 1)
						EndIf
						
						If _TCPInet_GetActiveDownloads() = 0 Then
							GUICtrlSetState($iDownload_Bttn, $GUI_ENABLE)
							$bDownloading = False
							ExitLoop 2
						EndIf
						
						ExitLoop
					EndIf
				Next
			Next
		Case $iDownload_Bttn
			$aSel_Indices = _Check_Sel_Proc()
			If @error Then ContinueLoop
			
			$sPath = FileSelectFolder('Save to...', '', 0, @DesktopDir, $hGUI)
			If @error Then ContinueLoop
			
			GUICtrlSetState($iDownload_Bttn, $GUI_DISABLE)
			
			For $i = 1 To $aSel_Indices[0]
				$sURL = _GUICtrlListView_GetItemText($iListView, $aSel_Indices[$i], 0)
				
				$ahTCPInet[0][0] += 1
				ReDim $ahTCPInet[$ahTCPInet[0][0] + 1][2]
				
				$ahTCPInet[$ahTCPInet[0][0]][0] = $aSel_Indices[$i]
				$ahTCPInet[$ahTCPInet[0][0]][1] = _TCPInet_GetFile($sURL, $sPath, $INET_DOWNLOADBACKGROUND)
			Next
			
			$bDownloading = True
	EndSwitch
	
	If $bDownloading Then
		For $i = 1 To $ahTCPInet[0][0]
			$aInfo = _TCPInet_GetInfo($ahTCPInet[$i][1], -1)
			$iError = @error
			
			If Not $iError And Not $aInfo[$INET_DOWNLOADCOMPLETE] And Not $aInfo[$INET_DOWNLOADPAUSED] Then
				$sProgress = StringFormat('%i% (%i/%i)', (100 / ($aInfo[$INET_DOWNLOADSIZE] / $aInfo[$INET_DOWNLOADREAD])), $aInfo[$INET_DOWNLOADREAD], $aInfo[$INET_DOWNLOADSIZE])
				_GUICtrlListView_SetItemText($iListView, $ahTCPInet[$i][0], $sProgress, 1)
			ElseIf Not $iError And $aInfo[$INET_DOWNLOADSUCCESS] Then
				_GUICtrlListView_SetItemText($iListView, $ahTCPInet[$i][0], 'Downloaded', 1)
			EndIf
			
			If _TCPInet_GetActiveDownloads() = 0 Then
				GUICtrlSetState($iDownload_Bttn, $GUI_ENABLE)
				$bDownloading = False
				ExitLoop
			EndIf
		Next
	EndIf
WEnd

Func _Set_URLs_GUI()
	Local $hGUI, $iURLs_Edit, $iOK_Bttn, $iCancel_Bttn
	
	$hGUI = GUICreate('Set URLs to download...', 500, 300)
	
	$iURLs_Edit = GUICtrlCreateEdit((StringRegExp(ClipGet(), '(?mi)^http://.*?') ? ClipGet() : ''), 20, 20, 460, 240)
	
	$iOK_Bttn = GUICtrlCreateButton('OK', 20, 270, 60, 20)
	$iCancel_Bttn = GUICtrlCreateButton('Cancel', 100, 270, 60, 20)
	
	GUISetState(@SW_SHOW, $hGUI)
	
	While 1
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE, $iCancel_Bttn
				Exit
			Case $iOK_Bttn
				Local $sURLs = GUICtrlRead($iURLs_Edit)
				
				GUIDelete($hGUI)
				
				If StringRegExp($sURLs, '(?mi)^http://.*?') Then
					$aURLs = StringSplit(StringStripCR($sURLs), @LF)
					ExitLoop
				EndIf
				
				MsgBox(48, 'Error', 'Invalid URLs set.')
				Exit
		EndSwitch
	WEnd
EndFunc

Func _Check_Sel_Proc()
	Local $aSel_Indices = _GUICtrlListView_GetSelectedIndices($iListView, True)
	
	If $aSel_Indices[0] = 0 Then
		MsgBox(48, 'Attention', 'Please select items.', 0, $hGUI)
		Return SetError(1, 0, 0)
	EndIf
	
	Return $aSel_Indices
EndFunc


Библиотеку с примером прикрепил.
 

Вложения

  • TCPInet.zip
    6.5 КБ · Просмотры: 20

XpycT

Скриптер
Сообщения
380
Репутация
133
CreatoR
Протестировал немного вашу библиотеку.

Если в начале ссылки нет "http://" то ссылка не принимается, даже если вставить ее вручную.

AutoIt 3.3.13.15 Beta
Не получилось сказать файл, ждал 10 минут. Скрипт не реагировал ни на одну кнопку, пришлось убить процесс.

AutoIt 3.3.12.0
Скрипт нормально отработал
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
XpycT [?]
Если в начале ссылки нет "http://" то ссылка не принимается, даже если вставить ее вручную.
Так всё верно, об этом написано в описании (заголовок функции).
Можно конечно и добавить...

AutoIt 3.3.12.0
Скрипт нормально отработал
Что и указано в заголовке библиотеки.

Нужно смотреть что изменилось в бета версиях, я на них пока не тестирую. Как показывает опыт, функционал в бета версиях может быть убран или изменён, поэтому библиотеки лучше писать под стабильные версии.
 

XpycT

Скриптер
Сообщения
380
Репутация
133
CreatoR

Тестировал с спросонья, не прочитал описание. :whistle:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR,
Вставил ссылки на 5 последних бета-версий AutoIt, протестировал, вроде, все в порядке - и пауза, и докачка работают.

Минус то, что качает очень долго, хоть один файл, хоть несколько (сравнивал с встроенным загрузчиком Opera и штатной InetGet). ИМХО, можно устанавливать $iTCPINET_MAXBYTES в зависимости от размера файла или увеличить его до 8 Кб (как в WinHttp.au3), еще можно попробовать качать в несколько потоков.
И еще, ИМХО, минус - использование HTTP/1.0 (интересно, не проверял, поправили баг HTTP/1.1 в версии 3.3.12.0).

OffTopic:
PS
Я как-то пробовал делать все это через MSXML2.ServerXMLHTTP.6.0 в асинхронном режиме и, если мне память не изменяет, работало это значительно быстрее, чем с штатными TCP* функциями.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
madmasles [?]
Я как-то пробовал делать все это через MSXML2.ServerXMLHTTP.6.0 в асинхронном режиме и, если мне память не изменяет, работало это значительно быстрее, чем с штатными TCP* функциями.
Буду признателен если сможете сделать аналогичные функции тем что в библиотеке TCPInet. Конечно же основной возможностью должна быть пауза закачек.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Библиотеку можно оформлять?
Или может у кого то будут другие предложения по реализации? :scratch:
 
Верх