Sign in to follow this  
Followers 0
JohnOne

URLDownloadToFile

22 posts in this topic

#1 ·  Posted (edited)

Hoping someone can point out my errors.

Been looking for a C++ solution for something like _InetGetSource()

I was expecting this code to download something (even just binary data) but it just defaults in switchblock.

I'd sure appreciate some pointers.

#include "stdafx.h"
#include <urlmon.h>
#include <iostream>
using namespace std;

#pragma comment(lib, "urlmon.lib")

int main()
{
    char x;

    HRESULT hresult = URLDownloadToFile( NULL, "http://www.google.com/", "C:\\Users\\john\\desktop.html", 0, NULL );
    switch (hresult)
    {
        case S_OK:
            std::cout << "OK";
        case E_OUTOFMEMORY:
            std::cout << "out of memory";
        case INET_E_DOWNLOAD_FAILURE:
            std::cout << "download failed";
        default:
            std::cout << "some other value";
    }
    std::cin >> x;

    return 0;
}
http://msdn.microsoft.com/en-us/library/ms775123%28v=vs.85%29.aspx Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites



You could always just print the HRESULT and Google it, works better than guessing what may be wrong.

Share this post


Link to post
Share on other sites

I was expecting this code to download something (even just binary data) but it just defaults in switchblock.

You need a break.

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I'd sure appreciate some pointers.

here you go: char* form; Edited by hyperzap

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

You need a break.

Cant believe I missed them out, was falling through, but still same dance with them in

Heres my new code but still the same undesired result.

#include "stdafx.h"
#include <urlmon.h>
#include <iostream>
using namespace std;

#pragma comment(lib, "urlmon.lib")

int main()
{
    char x;
    char *url = "http://www.google.com/";
    char *file = "C:\\Users\\john\\desktop.html";
    HRESULT hresult = URLDownloadToFile( NULL, url, file, 0, NULL );
    switch (hresult)
    {
        case S_OK:
            std::cout << "OK";
            break;
        case E_OUTOFMEMORY:
            std::cout << "out of memory";
            break;
        case INET_E_DOWNLOAD_FAILURE:
            std::cout << "download failed";
            break;
        default:
            std::cout << "some other value";
    }
    std::cin >> x;

    return 0;
}
Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

Print the hresult as danielkza suggested to see what's happening.

Out of curiosity, do you know what

using namespace std;
...means and why are you using it?

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Print the hresult as danielkza suggested to see what's happening.

Out of curiosity, do you know what

using namespace std;
...means and why are you using it?

I think I do, right or wrong, i think its just the same as #using

Its in there from the start when I wasnt typing std::cout.

the code has morphed with everything I have tried and perhaps its relic.

I'm not ashamed to admit that I wouldnt know how to "print" hresult, because I just dont even know what type it is.

I learn by "do and try" not books or a thousand years of study (sorry kids dont listen to me) I dont have that time.

The penny only drops with me after the fact, old dog new tricks and all that.


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

II'm not ashamed to admit that I wouldnt know how to "print" hresult, because I just dont even know what type it is.

I learn by "do and try" not books or a thousand years of study (sorry kids dont listen to me) I dont have that time.

The penny only drops with me after the fact, old dog new tricks and all that.

You said hresult is HRESULT.

If you "do and try" then why haven't you tried the most obvious std::cout << hresult; to see what happens? :unsure:

Good luck with your code, you old dog :>

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

You said hresult is HRESULT.

If you "do and try" then why haven't you tried the most obvious std::cout << hresult; to see what happens? :>

Good luck with your code, you old dog ;)

I did, but got some silly result like -214xxxxx or something and assumed it was because of type of var.

And never mind "Good luck with your code" darlin, I'm counting on you here sugarplum :unsure:

Well not really, I know I'll get it in the end, but the reason I asked for help here is because the internet has failed me, it seems to be a poorly discussed function even on C++ forums. I figured there are top of the pops people here and tried my luck.

I think you have given me a good clue in your cryptic way and feel I should have gotten it, so I'm a bit disappointed with myself, but at the same time think the function might be a bit shit and flawed.

Dont abandon me trancexx !


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

HRESULT is just a DWORD which is an unsigned long, which is the same width of an unsigned int. Basically Uint32.

Share this post


Link to post
Share on other sites

JohnOne, I have absolutely no idea what you were doing wrong, but I just wrote something that worked first time. Here is the complete solution so no project settings should matter: JohnOnesTest.zip.

JohnOnesTest.cpp

#include "stdafx.h"
#include <stdio.h>

#include <urlmon.h>
#pragma comment(lib, "urlmon.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    wchar_t* sUrl = L"http://www.google.com/";
    wchar_t* sFile = L"C:\\desktop.html";

    printf("~~~ Downloading file ~~~\nFrom: %S\nTo:   %S\n", sUrl, sFile);

    HRESULT hr = URLDownloadToFile(0, sUrl, sFile, 0, 0);

    if (SUCCEEDED(hr))
        printf("It worked :) returned: %d", hr);
    else
        printf("Oh noes :( returned: %d", hr);

    getchar();

    return 0;
}

For anyone about to tell me off... That was a quick and cheerful solution. I wouldn't usually mix string types.

Share this post


Link to post
Share on other sites

Thanks Mat, I'll have a look at that now.

Heres some of what I was attempting, and might have gotten around to using wchar_t eventually (but probably would have been some time)

#include "stdafx.h"
#include <urlmon.h>
#include <iostream>
#include <string.h>
//#include <Objbase.h>
using namespace std;

#pragma comment(lib, "urlmon.lib")

int main()
{

    char x;
    
    //string csurl = "http://www.google.com/";
    //CString csfile (L"C:\\Users\\john\\desktop.txt");
    const char *url = "http://www.google.com/";
    const char *file = "C:\\Users\john\desktop.txt";
    //TCHAR url[] = _T("http://www.google.com/");
    //LPCTSTR myurl = url;
    //TCHAR file[] = _T("C:\\Users\\john\\desktop.txt");
    //LPCTSTR myfile = file;
    HRESULT hresult = URLDownloadToFile( NULL, (LPCTSTR)url, (LPCTSTR)file, 0, NULL );
    //HRESULT hresult = URLDownloadToFile( NULL, myurl, myfile, 0, NULL );
    cout << hresult << "\n"; //-2146697211 multibyte / -2146697203 unicode
    switch (hresult)
    {
        case S_OK:
            std::cout << "OK";
            break;
        case E_OUTOFMEMORY:
            std::cout << "out of memory";
            break;
        case INET_E_DOWNLOAD_FAILURE:
            std::cout << "download failed";
            break;
        default:
            std::cout << "some other value"; // always this
    }
    std::cin >> x;

    return 0;
}

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Cheers Mat, knowing that code worked for you, and not for me, made me look at possible problems.

My firewall had updated and not restarted. It was blocking all new apps without asking and that was a problem from the start :unsure:

This was fine as well as your code.

#include "stdafx.h"
#include <urlmon.h>
#include <iostream>
#include <string.h>
//#include <Objbase.h>
using namespace std;

#pragma comment(lib, "urlmon.lib")

int main()
{

    char x;
    
    TCHAR url[] = _T("http://www.google.com/");
    LPCTSTR myurl = url;
    TCHAR file[] = _T("C:\\Users\\BOB\\desktop.txt");
    LPCTSTR myfile = file;
    HRESULT hresult = URLDownloadToFile( NULL, myurl, myfile, 0, NULL );
    cout << hresult << "\n";
    switch (hresult)
    {
        case S_OK:
            std::cout << "OK";
            break;
        case E_OUTOFMEMORY:
            std::cout << "out of memory";
            break;
        case INET_E_DOWNLOAD_FAILURE:
            std::cout << "download failed";
            break;
        default:
            std::cout << "some other value";
    }
    std::cin >> x;

    return 0;
}

Thanks for the clarification about the HRESULT type Richard.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

Good to see it working :> I just use the FAILED and SUCCEEDED macros for working with HRESULTs (that's a lie, I have never used FAILED, only !SUCCEEDED :unsure: )

HRESULT is just a DWORD which is an unsigned long, which is the same width of an unsigned int. Basically Uint32.

HRESULT is defined as being LONG, which is a 32 bit signed integer. This is very important as the success of an operation is determined by the fact that the HRESULT code is greater than or equal to zero.

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Good to see it working :> I just use the FAILED and SUCCEEDED macros for working with HRESULTs (that's a lie, I have never used FAILED, only !SUCCEEDED :unsure: )

HRESULT is defined as being LONG, which is a 32 bit signed integer. This is very important as the success of an operation is determined by the fact that the HRESULT code is greater than or equal to zero.

What operation? URLDownloadToFile? It's not.

You should never use SUCCEEDED(hresult) if you just want to check against S_OK, as you should with URLDownloadToFile function according to the documentation for that function. Meaning your code is not correct.

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

What operation? URLDownloadToFile? It's not.

You should never use SUCCEEDED(hresult) if you just want to check against S_OK, as you should with URLDownloadToFile function according to the documentation for that function. Meaning your code is not correct.

S_OK = zero, so it works. It's certainly the case that you wouldn't want to just check the returns listed on msdn. Why have different rules for checking for success when there is a one size fits all solution that is easy to understand?

Share this post


Link to post
Share on other sites

S_OK = zero, so it works. It's certainly the case that you wouldn't want to just check the returns listed on msdn. Why have different rules for checking for success when there is a one size fits all solution that is easy to understand?

You are being vague with SUCCEEDED(). S_OK for that function means success (The download started successfully).

I can imagine (just imagination really) this situation: URLDownloadToFile function returns S_FALSE (Already downloaded).

Your code would interpret it as a success, but in reality it's a failure because no download actually occurred.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

You are being vague with SUCCEEDED(). S_OK for that function means success (The download started successfully).

I can imagine (just imagination really) this situation: URLDownloadToFile function returns S_FALSE (Already downloaded).

Your code would interpret it as a success, but in reality it's a failure because no download actually occurred.

Already downloaded means the files there, and can be used. In 99% of cases that means success. If you know that you always want to download a new file then delete the file beforehand. If you look at it the other way round, if I wanted to treat S_FALSE as a success, I'd have to compare it against at least two values... If there were 200 different possible success codes then do you really want to test all of them?

I would still do if (SUCCEEDED(hr) && (hr != S_FALSE)) {}

Share this post


Link to post
Share on other sites

I'm surprised HRESULT isn't unsigned. Honestly, I hate it when types are defined via typedef and #define. It would be significantly easier if types were called their types and only got a new name if they were different.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0