elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP)
| | | |-+  Programación Visual Basic (Moderadores: LeandroA, seba123neo)
| | | | |-+  Problemas con múltiples descargas
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problemas con múltiples descargas  (Leído 1,863 veces)
aaronduran2


Desconectado Desconectado

Mensajes: 790



Ver Perfil WWW
Problemas con múltiples descargas
« en: 18 Agosto 2009, 21:53 pm »

Hola. Estoy haciendo un downloader de archivos, y hasta ahora, las descargas iban una por una (desde un ListView).
Pero quería mejorarlo y que se descargasen múltiples archivos, por lo que intenté crear una colección, pero no me salió.

Este es el código que tengo hasta ahora:

Código
  1. Dim cDescarga As clsDescarga
  2. Dim cColeccionDescargas As New Collection
  3.  
  4. Dim s_NombreArchivo As String, s_URLDescarga As String, s_RutaDestino As String
  5.  
  6. Private Sub cmdAgregarDescarga_Click()
  7.        Set cDescarga = New clsDescarga
  8.  
  9.        With lvwDescargas.ListItems.Add(, , s_NombreArchivo)
  10.            .SubItems(1) = s_URLDescarga
  11.        End With
  12.  
  13.        cDescarga.URL = s_URLDescarga
  14.        cDescarga.Fichero = s_RutaDestino
  15.        cDescarga.Descargar
  16.        cItemDescarga.Add cDescarga
  17. End Sub
  18.  
  19. Private Sub tmrEstado_Timer()
  20.    For i = 1 To cColeccionDescargas.Count
  21.        With lvwDescargas.ListItems(i)
  22.            .SubItems(2) = cColeccionDescargas(i).BytesRecibidos & "/" & cColeccionDescargas(i).BytesTotales
  23.        End With
  24.    Next
  25. End Sub

Y este es el módulo de clase:

Código
  1. Option Explicit
  2. Private Protocolo As String, Servidor As String, Objeto As String, Servicio As Long
  3. Private URLCorrecta As Boolean, TipoConexion As Long
  4. Private hInternetSession As Long, hInternetConnect As Long, hHttpOpenRequest As Long
  5.  
  6.  
  7. Public Enum jrDownTipoAccion
  8.    jrDownSoloInformacion = 0
  9.    jrDownDescargar = 1
  10. End Enum
  11.  
  12. 'constantes de error
  13. Private Const ERROR_URL As Long = 1
  14. Private Const ERROR_INTERNETOPEN = 2
  15. Private Const ERROR_INTERNETCONNECT = 3
  16. Private Const ERROR_INTERNETOPENREQUEST = 4
  17. Private Const ERROR_INTERNETSENDREQUEST = 5
  18. Private Const ERROR_INTERNETQUERYINFO = 6
  19. Private Const ERROR_INTERNETREADFILE = 7
  20. Private Const ERROR_FICHERO = 8
  21. Private Const ERROR_DESCARGA = 999
  22. Private Const ERROR_CANCELADO = 998
  23.  
  24.  
  25. 'declaraciones del API
  26. Const scUserAgent = "jrDownload"
  27. Const INTERNET_OPEN_TYPE_PRECONFIG = 0
  28. Const INTERNET_OPEN_TYPE_DIRECT = 1
  29. Const INTERNET_OPEN_TYPE_PROXY = 3
  30. Const INTERNET_FLAG_RELOAD = &H80000000
  31. Const HTTP_QUERY_CONTENT_TYPE = 1
  32. Const HTTP_QUERY_CONTENT_LENGTH = 5
  33. Const HTTP_QUERY_EXPIRES = 10
  34. Const HTTP_QUERY_LAST_MODIFIED = 11
  35. Const HTTP_QUERY_PRAGMA = 17
  36. Const HTTP_QUERY_VERSION = 18
  37. Const HTTP_QUERY_STATUS_CODE = 19
  38. Const HTTP_QUERY_STATUS_TEXT = 20
  39. Const HTTP_QUERY_RAW_HEADERS = 21
  40. Const HTTP_QUERY_RAW_HEADERS_CRLF = 22
  41. Const HTTP_QUERY_FORWARDED = 30
  42. Const HTTP_QUERY_SERVER = 37
  43. Const HTTP_QUERY_USER_AGENT = 39
  44. Const HTTP_QUERY_SET_COOKIE = 43
  45. Const HTTP_QUERY_REQUEST_METHOD = 45
  46. Const HTTP_QUERY_FLAG_REQUEST_HEADERS = &H80000000
  47. 'Puertos por defecto
  48. Const INTERNET_DEFAULT_FTP_PORT = 21
  49. Const INTERNET_DEFAULT_GOPHER_PORT = 70
  50. Const INTERNET_DEFAULT_HTTP_PORT = 80
  51. Const INTERNET_DEFAULT_HTTPS_PORT = 443
  52. Const INTERNET_DEFAULT_SOCKS_PORT = 1080
  53. ' Tipos de servicios
  54. Const INTERNET_SERVICE_FTP = 1
  55. Const INTERNET_SERVICE_GOPHER = 2
  56. Const INTERNET_SERVICE_HTTP = 3
  57. 'funciones del API para internet
  58. Private Declare Function InternetOpen Lib "wininet" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Long) As Long
  59. Private Declare Function InternetCloseHandle Lib "wininet" (ByVal hInet As Long) As Integer
  60. Private Declare Function InternetReadFile Lib "wininet" (ByVal hFile As Long, ByVal sBuffer As String, ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
  61. Private Declare Function InternetConnect Lib "wininet.dll" Alias _
  62.        "InternetConnectA" (ByVal InternetSession As Long, _
  63.        ByVal sServerName As String, ByVal nServerPort As Integer, _
  64.        ByVal sUsername As String, ByVal sPassword As String, _
  65.        ByVal lService As Long, ByVal lFlags As Long, _
  66.        ByVal lContext As Long) As Long
  67. Private Declare Function HttpOpenRequest Lib "wininet.dll" Alias _
  68.        "HttpOpenRequestA" (ByVal hHttpSession As Long, ByVal sVerb As _
  69.        String, ByVal sObjectName As String, ByVal sVersion As String, _
  70.        ByVal sReferer As String, ByVal something As Long, ByVal lFlags _
  71.        As Long, ByVal lContext As Long) As Long
  72. Private Declare Function HttpSendRequest Lib "wininet.dll" Alias _
  73.        "HttpSendRequestA" (ByVal hHttpRequest As Long, ByVal sHeaders _
  74.        As String, ByVal lHeadersLength As Long, sOptional As Any, _
  75.        ByVal lOptionalLength As Long) As Integer
  76. Private Declare Function HttpQueryInfo Lib "wininet.dll" Alias "HttpQueryInfoA" _
  77.        (ByVal hHttpRequest As Long, ByVal lInfoLevel As Long, ByRef sBuffer As Any, _
  78.        ByRef lBufferLength As Long, ByRef lIndex As Long) As Integer
  79. 'para crear un nombre de fichero temporal y único
  80. Private Declare Function GetTempFileName Lib "kernel32" Alias "GetTempFileNameA" (ByVal lpszPath As String, ByVal lpPrefixString As String, ByVal wUnique As Long, ByVal lpTempFileName As String) As Long
  81. 'para obtener descripción de errores del sistema
  82. Private Declare Function GetLastError Lib "kernel32" () As Long
  83. Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" _
  84.    (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, _
  85.    ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, _
  86.    Arguments As Long) As Long
  87. Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
  88. 'para obtener el tiempo de descarga
  89. Private Declare Function GetTickCount Lib "kernel32" () As Long
  90. 'variables locales para almacenar los valores de las propiedades
  91. Private mvarURL As String 'copia local
  92. Private mvarHuboError As Boolean 'copia local
  93. Private mvarStatusCode As String 'copia local
  94. Private mvarStatusText As String 'copia local
  95. Private mvarUsarProxy As String 'copia local
  96. Private mvarNoUsarProxy As String 'copia local
  97. Private mvarUsuario As String 'copia local
  98. Private mvarPassword As String 'copia local
  99. Private mvarFichero As String 'copia local
  100. Private mvarContenidoDescargado As String 'copia local
  101. Private mvarPuerto As Long 'copia local
  102. Private mvarQContentType As Boolean 'copia local
  103. Private mvarQContentLength As Boolean 'copia local
  104. Private mvarQLastModified As Boolean 'copia local
  105. Private mvarQVersion As Boolean 'copia local
  106. Private mvarQRawHeaders As Boolean 'copia local
  107. Private mvarQRawHeadersCrLf As Boolean 'copia local
  108. Private mvarQForwarded As Boolean 'copia local
  109. Private mvarQServer As Boolean 'copia local
  110. Private mvarQRequestMethod As Boolean 'copia local
  111. Private mvarQPragma As Boolean 'copia local
  112. Private mvarQContentLengthStr As String 'copia local
  113. Private mvarQContentTypeStr As String 'copia local
  114. Private mvarQForwardedStr As String 'copia local
  115. Private mvarQLastModifiedStr As String 'copia local
  116. Private mvarQPragmaStr As String 'copia local
  117. Private mvarQRawHeadersStr As String 'copia local
  118. Private mvarQRequestMethodStr As String 'copia local
  119. Private mvarQServerStr As String 'copia local
  120. Private mvarQVersionStr As String 'copia local
  121. Private mvarQRawHeadersCrLfStr As String 'copia local
  122. Private mvarQExpires As Boolean 'copia local
  123. Private mvarQExpiresStr As String 'copia local
  124. Private mvarBytesBloqueDescarga As Long 'copia local
  125.  
  126. 'Para activar este evento, use RaiseEvent con la siguiente sintaxis:
  127. 'RaiseEvent Progreso[(arg1, arg2, ... , argn)]
  128. Public BytesTotales As Long, BytesRecibidos As Long, Porcentaje As Double, SegundosTranscurridos As Long, SegundosRestantes As Double, BytesPorSegundo As Long, Cancelar As Boolean
  129. Public Property Let BytesBloqueDescarga(ByVal vData As Long)
  130. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  131. 'Syntax: X.BytesBloqueDescarga = 5
  132.    mvarBytesBloqueDescarga = vData
  133. End Property
  134.  
  135.  
  136. Public Property Get BytesBloqueDescarga() As Long
  137. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  138. 'Syntax: Debug.Print X.BytesBloqueDescarga
  139.    BytesBloqueDescarga = mvarBytesBloqueDescarga
  140. End Property
  141.  
  142.  
  143.  
  144.  
  145. Private Function LastSystemError() As String
  146. Dim sError As String * 500, lErrNum As Long, lErrMsg As Long
  147.  
  148. lErrNum = GetLastError()
  149. lErrMsg = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, _
  150.  ByVal 0&, lErrNum, 0, sError, Len(sError), 0)
  151. LastSystemError = left(sError, InStr(sError, Chr(0) - 1))
  152. End Function
  153.  
  154. Private Sub CierraConexiones()
  155. If hHttpOpenRequest <> 0 Then InternetCloseHandle hHttpOpenRequest
  156. If hInternetConnect <> 0 Then InternetCloseHandle hInternetConnect
  157. If hInternetSession <> 0 Then InternetCloseHandle hInternetSession
  158. End Sub
  159.  
  160. Public Property Let QExpiresStr(ByVal vData As String)
  161. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  162. 'Syntax: X.QExpiresStr = 5
  163.    mvarQExpiresStr = vData
  164. End Property
  165.  
  166.  
  167. Public Property Get QExpiresStr() As String
  168. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  169. 'Syntax: Debug.Print X.QExpiresStr
  170.    QExpiresStr = mvarQExpiresStr
  171. End Property
  172.  
  173.  
  174.  
  175. Public Property Let QExpires(ByVal vData As Boolean)
  176. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  177. 'Syntax: X.QExpires = 5
  178.    mvarQExpires = vData
  179. End Property
  180.  
  181.  
  182. Public Property Get QExpires() As Boolean
  183. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  184. 'Syntax: Debug.Print X.QExpires
  185.    QExpires = mvarQExpires
  186. End Property
  187.  
  188.  
  189.  
  190.  
  191. Public Property Let QRawHeadersCrLfStr(ByVal vData As String)
  192. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  193. 'Syntax: X.QRawHeadersCrLfStr = 5
  194.    mvarQRawHeadersCrLfStr = vData
  195. End Property
  196.  
  197.  
  198. Public Property Get QRawHeadersCrLfStr() As String
  199. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  200. 'Syntax: Debug.Print X.QRawHeadersCrLfStr
  201.    QRawHeadersCrLfStr = mvarQRawHeadersCrLfStr
  202. End Property
  203.  
  204.  
  205.  
  206.  
  207. Private Sub InicializaCabecerasStr()
  208. mvarQContentLengthStr = ""
  209. mvarQContentTypeStr = ""
  210. mvarQForwardedStr = ""
  211. mvarQLastModifiedStr = ""
  212. mvarQPragmaStr = ""
  213. mvarQRawHeadersStr = ""
  214. mvarQRequestMethodStr = ""
  215. mvarQServerStr = ""
  216. mvarQVersionStr = ""
  217. mvarQRawHeadersCrLfStr = ""
  218. End Sub
  219.  
  220.  
  221. Public Property Get QVersionStr() As String
  222. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  223. 'Syntax: Debug.Print X.QVersionStr
  224.    QVersionStr = mvarQVersionStr
  225. End Property
  226.  
  227.  
  228.  
  229.  
  230.  
  231. Public Property Get QServerStr() As String
  232. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  233. 'Syntax: Debug.Print X.QServerStr
  234.    QServerStr = mvarQServerStr
  235. End Property
  236.  
  237.  
  238.  
  239.  
  240.  
  241. Public Property Get QRequestMethodStr() As String
  242. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  243. 'Syntax: Debug.Print X.QRequestMethodStr
  244.    QRequestMethodStr = mvarQRequestMethodStr
  245. End Property
  246.  
  247.  
  248.  
  249.  
  250.  
  251. Public Property Get QRawHeadersStr() As String
  252. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  253. 'Syntax: Debug.Print X.QRawHeadersStr
  254.    QRawHeadersStr = mvarQRawHeadersStr
  255. End Property
  256.  
  257.  
  258.  
  259.  
  260.  
  261. Public Property Get QPragmaStr() As String
  262. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  263. 'Syntax: Debug.Print X.QPragmaStr
  264.    QPragmaStr = mvarQPragmaStr
  265. End Property
  266.  
  267.  
  268.  
  269.  
  270.  
  271. Public Property Get QLastModifiedStr() As String
  272. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  273. 'Syntax: Debug.Print X.QLastModifiedStr
  274.    QLastModifiedStr = mvarQLastModifiedStr
  275. End Property
  276.  
  277.  
  278.  
  279.  
  280.  
  281. Public Property Get QForwardedStr() As String
  282. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  283. 'Syntax: Debug.Print X.QForwardedStr
  284.    QForwardedStr = mvarQForwardedStr
  285. End Property
  286.  
  287.  
  288.  
  289.  
  290.  
  291. Public Property Get QContentTypeStr() As String
  292. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  293. 'Syntax: Debug.Print X.QContentTypeStr
  294.    QContentTypeStr = mvarQContentTypeStr
  295. End Property
  296.  
  297.  
  298.  
  299.  
  300.  
  301. Public Property Get QContentLengthStr() As String
  302. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  303. 'Syntax: Debug.Print X.QContentLengthStr
  304.    QContentLengthStr = mvarQContentLengthStr
  305. End Property
  306.  
  307.  
  308.  
  309. Public Property Let QPragma(ByVal vData As Boolean)
  310. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  311. 'Syntax: X.QPragma = 5
  312.    mvarQPragma = vData
  313. End Property
  314.  
  315.  
  316. Public Property Get QPragma() As Boolean
  317. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  318. 'Syntax: Debug.Print X.QPragma
  319.    QPragma = mvarQPragma
  320. End Property
  321.  
  322.  
  323.  
  324. Public Property Let QRequestMethod(ByVal vData As Boolean)
  325. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  326. 'Syntax: X.QRequestMethod = 5
  327.    mvarQRequestMethod = vData
  328. End Property
  329.  
  330.  
  331. Public Property Get QRequestMethod() As Boolean
  332. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  333. 'Syntax: Debug.Print X.QRequestMethod
  334.    QRequestMethod = mvarQRequestMethod
  335. End Property
  336.  
  337.  
  338.  
  339. Public Property Let QServer(ByVal vData As Boolean)
  340. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  341. 'Syntax: X.QServer = 5
  342.    mvarQServer = vData
  343. End Property
  344.  
  345.  
  346. Public Property Get QServer() As Boolean
  347. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  348. 'Syntax: Debug.Print X.QServer
  349.    QServer = mvarQServer
  350. End Property
  351.  
  352.  
  353.  
  354. Public Property Let QForwarded(ByVal vData As Boolean)
  355. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  356. 'Syntax: X.QForwarded = 5
  357.    mvarQForwarded = vData
  358. End Property
  359.  
  360.  
  361. Public Property Get QForwarded() As Boolean
  362. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  363. 'Syntax: Debug.Print X.QForwarded
  364.    QForwarded = mvarQForwarded
  365. End Property
  366.  
  367.  
  368.  
  369. Public Property Let QRawHeadersCrLf(ByVal vData As Boolean)
  370. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  371. 'Syntax: X.QRawHeadersCrLf = 5
  372.    mvarQRawHeadersCrLf = vData
  373. End Property
  374.  
  375.  
  376. Public Property Get QRawHeadersCrLf() As Boolean
  377. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  378. 'Syntax: Debug.Print X.QRawHeadersCrLf
  379.    QRawHeadersCrLf = mvarQRawHeadersCrLf
  380. End Property
  381.  
  382.  
  383.  
  384. Public Property Let QRawHeaders(ByVal vData As Boolean)
  385. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  386. 'Syntax: X.QRawHeaders = 5
  387.    mvarQRawHeaders = vData
  388. End Property
  389.  
  390.  
  391. Public Property Get QRawHeaders() As Boolean
  392. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  393. 'Syntax: Debug.Print X.QRawHeaders
  394.    QRawHeaders = mvarQRawHeaders
  395. End Property
  396.  
  397.  
  398.  
  399. Public Property Let QVersion(ByVal vData As Boolean)
  400. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  401. 'Syntax: X.QVersion = 5
  402.    mvarQVersion = vData
  403. End Property
  404.  
  405.  
  406. Public Property Get QVersion() As Boolean
  407. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  408. 'Syntax: Debug.Print X.QVersion
  409.    QVersion = mvarQVersion
  410. End Property
  411.  
  412.  
  413.  
  414. Public Property Let QLastModified(ByVal vData As Boolean)
  415. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  416. 'Syntax: X.QLastModified = 5
  417.    mvarQLastModified = vData
  418. End Property
  419.  
  420.  
  421. Public Property Get QLastModified() As Boolean
  422. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  423. 'Syntax: Debug.Print X.QLastModified
  424.    QLastModified = mvarQLastModified
  425. End Property
  426.  
  427.  
  428.  
  429. Public Property Let QContentLength(ByVal vData As Boolean)
  430. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  431. 'Syntax: X.QContentLength = 5
  432.    mvarQContentLength = vData
  433. End Property
  434.  
  435.  
  436. Public Property Get QContentLength() As Boolean
  437. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  438. 'Syntax: Debug.Print X.QContentLength
  439.    QContentLength = mvarQContentLength
  440. End Property
  441.  
  442.  
  443.  
  444. Public Property Let QContentType(ByVal vData As Boolean)
  445. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  446. 'Syntax: X.QContentType = 5
  447.    mvarQContentType = vData
  448. End Property
  449.  
  450.  
  451. Public Property Get QContentType() As Boolean
  452. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  453. 'Syntax: Debug.Print X.QContentType
  454.    QContentType = mvarQContentType
  455. End Property
  456.  
  457.  
  458.  
  459. Public Sub Descargar(Optional TipoAccion As jrDownTipoAccion = jrDownDescargar)
  460. Dim BytesTotales As Long, BytesRecibidos As Long, BytesRecibidosTotales As Long, Porcentaje As Double
  461. Dim sBuffer As String, Res As Integer, UsarPuerto As Long, NumBloques As Long
  462. Dim FileName As String, Fich As Long, Contenido As String, aux As String
  463. Dim Cancelar As Boolean
  464. Dim TiempoTranscurrido As Long, TiempoRestante As Double, TiempoInicio As Long, BytesSegundo As Double
  465.  
  466. On Error Resume Next
  467.  
  468. Dim ChunkSize As Long
  469.  
  470. ChunkSize = mvarBytesBloqueDescarga
  471.  
  472. 'inicializo propiedades
  473. InicializaCabecerasStr
  474. mvarHuboError = False
  475. mvarStatusCode = ""
  476. mvarStatusText = ""
  477. mvarContenidoDescargado = ""
  478. Cancelar = False
  479.  
  480. 'compruebo que la URL esté introdocida y sea sintácticamente correcta
  481. URLCorrecta = ProcesaURL()
  482. If Not URLCorrecta Then
  483.    mvarHuboError = True
  484.    Exit Sub
  485. End If
  486. 'Creo buffer para recibir el fichero
  487. sBuffer = Space(ChunkSize)
  488. 'Creo una conexión a internet
  489. If TipoConexion = INTERNET_OPEN_TYPE_PROXY Then
  490.    hInternetSession = InternetOpen(scUserAgent, INTERNET_OPEN_TYPE_PROXY, mvarUsarProxy, mvarNoUsarProxy, 0)
  491. Else
  492.    hInternetSession = InternetOpen(scUserAgent, TipoConexion, vbNullString, vbNullString, 0)
  493. End If
  494. If hInternetSession = 0 Then
  495.    ProcesaError ERROR_INTERNETOPEN
  496.    Exit Sub
  497. End If
  498. 'me conecto con el servidor
  499. UsarPuerto = Puerto
  500. hInternetConnect = InternetConnect(hInternetSession, Servidor, UsarPuerto, mvarUsuario, mvarPassword, Servicio, 0, 0)
  501. If hInternetConnect = 0 Then
  502.    ProcesaError ERROR_INTERNETCONNECT
  503.    Exit Sub
  504. End If
  505. 'abro una petición para el fichero solicitado
  506. hHttpOpenRequest = HttpOpenRequest(hInternetConnect, "GET", Objeto, "HTTP/1.0", vbNullString, 0, INTERNET_FLAG_RELOAD, 0)
  507. If hHttpOpenRequest = 0 Then
  508.    ProcesaError ERROR_INTERNETOPENREQUEST
  509.    Exit Sub
  510. End If
  511. 'envío la petición
  512. Res = HttpSendRequest(hHttpOpenRequest, vbNullString, 0, 0, 0)
  513. If Res = 0 Then
  514.    ProcesaError ERROR_INTERNETSENDREQUEST
  515.    Exit Sub
  516. End If
  517. 'miro la cabecera para ver si el fichero existe
  518. If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_STATUS_TEXT, sBuffer) Then
  519.    mvarStatusText = sBuffer
  520. Else
  521.    ProcesaError ERROR_INTERNETQUERYINFO
  522.    Exit Sub
  523. End If
  524. If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_STATUS_CODE, sBuffer) Then
  525.    mvarStatusCode = sBuffer
  526.    If left(sBuffer, 1) <> "2" Then
  527.        ProcesaError CLng(mvarStatusCode)
  528.        Exit Sub
  529.    End If
  530. Else
  531.    ProcesaError ERROR_INTERNETQUERYINFO
  532.    Exit Sub
  533. End If
  534. 'miro la longitud del contenido a descargar
  535. If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_CONTENT_LENGTH, sBuffer) Then
  536.    If IsNumeric(sBuffer) Then
  537.        BytesTotales = CLng(sBuffer)
  538.    Else
  539.        BytesTotales = -1
  540.    End If
  541.    If mvarQContentLength Then mvarQContentLengthStr = sBuffer
  542. Else
  543.    BytesTotales = -1
  544. End If
  545. 'busco el resto de valores de la cabecera, si lo ha solicitado el usuario
  546. If mvarQContentType Then
  547.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_CONTENT_TYPE, sBuffer) Then mvarQContentTypeStr = sBuffer
  548. End If
  549. If mvarQExpires Then
  550.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_EXPIRES, sBuffer) Then mvarQExpiresStr = sBuffer
  551. End If
  552. If mvarQLastModified Then
  553.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_LAST_MODIFIED, sBuffer) Then mvarQLastModifiedStr = sBuffer
  554. End If
  555. If mvarQPragma Then
  556.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_PRAGMA + HTTP_QUERY_FLAG_REQUEST_HEADERS, sBuffer) Then mvarQPragmaStr = sBuffer
  557. End If
  558. If mvarQVersion Then
  559.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_VERSION, sBuffer) Then mvarQVersionStr = sBuffer
  560. End If
  561. If mvarQRawHeaders Then
  562.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_RAW_HEADERS, sBuffer) Then mvarQRawHeadersStr = sBuffer
  563. End If
  564. If mvarQRawHeadersCrLf Then
  565.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_RAW_HEADERS_CRLF, sBuffer) Then mvarQRawHeadersCrLfStr = sBuffer
  566. End If
  567. If mvarQForwarded Then
  568.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_FORWARDED, sBuffer) Then mvarQForwardedStr = sBuffer
  569. End If
  570. If mvarQServer Then
  571.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_SERVER, sBuffer) Then mvarQServerStr = sBuffer
  572. End If
  573. If mvarQRequestMethod Then
  574.    If GetQueryInfo(hHttpOpenRequest, HTTP_QUERY_FLAG_REQUEST_HEADERS + HTTP_QUERY_REQUEST_METHOD, sBuffer) Then mvarQRequestMethodStr = sBuffer
  575. End If
  576. 'si sólo queríamos información del archivo, ya acabamos
  577. If TipoAccion = jrDownSoloInformacion Then
  578.    CierraConexiones
  579.    Exit Sub
  580. End If
  581. 'si tengo que grabar un fichero
  582. If mvarFichero <> "" Then
  583.    'obtengo un nombre de fichero temporal para guardar lo que descargue
  584.    FileName = Space(260)
  585.    GetTempFileName DameDirectorio(mvarFichero), "jrD", 0, FileName
  586.    FileName = left(FileName, InStr(FileName, Chr$(0)) - 1)
  587.    'abro el fichero
  588.    Fich = FreeFile()
  589.    Open FileName For Binary As Fich
  590. Else
  591.    'si conozco la longitud del archivo dimensiono el string porque se gana mucho en velocidad
  592.    If BytesTotales <> -1 Then mvarContenidoDescargado = Space(BytesTotales)
  593. End If
  594. 'leo el archivo de internet
  595. 'inicio el contador de tiempo
  596. TiempoInicio = GetTickCount()
  597. 'inicio los bytes recibidos y el espacio a leer de cada vez
  598. BytesRecibidosTotales = 0
  599. Res = 1: BytesRecibidos = ChunkSize
  600. sBuffer = Space(ChunkSize): NumBloques = 0
  601. While Res <> 0 And BytesRecibidos <> 0 And Not Cancelar
  602.    Res = InternetReadFile(hHttpOpenRequest, sBuffer, ChunkSize, BytesRecibidos)
  603.    If Res = 0 Then
  604.        mvarStatusText = LastSystemError()
  605.        mvarStatusCode = "999"
  606.    Else
  607.        If BytesRecibidos > 0 Then
  608.            aux = left(sBuffer, BytesRecibidos)
  609.            'si estoy grabando un fichero...
  610.            If mvarFichero <> "" Then
  611.                Put Fich, , aux
  612.            Else
  613.                'si conozco el tamaño del archivo
  614.                If BytesTotales <> -1 Then
  615.                    Mid(mvarContenidoDescargado, (NumBloques * ChunkSize) + 1, BytesRecibidos) = aux
  616.                    NumBloques = NumBloques + 1
  617.                Else
  618.                    mvarContenidoDescargado = mvarContenidoDescargado + aux
  619.                End If
  620.            End If
  621.            BytesRecibidosTotales = BytesRecibidosTotales + BytesRecibidos
  622.            TiempoTranscurrido = GetTickCount() - TiempoInicio
  623.            BytesSegundo = BytesRecibidosTotales / (TiempoTranscurrido / 1000)
  624.            'calcular el porcentaje descargado y lanzar el evento progreso
  625.            If BytesTotales <> -1 Then
  626.                Porcentaje = (BytesRecibidosTotales * 100) / BytesTotales
  627.                TiempoRestante = (BytesTotales / BytesSegundo) - (TiempoTranscurrido / 1000)
  628.            Else
  629.                Porcentaje = 0
  630.                TiempoRestante = 0
  631.            End If
  632.            If TiempoRestante < 0 Then TiempoRestante = 0
  633.            'RaiseEvent Progreso(BytesTotales, BytesRecibidosTotales, Porcentaje, CLng(TiempoTranscurrido / 1000), CLng(TiempoRestante), CLng(BytesSegundo), Cancelar)
  634.            DoEvents
  635.        End If
  636.    End If
  637. Wend
  638. 'cierro el fichero
  639. If mvarFichero <> "" Then Close Fich
  640. 'si el usuario canceló borro el fichero
  641. If Cancelar Then
  642.    If mvarFichero <> "" Then
  643.        If Dir(FileName) <> "" Then Kill FileName
  644.    End If
  645.    ProcesaError ERROR_CANCELADO
  646.    Exit Sub
  647. Else
  648.    'si acabó por un error borro el fichero (dejo la variable por si el contenido sirviera para algo)
  649.    If Res = 0 Then
  650.        If mvarFichero <> "" Then
  651.            If Dir(FileName) <> "" Then Kill FileName
  652.        End If
  653.        ProcesaError ERROR_DESCARGA
  654.        Exit Sub
  655.    Else
  656.        'cambio el nombre al fichero
  657.        If mvarFichero <> "" Then
  658.            If Dir(mvarFichero) <> "" Then Kill mvarFichero
  659.        End If
  660.        Name FileName As mvarFichero
  661.    End If
  662. End If
  663. CierraConexiones
  664. End Sub
  665.  
  666. Private Function DameDirectorio(Archivo As String) As String
  667. Dim i As Long
  668.  
  669. 'busco la última barra
  670. i = InStrRev(Archivo, "\")
  671. If i = 0 Then
  672.    DameDirectorio = CurDir()
  673. Else
  674.    DameDirectorio = left(Archivo, i - 1)
  675. End If
  676. End Function
  677.  
  678. Private Function GetQueryInfo(ByVal hHttpRequest As Long, ByVal iInfoLevel As Long, Valor As String) As Boolean
  679. Dim sBuffer As String * 1024, lBufferLength As Long
  680.  
  681. lBufferLength = Len(sBuffer)
  682. GetQueryInfo = CBool(HttpQueryInfo(hHttpRequest, iInfoLevel, ByVal sBuffer, lBufferLength, 0))
  683. lBufferLength = InStr(sBuffer, Chr(0))
  684. Valor = left(sBuffer, lBufferLength - 1)
  685. End Function
  686.  
  687.  
  688.  
  689. Public Property Let Puerto(ByVal vData As Long)
  690. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  691. 'Syntax: X.Puerto = 5
  692.    mvarPuerto = vData
  693. End Property
  694.  
  695.  
  696. Public Property Get Puerto() As Long
  697. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  698. 'Syntax: Debug.Print X.Puerto
  699. If mvarPuerto = 0 Then
  700.    Select Case Protocolo
  701.        Case "http": Puerto = INTERNET_DEFAULT_HTTP_PORT
  702.        Case "https": Puerto = INTERNET_DEFAULT_HTTPS_PORT
  703.    End Select
  704. Else
  705.    Puerto = mvarPuerto
  706. End If
  707. End Property
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714. Public Property Get ContenidoDescargado() As String
  715. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  716. 'Syntax: Debug.Print X.ContenidoDescargado
  717.    ContenidoDescargado = mvarContenidoDescargado
  718. End Property
  719.  
  720.  
  721.  
  722. Public Property Let Fichero(ByVal vData As String)
  723. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  724. 'Syntax: X.Fichero = 5
  725.    mvarFichero = vData
  726. End Property
  727.  
  728.  
  729. Public Property Get Fichero() As String
  730. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  731. 'Syntax: Debug.Print X.Fichero
  732.    Fichero = Trim(mvarFichero)
  733. End Property
  734.  
  735.  
  736.  
  737. Public Property Let Password(ByVal vData As String)
  738. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  739. 'Syntax: X.Password = 5
  740.    mvarPassword = vData
  741. End Property
  742.  
  743.  
  744. Public Property Get Password() As String
  745. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  746. 'Syntax: Debug.Print X.Password
  747.    Password = mvarPassword
  748. End Property
  749.  
  750.  
  751.  
  752. Public Property Let Usuario(ByVal vData As String)
  753. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  754. 'Syntax: X.Usuario = 5
  755.    mvarUsuario = vData
  756. End Property
  757.  
  758.  
  759. Public Property Get Usuario() As String
  760. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  761. 'Syntax: Debug.Print X.Usuario
  762.    Usuario = mvarUsuario
  763. End Property
  764.  
  765.  
  766.  
  767.  
  768. Public Property Let NoUsarProxy(ByVal vData As String)
  769. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  770. 'Syntax: X.NoUsarProxy = 5
  771.    mvarNoUsarProxy = vData
  772.    If mvarUsarProxy = "" And mvarNoUsarProxy = "" Then
  773.        TipoConexion = INTERNET_OPEN_TYPE_PRECONFIG
  774.    Else
  775.        TipoConexion = INTERNET_OPEN_TYPE_PROXY
  776.    End If
  777. End Property
  778.  
  779.  
  780. Public Property Get NoUsarProxy() As String
  781. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  782. 'Syntax: Debug.Print X.NoUsarProxy
  783.    NoUsarProxy = mvarNoUsarProxy
  784. End Property
  785.  
  786.  
  787.  
  788. Public Property Let UsarProxy(ByVal vData As String)
  789. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  790. 'Syntax: X.UsarProxy = 5
  791.    mvarUsarProxy = vData
  792.    If mvarUsarProxy = "" And mvarNoUsarProxy = "" Then
  793.        TipoConexion = INTERNET_OPEN_TYPE_PRECONFIG
  794.    Else
  795.        TipoConexion = INTERNET_OPEN_TYPE_PROXY
  796.    End If
  797.  
  798. End Property
  799.  
  800.  
  801. Public Property Get UsarProxy() As String
  802. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  803. 'Syntax: Debug.Print X.UsarProxy
  804.    UsarProxy = mvarUsarProxy
  805. End Property
  806.  
  807.  
  808.  
  809.  
  810. Private Sub ProcesaError(Numero As Long)
  811.  
  812. mvarStatusCode = Format(Numero, "000")
  813.  
  814. Select Case Numero
  815.    Case ERROR_URL: mvarStatusText = "URL incorrecta."
  816.    Case ERROR_INTERNETOPEN: mvarStatusText = "Error en InternetOpen."
  817.    Case ERROR_INTERNETCONNECT: mvarStatusText = "Error en InternetConnect."
  818.    Case ERROR_INTERNETOPENREQUEST: mvarStatusText = "Error en InternetOpenRequest."
  819.    Case ERROR_INTERNETSENDREQUEST: mvarStatusText = "Error en InternetSendRequest."
  820.    Case ERROR_INTERNETQUERYINFO: mvarStatusText = "Error en InternetQueryInfo."
  821.    Case ERROR_INTERNETREADFILE: mvarStatusText = "Error en InternetReadFile."
  822.    Case ERROR_FICHERO: mvarStatusText = "No se ha podido crear el fichero de destino."
  823.    Case ERROR_DESCARGA: mvarStatusText = "Ha ocurrido un error durante la descarga."
  824.    Case ERROR_CANCELADO: mvarStatusText = "Descarga cancelada por el usuario."
  825. End Select
  826. CierraConexiones
  827. mvarHuboError = True
  828. End Sub
  829.  
  830. Public Property Get StatusText() As String
  831. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  832. 'Syntax: Debug.Print X.StatusText
  833.    StatusText = mvarStatusText
  834. End Property
  835.  
  836.  
  837.  
  838.  
  839.  
  840. Public Property Get StatusCode() As String
  841. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  842. 'Syntax: Debug.Print X.StatusCode
  843.    StatusCode = mvarStatusCode
  844. End Property
  845.  
  846.  
  847.  
  848.  
  849.  
  850. Public Property Get HuboError() As Boolean
  851. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  852. 'Syntax: Debug.Print X.HuboError
  853.    HuboError = mvarHuboError
  854. End Property
  855.  
  856.  
  857.  
  858. Public Property Let URL(ByVal vData As String)
  859. 'se usa al asignar un valor a la propiedad, en la parte izquierda de una asignación.
  860. 'Syntax: X.URL = 5
  861. Dim i As Long, j As Long
  862.  
  863. mvarURL = vData
  864. URLCorrecta = ProcesaURL()
  865.  
  866. End Property
  867.  
  868. Public Property Get URL() As String
  869. 'se usa al recuperar un valor de una propiedad, en la parte derecha de una asignación.
  870. 'Syntax: Debug.Print X.URL
  871.    URL = mvarURL
  872. End Property
  873.  
  874.  
  875.  
  876. Private Function ProcesaURL() As Boolean
  877. Dim i As Long, j As Long
  878.  
  879. On Error GoTo ProcesaURL_Err
  880.  
  881. ProcesaURL = False
  882. 'descomponemos la url en protocolo, servidor y objeto
  883. 'busco el protocolo
  884. i = InStr(mvarURL, "://")
  885. If i = 0 Then
  886.    'si no existe asumimos que es http
  887.    Protocolo = "http"
  888.    i = 1
  889. Else
  890.    Protocolo = LCase(Mid(mvarURL, 1, i - 1))
  891.    i = i + 3
  892. End If
  893. 'sólo permitimos http
  894. Select Case Protocolo
  895.    Case "http":
  896.    Case "https":
  897.    Case Else: ProcesaError ERROR_URL
  898. End Select
  899. 'busco el servidor
  900. j = InStr(i, mvarURL, "/")
  901. If j = 0 Then j = Len(mvarURL) + 1
  902. Servidor = Mid(mvarURL, i, j - i)
  903. i = j + 1
  904. 'busco el objeto a descargar
  905. If i > Len(mvarURL) Then
  906.    Objeto = vbNullString
  907. Else
  908.    Objeto = "/" & Mid(mvarURL, i)
  909. End If
  910. ProcesaURL = True
  911.  
  912. ProcesaURL_End:
  913.    Exit Function
  914.  
  915. ProcesaURL_Err:
  916.    ProcesaError ERROR_URL
  917.    Resume ProcesaURL_End
  918.  
  919. End Function
  920.  
  921. Private Sub Class_Initialize()
  922. TipoConexion = INTERNET_OPEN_TYPE_PRECONFIG
  923. mvarQContentLength = True
  924. Servicio = INTERNET_SERVICE_HTTP
  925. mvarBytesBloqueDescarga = 512
  926. End Sub
  927.  
  928.  
  929. Private Sub Class_Terminate()
  930. CierraConexiones
  931. End Sub

¿Alguien podría darme alguna idea? Si existe otra forma de hacer las múltiples descargas con este módulo, etc...

Saludos, y gracias de antemano.


« Última modificación: 18 Agosto 2009, 22:41 pm por aaronduran2 » En línea

LeandroA
Moderador
***
Desconectado Desconectado

Mensajes: 760


www.leandroascierto.com


Ver Perfil WWW
Re: Problemas con múltiples descargas
« Respuesta #1 en: 19 Agosto 2009, 23:18 pm »

Hola a como yo lo veo es imposible hacer lo que queres, cuando trabajas con bucles cortas todo tipo de hilo, y que es lo que hace visual basic en ese sentido, recorre un solo camino. vos podes poner a descargar 3 archivos, pero que es lo que pasa

suponete que le das tres click seguidos al boton, todo bien comienzan las tres descargas pero en realidad primero descargara es la ultima, luego la penultima y por ultimo la primera, es como que lleva a puntero a la clase  que se llamo ultimo

una solucion algo fea es poder remplazar este bucle
While Res <> 0 And pBytesRecibidos <> 0 And Not Cancelar
por algun pulso de un timer, pero no es lo mas efeciente.

te preguntars porque con el metodo que use yo funciona, sensillamente porque la clase no intenta leer datos, sino los datos le llegan a este (AddressOf)

te lo digo por experiencia yo renegue mucho con este tema utilizando winsock.ocx

Consejo: las apis wininet no te van a servir para esto.

Saludos


En línea

aaronduran2


Desconectado Desconectado

Mensajes: 790



Ver Perfil WWW
Re: Problemas con múltiples descargas
« Respuesta #2 en: 19 Agosto 2009, 23:30 pm »

Vale, muchas gracias por los consejos. Intentaré modificarlo, pero sino no pasa nada.

Gracias y saludos  ;)
En línea

HaX991

Desconectado Desconectado

Mensajes: 33



Ver Perfil
Re: Problemas con múltiples descargas
« Respuesta #3 en: 20 Agosto 2009, 15:04 pm »

aaronduran2 lo k intentas acer (multiple downloader) si es posible hacerlo solo tienes k adaptar el codigo en un modulo de clase y crear un array como l k ace la clase cSocketPlus pues igual.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
problemas con descargas java a pc
Dudas Generales
gringadel30 1 1,913 Último mensaje 4 Mayo 2012, 19:12 pm
por el-brujo
Problemas red wifi con multiples pcs
Redes
Ismaw34 3 1,857 Último mensaje 25 Julio 2012, 01:09 am
por Ismaw34
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines