How to Download a file from internet without using UrlDownloadToFile() ???

Aug 8, 2013 at 7:31am
closed account (3hMz8vqX)
Hi All,

I recently heard about the URLDownloadToFile() function
This works only on Visual Studio and does not work with other compilers . . .

Can anyone give me a code to download file from internet using C++ . . .

Im a beginner at WINAPI C++
But I like the URLDownloadToFile() . . .

Can anyone give a suggestion about any free compiler which supports this
URLDownloadToFile() ???

Does codeblocks 12.11 support this ???

Thankyou, everyone in advance!!!
Aug 8, 2013 at 8:21am
The issue isn't the compiler, it's the Windows SDK. The SDK which comes with MinGW doesn't always include urlmon.h or urlmon.lib.
(Edit: add "always" in resp to mordoran's post)

You can download the Windows SDK from Microsoft's website and use the header and library from it, but it's a bit of a hack:
How to use the URLDownloadToFile() Function???
http://www.cplusplus.com/forum/windows/107840/#msg585474

Or you can use LoadLibrary to dynamically load on urlmon.dll and obtain the address of URLDownloadToFile with GetProcAddress.
LoadLibrary function
http://msdn.microsoft.com/library/ms684175%28VS.85%29.aspx
GetProcAddress function
http://msdn.microsoft.com/en-us/library/ms683212%28v=vs.85%29.aspx

Code::Blocks is not a compiler either. It's an IDE, which is usually used with the MinGW version of the GCC compiler on Windows. You can use Code::Blocks with the Visual C++ compiler if you want to.

Or you download the file using either (Windows specific) WinINet functions (wininet.h and winient.lib are provided by the MinGW) or using a third party library (the most well kown is probably cURL)

WinINet: The opening post of this thread shows a function which pretty much does what you want:
Get data from a Internet file into a char
http://www.cplusplus.com/forum/windows/62128/
(But note that the buffer is newed and deleted on avery loop when the same buffer could be reused; the poster was in the process of converting the function from one which downloaded to a file to one which downloaded to a set of memory buffers.)

cURL: See this post
cUrl, how to retreive the contents of a url
http://www.cplusplus.com/forum/unices/45878/#msg249287

Andy
Last edited on Aug 8, 2013 at 11:05am
Aug 8, 2013 at 10:52am
The issue isn't the compiler, it's the Windows SDK. The SDK which comes with MinGW doesn't include urlmon.h or urlmon.lib.


It does, at least MinGW-w64 from here:
http://tdragon.net/recentgcc/

It can easily be used with Code::Blocks, this is what I use myself.
Aug 8, 2013 at 11:06am
Added "always" to my prev post, wrt inclusion of urlmon.h/.lib by MinGW

Andy
Aug 8, 2013 at 5:25pm
I used to use MingW with Code::Blocks for awhile but honestly it's not worth the hassle. There are few things more frustrating then getting into a project only to realize you don't have the library to support some random function that you need. I used the LoadLibrary GetProcAddress trick for awhile but eventually you realize that if you're using the WinAPI, then you might as well use a compiler that has full support for it. It's not like your stuff is going to work on *nix anyway (outside of WINE that is). Code::Blocks works fine with MS V C++ on Windows some of the function calling conventions are different but it's not that hard to learn them.
Aug 8, 2013 at 11:51pm
Just in case the OP is interested in a cross platform solution there is Boost.Asio

This is a function I use to download files using it, I adapted it from http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/example/cpp03/iostreams/http_client.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <boost/asio.hpp>
#include <iostream>
#include <string>
#include <fstream>

std::string get_http_data(const std::string& server, const std::string& file)
{
	try
	{
		boost::asio::ip::tcp::iostream s(server, "http");
		s.expires_from_now(boost::posix_time::seconds(60));

		if (!s){ throw "Unable to connect: " + s.error().message(); }

		// ask for the file
		s << "GET " << file << " HTTP/1.0\r\n";
		s << "Host: " << server << "\r\n";
		s << "Accept: */*\r\n";
		s << "Connection: close\r\n\r\n";

		// Check that response is OK.
		std::string http_version;
		s >> http_version;
		unsigned int status_code;
		s >> status_code;
		std::string status_message;
		std::getline(s, status_message);
		if (!s && http_version.substr(0, 5) != "HTTP/"){ throw "Invalid response\n"; }
		if (status_code != 200){ throw "Response returned with status code " + status_code; }

		// Process the response headers, which are terminated by a blank line.
		std::string header;
		while (std::getline(s, header) && header != "\r"){}

		// Write the remaining data to output.
		std::stringstream ss;
		ss << s.rdbuf();
		return ss.str();
	}
	catch(std::exception& e)
	{
		return e.what();
	}
}

int main() 
  {
	//http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
	  std::string result = get_http_data("www.open-std.org", "/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf");

	  std::ofstream of("cpp11_draft_n3242.pdf", std::ios::binary);
	  of << result;
  }
Topic archived. No new replies allowed.