Valhalla Legends Forums Archive | Battle.net Bot Development | Synchronous file downloading

AuthorMessageTime
Stealth
I would like StealthBot to download a news file (simple, one-line .txt file containing formatted data). This is fairly easily accomplished using INet, or the URLDownloadToFile() API call. However, I need the file to be downloaded without interfering with the functionality of the bot at all or it won't meet my standards.

The current method, a standard INet control, hangs the rest of the bot's operations while it downloads. This isn't acceptable. I also attempted to create a class module to handle the task using URLDownloadToFile() -- the same problem occurs. URLDownloadToFile() within the class hangs the program until finished. Is it possible to download the file synchronously, perhaps by multithreading it? If necessary, I can port the class module's code to a standard module so that it can be used with the AddressOf operator.

Additionally, I will post the code to either the static-reference subroutine or the class module if necessary.
February 24, 2004, 12:32 AM
K
The easiest way to trick VB into multithreading is to do something like:

[code]
// to download file:
Form1_Load() // or whenever
{
tmrDownload.Enabled = True
}

// Timer Proc
tmrDownload_Tick()
{
URLDownloadToFile(/ * ..... */ )
MessageBox(0, "File Download Complete", "", MB_OK)
DoThingsWithDownloadedFile()
tmrDownload.Enabled = False

}[/code]

Alternatively, I believe the INET control does have the ability to do asynchronous downloading. I'm not sure how, though.
February 24, 2004, 12:50 AM
Stealth
The timer idea worked beautifully. Thank you. :)
February 24, 2004, 1:17 AM
UserLoser.
Could just set up a socket, connect, and request the file to the news, then just dump all the recieved text to a file
February 24, 2004, 1:21 AM
Stealth
I ended up writing a module that uses SetTimer and KillTimer to create a short-lived timer thread within which URLDownloadToFile() can do its thing peacefully and without interfering. It works and it's low-overhead, so it seems to be all good. =)
February 24, 2004, 1:36 AM
o.OV
mm..
You already have a working solution but..
I'll add to the thread anyways.

One alternate method involves using UserControls.
I suck with my object oriented programming but..
here is an example project.

[code]

'FORM1

Option Explicit

Public fromFile As String, toFile As String

Private Sub Form_Load()
'specify the url to download from
fromFile = "https://davnit.net/bnet/vL/bbsImages/vl_logo_new.jpg"
'specify where to output the file to
toFile = App.Path & "\Temp.jpg"
'start the download
Load Form2
End Sub

Private Sub Form_Unload(Cancel As Integer)
'abort download
Unload Form2
End Sub

[/code]
[code]

'FORM2

'nothing here _
don't forget to add the UserControl to form2 using ToolBox

[/code]
[code]

'USERCONTROL1

Option Explicit

Private Type SHFILEOPSTRUCT
hWnd As Long
wFunc As Long
pFrom As String
pTo As String
fFlags As Integer
fAnyOperationsAborted As Long
hNameMappings As Long
lpszProgressTitle As Long
End Type

Dim Operation As SHFILEOPSTRUCT

Private Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

Private Sub UserControl_AsyncReadComplete(AsyncProp As AsyncProperty)
If AsyncProp.PropertyName = 69 Then
With Operation
.wFunc = 1
.pFrom = AsyncProp.Value
.pTo = Form1.toFile
.fFlags = &H100
End With
SHFileOperation Operation
MsgBox Form1.toFile
Unload Form2
End If
End Sub

Private Sub UserControl_Initialize()
UserControl.AsyncRead Form1.fromFile, vbAsyncTypeFile, 69
End Sub

[/code]
February 24, 2004, 6:58 AM
Adron
I don't see why using SetTimer and KillTimer is supposed to help. Don't they call in the context of the original thread, blocking that?

Also, as far as I can remember, the Inet transfer control operates just fine asynchronously, with events for when you receive some data.
February 24, 2004, 9:56 PM
Stealth
[quote author=Adron link=board=17;threadid=5421;start=0#msg45805 date=1077659802]
I don't see why using SetTimer and KillTimer is supposed to help. Don't they call in the context of the original thread, blocking that?

Also, as far as I can remember, the Inet transfer control operates just fine asynchronously, with events for when you receive some data.
[/quote]

You may be correct about the threading -- my testing of whether or not it actually stalled the rest of the operations wasn't very scientific.

In any event, I rewrote it as follows:

[code] 'Form_Load()
INet.Execute "http://www.cold-chaos.net/stealth/getver.php", "GET"
[/code]

[code]Private Sub INet_StateChanged(ByVal State As Integer)
If (State = icResponseCompleted) Then
Call HandleNews(INet.GetChunk(1024, icString))
End If
End Sub
[/code]
February 24, 2004, 10:39 PM

Search