wxDownloadFile

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

wxDownloadFile

Post by priyank_bolia »

Class for downloading a file from a given URL and send back event notification to the owner, when the download fails or complete.

http://www.priyank.in/downloads/
Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg »

Congrats! I took a glance at the source and it looks very useful. I have stored a copy in my favorite compoents dir because I am sure I can use it ...

Regards,
- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb
Chr
Earned some good credits
Earned some good credits
Posts: 115
Joined: Tue May 31, 2005 2:17 pm

Post by Chr »

maybe you can put it in wxCode?
wxWidgets is nice
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

Modified it little bit to return the file size if available and the number of bytes downloaded. Download from:
http://www.priyank.in/downloads/


An example:

Code: Select all

BEGIN_EVENT_TABLE(CMyFrame, wxFrame)
    EVT_DOWNLOAD(CMyFrame::OnDownloadEvent)
END_EVENT_TABLE()

void CMyFrame::OnDownloadMenu(wxCommandEvent &event)
{
	wxDownloadFile *pDownloadFile = new wxDownloadFile(this, wxT("http://www.codeproject.com/webservices/articlerss.aspx?cat=2"), wxT("CodeProjectMFC.xml"), true, 1000);
}

void CMyFrame::OnDownloadEvent(wxDownloadEvent &event)
{
	if(event.GetDownLoadStatus() == wxDownloadEvent::DOWNLOAD_COMPLETE || event.GetDownLoadStatus() == wxDownloadEvent::DOWNLOAD_FAIL)
	{
	}
	else if(event.GetDownLoadStatus() == wxDownloadEvent::DOWNLOAD_INPROGRESS)
	{
		wxInt64 nFileSize = event.GetFileSize();
		wxInt64 nDownloaded = event.GetDownLoadedBytesCount();
	}
}

This will help you to make the world's worst download manager :D
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

Chr wrote:maybe you can put it in wxCode?
Its already listed at: http://www.wxwidgets.org/contrib2.htm

Also it makes more easier for me to change parameters/files on my server rather than others. I can keep track on the number of downloads and others things. I still remember I asked them to create wxAutoStartUp and that take a lot of days to create, at that time I had already stopped working on that, also I still don't have the details on how to manage that on wxCode. Its still there with no files. I don't want to repeat such things and create mess there.
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Code added to read the proxy automatically in windows

Post by priyank_bolia »

Can be downloaded from:
http://www.priyank.in/downloads/

Code: Select all

#ifdef __WXMSW__
		wxRegKey *pRegKey = new wxRegKey(wxT("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"));
		if( pRegKey->Exists() && pRegKey->HasValue(wxT("ProxyEnable")))
		{
			long lProxyEnable;
			pRegKey->QueryValue(wxT("ProxyEnable"), &lProxyEnable);
			if(lProxyEnable == 1 && pRegKey->HasValue(wxT("ProxyServer")))
			{
				wxString strProxyAddress;
				pRegKey->QueryValue(wxT("ProxyServer"), strProxyAddress);
				Url.SetProxy(strProxyAddress);
				pIn_Stream = Url.GetInputStream();
			}
		}
		delete pRegKey;
#else
daddydave
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 214
Joined: Wed Jun 15, 2005 3:31 am
Location: United States
Contact:

Post by daddydave »

This looks very useful, as does your wxVCExpressIntegration
wizard. Thank you.
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

wxDownloadFile updated with the comments from ryandistel for proxy detection failure and event processing.
Can be downloaded from from: http://priyank.co.in
michalm
Earned some good credits
Earned some good credits
Posts: 122
Joined: Wed Dec 13, 2006 3:25 pm

Post by michalm »

Nope, this isn't useful.

Code: Select all

static enum DownloadSTATUS
	{
		DOWNLOAD_NONE = -2,				/// No Status, yet to be initialized
		DOWNLOAD_FAIL = -1,				/// Failed to download the file
		DOWNLOAD_RUNNING = 0,			/// Download is currently running
		DOWNLOAD_COMPLETE = 1,			/// Download has completed
		DOWNLOAD_INPROGRESS = 2			/// Number of bytes downloaded notification.
	};
"static" isn't allowed here (DevC++). static enums aren't allowed in C++ at all and I wonder how this can by compiled.
Why did you try to make this static? I suspect that making DOWNLOAD_NONE and others static will cause compile errors in this case.

I've removed static keyword, but downloading blocks the GUI and CPU usage is 100%.

To start download I use wxDownloadFile::Entry - downloading wont't start without it.

Is there something wrong with this class or maybe I'm doing wrong?
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

michalm wrote:Nope, this isn't useful.

"static" isn't allowed here (DevC++). static enums aren't allowed in C++ at all and I wonder how this can by compiled.
Why did you try to make this static? I suspect that making DOWNLOAD_NONE and others static will cause compile errors in this case.
I am still learning, may be static is not required. But its compiling on all MS compilers, and no one ever reported a compilation error, while so many people using it and providing patches.
michalm wrote:I've removed static keyword, but downloading blocks the GUI and CPU usage is 100%.

To start download I use wxDownloadFile::Entry - downloading wont't start without it.

Is there something wrong with this class or maybe I'm doing wrong?
Its a thread, you don't need to call the Entry function manually, put a break point in the constructor where it creates the thread and start it, and check whether the thread is successfully created.
michalm
Earned some good credits
Earned some good credits
Posts: 122
Joined: Wed Dec 13, 2006 3:25 pm

Post by michalm »

Hmm it seems that thread doesn't start until I call Entry manually.
But generally starting download in constructor is not very good idea, there should exist something like "Start" or "Begin".
But its compiling on all MS compilers, and no one ever reported a compilation error, while so many people using it and providing patches.
I'm confused - it seems this code is for MS C++ and not for real C++ - I'm pretty sure that static enums are not C++ standard.
It doesn't compile in Borland too (Error: "static strorage class not allowed here")

And one more thing - what about blocking gui and CPU? I assume this code works for you, have you tried using it in GUI apps? I mean indicating progress in progress bar for example.
I'm not wxWidgets expert - maybe I have ommited something.
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

Regarding static enums, just remove the static keyword. It looks you are right, but MS compilers take it, and I don't have means and knowledge to test it on all platforms.


Regarding GUI, the problem is you are not using threads, you are directly calling the entry function in the same thread. As a said I don't have idea why thread is not working on your machine. You can remove that piece of code from constructor and move it to your main application. Also try to create some other threads and see whether threading works in your program or not.
I put the code into constructor, because its the same code I need everywhere without any modification. I makes life easier for me, by having to write just one line in the client application.
michalm
Earned some good credits
Earned some good credits
Posts: 122
Joined: Wed Dec 13, 2006 3:25 pm

Post by michalm »

It seems that threads demo application for wxWidgets works fine.
I have no idea where is the problem, I'll check everything again and post my comments here if unsuccessful.
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

Did you debug inside the constructor whether the thread is created and started smoothly or not? try to move that code outside the constructor into your application.
michalm
Earned some good credits
Earned some good credits
Posts: 122
Joined: Wed Dec 13, 2006 3:25 pm

Post by michalm »

I use wxdevC++

Code for donwload:

Code: Select all

void testDlg::WxButton1Click(wxCommandEvent& event)
{
 pDownloadFile = new wxDownloadFile(this,"http://j.o2.pl/idi/tleninst60269.exe","tleninst60269.exe",true, 1000);
 //pDownloadFile->Entry();

 if(pDownloadFile->Create()!= wxTHREAD_NO_ERROR )
    wxMessageBox("Can't create download thread!");

 if(pDownloadFile->Run() != wxTHREAD_NO_ERROR )
    wxMessageBox("Can't start download thread!");

}
Code for events:
void testDlg::OnDownloadEvent(wxDownloadEvent &event)
{

if(event.GetDownLoadStatus() == wxDownloadEvent::DOWNLOAD_INPROGRESS)
{
wxInt64 nFileSize = event.GetFileSize();
wxInt64 nDownloaded = event.GetDownLoadedBytesCount();

progressBar->SetValue((nDownloaded*100)/nFileSize);
pDownloadFile->Yield();
}


}
As a result: no message boxes popups, so I assume that thread is created without errors. But download file is not created and download doesn't start at all.

If I call Entry() directly it works, but as you said above, donwloading is not threated.

What's wrong?

[added]
I checked it again, and it seems, that Entry() returns immediately after this line:

Code: Select all


//Thanks to maxinuruguay for the timeout fix.
((wxProtocol &)Url.GetProtocol()).SetTimeout(100);
wxInputStream *pIn_Stream = Url.GetInputStream();
So downolad doesn't even starts. But only if used in thread - if I call Entry directly, it works...

For example:

Code: Select all

if (Url.GetError() == wxURL_NOERR)
	{
		//Thanks to maxinuruguay for the timeout fix.
		((wxProtocol &)Url.GetProtocol()).SetTimeout(100);


		wxInputStream *pIn_Stream = Url.GetInputStream();
		wxMessageBox("AAA");
AAA won't appear in this case. But message appears if I place it after SetTimeout;

I'm not expert.. but is wxURL::GetInputStream() thread safe? Maybe you shold use mutexes, critical sections, etc.. here? I have no idea what's wrong. I can chceck what happen when I run this code on Linux, but there is something wrong here.
Post Reply