# c++ Datei downloaden



## GeileEier (8. Mai 2010)

hallo,
ist es in C++ möglich eine datei aus dem internet auf seinen localen rechner zu downloaden?
bsp.
http://www.domain.de/datei.txt --> C:\datei.txt 

ich habe bereits google benutzt und bin auf *URLDownloadToFile ()* gestoßen.
das funktioniert aber nicht wirklich richtig.
gibt es noch andere methoden?
kennt ihr einen befehl der das ganze zu 100% kann?

danke


----------



## Cromon (8. Mai 2010)

URLDownloadToFile funktioniert einwandfrei.


----------



## GeileEier (8. Mai 2010)

Cromon hat gesagt.:


> URLDownloadToFile funktioniert einwandfrei.



das hier ist mein code:

```
#include <windows.h>
#include <string>

using namespace std;

int main() {

	HRESULT hr;
	string szUrl  = "http://www.forrester.com";
	string szFile = "C:\\test.html";

	hr = URLDownloadToFile ( NULL, szUrl.c_str() , szFile.c_str() ,0,NULL );

	if(!SUCCEEDED(hr)) {
		string mMessage = "Download failed";
		MessageBox(NULL, mMessage.c_str(), mMessage.c_str(), MB_OK | MB_ICONERROR);
	}

	return 0;

}
```

beim compilieren mit DEV-C++ bekomme ich immer folgenden fehler:


> error: `URLDownloadToFile' undeclared (first use this function)


----------



## sheel (8. Mai 2010)

edit: Include und Lib?

Urlom.h und urlmon.lib


----------



## GeileEier (8. Mai 2010)

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

using namespace std;

int main() {

    HRESULT hr;
    string szUrl  = "http://www.forrester.com";
    string szFile = "C:\\test.html";

    hr = URLDownloadToFile ( NULL, szUrl.c_str() , szFile.c_str() ,0,NULL );

    if(!SUCCEEDED(hr)) {
        string mMessage = "Download failed";
        MessageBox(NULL, mMessage.c_str(), mMessage.c_str(), MB_OK | MB_ICONERROR);
    }

    return 0;

}
```
jetzt bekomme ich auch noch den error "*urlmon.h: No such file or directory*"
ok, ich verknüpfe  *urlmon.h* die datei manuell aus dem ordner *"\Microsoft SDKs\Windows\v6.0A\"* auf mein projekt und erhalte eine rießen liste mit FEHLERN und ERRORS


----------



## Cromon (8. Mai 2010)

Ja, weil die nötigen anderen includes der URLMon.h nicht stimmen. Und zum Thema Dev-CPP:
Von diesem IDE ist abzuraten. Wird nicht mehr wirklich weiterentwickelt.

Passe einfach die Includeordner entsprechend an, dass das SDK auch da mit dabei ist.


----------



## GeileEier (8. Mai 2010)

am besten lade ich mir ein neues SDK runter.
welches soll ich da nehmen?


----------



## Maik (8. Mai 2010)

@GeileEier: http://www.tutorials.de/forum/php/359747-ftp-zugriff-mit-php.html#post1863995 habe ich heute Nacht nicht aus Jux und Dollerei gepostet.



			
				Netiquette #15 hat gesagt.:
			
		

> Unser Forum ist kein Chatroom. Kurz-Beiträge ("Ein-Zeilen Postings"), die einfach so ins Forum "geklatscht" werden, werden ohne Vorwarnung von einem Moderator oder Administrator gelöscht. Das gleiche gilt insbesondere für Beiträge, die in Rechtschreibung, Satzbau und Verständlichkeit nicht ein vernünftiges, allgemein übliches und altersgruppen-übergreifendes Niveau erfüllen. Jugendsprache, regional verbreitete Dialekte und *durchgehend kleingeschriebene Beiträge sind ebenfalls unerwünscht*. Mit anderen Worten: wer erfolgreich die im Deutsch-Unterricht erlernten Kenntnisse praxisnah auf unserem Forum anwenden kann, wird nicht mit dieser Regel in Konflikt kommen. "Wiederholungstäter" werden, nachdem sie zuvor von einem Moderator auf die Mängel hingewiesen wurden, ggf. unbefristet gesperrt.



Zitat-Quelle: http://www.tutorials.de/netiquette.html

Das ist jetzt meine zweite Aufforderung binnen weniger Stunden, dich an die Forenregeln zu halten. Bei weiterer Mißachtung sehe ich mich leider gezwungen, dir als Vorwarnung für einen begrenzten Zeitraum die Rechte zu entziehen, am Forenleben aktiv teilzunehmen.

mfg Maik


----------



## Cromon (8. Mai 2010)

GeileEier hat gesagt.:


> am besten lade ich mir ein neues SDK runter.
> welches soll ich da nehmen?



Das ist eine denkbar schlechte Idee. Das SDK ist komplett korrekt. Du kannst aber nicht einfach die URLMon.h kopieren, welche zig andere Dateien aus dem SDK includiert und dich dann wundern, dass die nicht mehr gefunden werden.

Füge in deinen Compilereinstellungen das Verzeichnis zum SDK einfach als eines der Standardincludeverzeichnisse hinzu.


----------



## deepthroat (10. Mai 2010)

Cromon hat gesagt.:


> Das ist eine denkbar schlechte Idee. Das SDK ist komplett korrekt. Du kannst aber nicht einfach die URLMon.h kopieren, welche zig andere Dateien aus dem SDK includiert und dich dann wundern, dass die nicht mehr gefunden werden.
> 
> Füge in deinen Compilereinstellungen das Verzeichnis zum SDK einfach als eines der Standardincludeverzeichnisse hinzu.


Man kann das MS Windows SDK nicht mit dem GCC verwenden.

Aber der GCC ist in der Lage direkt zu einer DLL zu linken. Man muss nur den richtigen Funktionsnamen verwenden:

```
extern "C" __declspec(dllimport)
HRESULT URLDownloadToFileA(          LPUNKNOWN pCaller,
    const char* szURL,
    const char* szFileName,
    DWORD dwReserved,
    void* lpfnCB
);

hr = URLDownloadToFileA ( NULL, szUrl.c_str() , szFile.c_str() ,0,NULL );
```
Das* #pragma comment() *versteht der GCC nicht.

Du mußt schon die urlmon.dll auf der Kommandozeile angeben.

Gruß


----------



## Cromon (10. Mai 2010)

Ich verwende nicht den GCC, aber gibt es einen Grund, warum der #pragma comment nicht implementieren will? Ob man es verwenden will ist ja dann immernoch jedem selbst überlassen. Ich finde die Funktionalitäten da wahnsinnig praktisch!


----------



## deepthroat (10. Mai 2010)

Cromon hat gesagt.:


> Ich verwende nicht den GCC, aber gibt es einen Grund, warum der #pragma comment nicht implementieren will? Ob man es verwenden will ist ja dann immernoch jedem selbst überlassen. Ich finde die Funktionalitäten da wahnsinnig praktisch!


Evtl. ist es technisch nicht möglich, da der GCC ein anderes Objekt-Datei-Format verwendet und man diese Informationen nicht in die Dateien einbinden kann. Dafür das Format, den Compiler und Linker zu ändern ist vermutlich zuviel Aufwand (zumal der Linker zu den GNU binutils gehört und nicht zum GCC).

Ich habe die Funktionalität des #pragma comment jedenfalls noch nicht vermisst.

Gruß


----------



## brunlorenz (13. Mai 2010)

Hallo, ich habe auch Dev-C++ und hier die Funktion:

```
#include <shlobj.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
#include <w32api.h>
#include <stdio.h>
#include <stdlib.h>
#include <wininet.h>
int DownloadFile(char url[],char file[])
{
 		  HINTERNET hInternet; 
HINTERNET hFile; 
HGLOBAL   hGlobal; 
FILE*     fFile; 
CHAR*     szBuf; 
BOOL      bGO = TRUE; 
DWORD     dwReadSize = 256; 
CHAR      lpszFileSize[15]; 
INT       iFileSize; 
INT       iStep; 
INT       iDownloadedBytes = 0; 
DWORD     dwDummy; 
TCHAR     szErrBuf[256]; 

LPCTSTR httpFile;
LPCTSTR targetFile; 
LPVOID lpInfo;
 		  hInternet = InternetOpen("Downloader", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); 
                                  if(!hInternet) 
                                  { 
                                                 return -1; 
                                  } 
                                  hFile = InternetOpenUrl(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0); 
                                  if(!hFile) 
                                  { 
                                             InternetGetLastResponseInfo(&dwDummy, szErrBuf, &dwReadSize); 
                                             InternetCloseHandle(hInternet); 
                                             return -1; 
                                  }

                                  dwDummy = 15; 
                                  HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH, (LPVOID)lpszFileSize, &dwDummy, NULL); 
                                  iFileSize = atoi(lpszFileSize); 
                                  if(iFileSize == 0) 
                                  { 
                                               InternetCloseHandle(hFile); 
                                               InternetCloseHandle(hInternet); 
                                               return -1; 
                                  } 
                                  iStep = (iFileSize / 100 == 0) ? 1 : iFileSize / 100; 

                                  hGlobal = GlobalAlloc(GMEM_FIXED, iStep + 1); 
                                  szBuf = (CHAR*)GlobalLock(hGlobal); 

                                  fFile = fopen(file, "w+b"); 
                                  while(bGO) 
                                  { 
                                             bGO = InternetReadFile(hFile, szBuf, iStep, &dwReadSize); 
                                             if(bGO && dwReadSize == 0) 
                                                    break; 
                                                    szBuf[dwReadSize] = '\0'; 
                                                    fwrite(szBuf, 1, dwReadSize, fFile); 
                                                    iDownloadedBytes = iDownloadedBytes + iStep;
                                  } 
                                  fclose(fFile);
                                  GlobalUnlock(hGlobal); 
                                  GlobalFree(hGlobal); 
                                  InternetCloseHandle(hFile); 
                                  InternetCloseHandle(hInternet);

}
```
Viel spass beim runterladen!
PS: noch libwinmm.a einbinden!
lorenz


----------

