Eugen-Andrei Coliban
Eugen-Andrei Coliban

Reputation: 1090

File downloaded by CURL in C++ cannot be opened

I'm working upon a program in C++, where I have to download a file using cURL, and further open it, but the problem is that when I try to open the file after downloading, it isn't opening. I'm trying to open an .exe file. Here's the portion of code, which is responsible for file download

curl = curl_easy_init();
    if (curl) {
        fp = fopen(outfilename.c_str(), "w");
        curl_easy_setopt(curl, CURLOPT_URL, links[index]);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        fclose(fp);
    }

and the line which should open the downloaded file :

ShellExecute(NULL, "open", fileToLaunch.c_str() , NULL, NULL, SW_HIDE);

When I try to launch manually the file (by clicking on it), Windows returns me an error message which says that respective app isn't a Win32 app. I'm using Visual Studio 2017.

Here's the whole chunk of code :

#include <stdio.h>
#include <curl/curl.h>
#include <curl/easy.h>
#include <string>
#include <iostream>
using namespace std;

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
    size_t written = fwrite(ptr, size, nmemb, stream);
    return written;
}

int main(void) {
    CURL *curl;
    FILE *fp;
    CURLcode res;
    string url = "Here goes the url for file download";
    string outfilename = "C:\\1.exe";
    curl = curl_easy_init();
    if (curl) {
        fp = fopen(outfilename.c_str(), "wb");
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        fclose(fp);
    }
    return 0;

    ShellExecute(NULL, "open", outfilename.c_str(), NULL, NULL, SW_HIDE);
}

Upvotes: 1

Views: 648

Answers (2)

SangHun
SangHun

Reputation: 201

First of all this line should be deleted :

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);

because write_data function has the same functionality, as cURL's CURLOPT_WRITEDATA, and so, the line below the one which should be deleted will be enough, and secondly, on the line where curl_easy_setopt() is firstly met:

curl_easy_setopt(curl, CURLOPT_URL, url);

you should add to the url parameter .c_str(), so it will look like this :

curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

because this function is unable to operate with string type of data...

And as Rob K mentioned, you have to change 'w' to 'wb' in fopen() function, because you are working with a binary stream of data.

Upvotes: 2

Rob K
Rob K

Reputation: 8926

Change

fp = fopen(outfilename.c_str(), "w");

to

fp = fopen(outfilename.c_str(), "wb");

You're writing it to disk as text with newline translations by default. You need to write it as binary.

See https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=vs-2017 for a fuller explanation.

Upvotes: 3

Related Questions