Datei uploaden mit WINNET?

Danke euch allen.


Das werde ich unbedingt nachlesen.

Ich hab das HTML-Skript hier kopiert. Es kümmert sich darum, die Datei zuerst auszuwählen und dann auf den Server hochzuladen(durch Select & Submit Buttons, ganz normal und trivial).

HTML:
<HTML>
<TITLE>Upload</TITLE>
<BODY text="#000000" bgcolor="#FFFFFF" link="#CCCCCC" alink="#CC99CC" vlink="#CCCCAA" leftmargin="0" topmargin="0">
<TABLE WIDTH="100%" HEIGHT="100%" ALIGN="LEFT" border="0" cellspacing="0">
<TR>
<TD ALIGN="CENTER" VALIGN="MIDDLE" WIDTH="25%" HEIGHT="90" BGCOLOR="orange">
<FONT SIZE="5">UPLOAD</FONT>
</TD>
<TD WIDTH="75%" HEIGHT="90" ALIGN="CENTER" VALIGN="MIDDLE" BGCOLOR="#6487dc">
<FONT SIZE="5"><A HREF="home">TEST</A>
</FONT SIZE><BR>
<FONT SIZE="4">Upload Code
<TR>
<TD COLSPAN="2" HEIGHT="*" VALIGN="TOP" ALIGN="LEFT" BGCOLOR="#8CAAE6"><BR></FONT SIZE>
<FORM ENCTYPE="multipart/form-data" METHOD=POST>    File to process: 
<INPUT NAME="userfile2" TYPE="file">    
<INPUT TYPE="submit" VALUE="Send File">
</FORM>
<HR>
<P align=left><i>Last update: Jul 01 2007 12:02:46
</BODY>
</HTML>

Darin sehe ich, daß hinter "METHOD=POST" nicht wie normal "ACTION=xxx.php" steht, das letzte dann auf ein PHP Skript auf dem Server verweist. Das ist aber abnormal, oder? Und ich weiß auch nicht, wie es funktioniert.

Außerdem, die Unterstützung vom Server die Datei zu empfangen steht auf jeden Fall da. Per FTP würde ich eher abraten, da keine Kennung oder Passwort benötigt werden. Ob es über HTTP auch gehen solltee, bin ich jetzt langsam skeptisch geworden nach dem Lesen der Meinungen von euch...
 
Der dritte Wert im HttpOpenRequest() ist NICHT die Datei auf deinem Rechner, sondern die Zieldatei auf dem Server, sprich das .php Script, was die Daten empfängt.
HttpOpenRequest() stellt lediglich eine Verbindung zwischen deinem Rechner und der Zieldatei her, erst HttpSendRequest() sendet deine Daten.
Ich kann dir nicht sagen, wie das mit Dateiupload aussieht, aber das dürfte nicht viel anders sein als mit strings.

Was ich dir geben kann ist ein funktionierendes Beispiel, wie man einen string sendet:
Ich nehme an, alles was du tun musst ist nichts weiter als den Content-Type ändern und deinen Dateiinhalt als void* senden.

Nach deinem Hinweis habe ich meinen Code wie folgt angepasst.

Code:
void Upload()
{
HINTERNET inet = InternetOpen("Http Upload", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);

if(inet != NULL)    
{
HINTERNET connection    = NULL;
HINTERNET request       = NULL;        
unsigned long flags     = INTERNET_FLAG_PRAGMA_NOCACHE;        
char buffer[1024];        
DWORD InfoLevel, BufferLength;                     

connection = InternetConnect(inet, "xxx.xx.x.x/upload", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,INTERNET_SERVICE_HTTP,flags,1);

if(connection != NULL)        
{                                     
const char* ContentType = "multipart/form-data";  
                                                    
request = HttpOpenRequest(connection, "POST", NULL, NULL,  NULL, &ContentType, NULL,NULL);                 

//Einlesen der hochzuladenen Datei
	ifstream f;
	f.open("C:\\xxx");
	if(!f.good())
	{
		cout << "Open start file failed!" << endl;
		ExitProcess(0);
	}

	std::string c;
	c.erase();
	c.reserve(f.tellg());
	f.seekg(0);
	while(!f.eof())
	{
		c += f.get();
	}



	HttpSendRequest(hRequest,"multipart/form-data",19,(void*)c.c_str(),c.size());
}                                                    
 
InternetCloseHandle(request);
InternetCloseHandle(connection);                                
InternetCloseHandle(inet);     
}
}

Aber ich bin immer auf den Fehler "12150" angestoßen. Warum?:confused:
 
Zuletzt bearbeitet:
Hi.

Du hast falsch abgeschrieben. Der HttpSendRequest muss so aussehen:
C++:
HttpSendRequest(hRequest, "Content-Type: multipart/form-data", -1, static_cast<void*>(c.data()),c.size());

Außerdem ist liest du die Datei falsch und unnötig kompliziert ein.
C++:
std::string c(std::istream_iterator<char>(f), std::istream_iterator<char>());
\edit: oder falls du die Größe vorher angeben willst:
C++:
std::string c;
c.reserve(...);
c.assign(std::istream_iterator<char>(f), std::istream_iterator<char>());

Außerdem solltest du die Datei im Binärmodus öffnen.

Gruß

PS: Wenn du im Header als Content-Type "multipart/form-data" angibst, dann mußt du die Daten natürlich auch in dem Format liefern!
 
Zuletzt bearbeitet:
Hi.

Du hast falsch abgeschrieben. Der HttpSendRequest muss so aussehen:
C++:
HttpSendRequest(hRequest, "Content-Type: multipart/form-data", -1, static_cast<void*>(c.data()),c.size());

Ich hab mein .hml Skript nochmal geschaut. Sollte die Funktion HttpSendRequest() vielleicht so aussehen?
C++:
HttpSendRequest(hRequest, "ENCTYPE='multipart/form-data'", -1, static_cast<void*>(c.data()),c.size());

Und warum steht -1 als der dritte Para.?
Soll es nicht die Länge des vorausstehenden Strings sein, wie im Beispielcode von Thomasio?

Übrigens noch eine Fehlermeldung:
C++:
error C2440: 'static_cast' : cannot convert from 'const char *' to 'void *'

wenn ich "static_cast<void*>" auf "(void*)" ändere, verschwindet dieser Fehler. Woran kann es liegen?
 
Zuletzt bearbeitet:
Danke, deepthroat. Nun hab ich die Funktion HttpSendRequest() wie folgt:
C++:
HttpSendRequest(request, "Content-Type: multipart/form-data", -1, (void*)(c.data()), c.size());
Es gibt zwar keine Fehlermeldung mehr, aber das Uploaden scheint trotzdem schief. Durch Abfragen über
C++:
if(HttpQueryInfo(request, HTTP_QUERY_SERVER, (LPVOID)buffer, &BufferLength, NULL))
  cout << "Getting Query Info: " << buffer;
else
  {
  cout << "Error of getting Query Info: " << GetLastError() << endl; 
  }

Und es liefert 12019 zurück, also "The requested operation cannot be carried out because the handle supplied is not in the correct state."

Any idea?
 
Hast du denn die Daten ordentlich formatiert?

Den Text habe ich durchgelesen. Aber ich bin nicht ganz klar, was du mit den Daten meinst. Meinst du die hochzuladene Datei oder das .htm Skript?
Die hochzuladene Datei ist binär (Dementsprechend habe ich auch das Einlesen in String im Code angepasst) und kann nicht formatiert werden, oder?
Das .htm Skript steht auf dem Server und kann nicht verändert werden.

Eine Frage noch, wie du siehst, im .htm Skript steht "NAME="userfile2"". Spiels es für das Uploaden auch ne Rolle?
 
Den Text habe ich durchgelesen. Aber ich bin nicht ganz klar, was du mit den Daten meinst. Meinst du die hochzuladene Datei oder das .htm Skript?
Das HTML Skript hat damit überhaupt nichts zu tun.

Die Daten der Datei müssen entsprechend deiner Angabe von multipart/form-data eben auch in diesem Format sein, d.h. du mußt diese Daten in eine MIME Nachricht entsprechend RFC 2045 verpacken.
Eine Frage noch, wie du siehst, im .htm Skript steht "NAME="userfile2"". Spiels es für das Uploaden auch ne Rolle?
Ja, natürlich.

Das ist doch aber alles genau - sogar mit Beispiel - hier erklärt.

Gruß
 
Zurück