Rückgabewerte abfangen (z. B. von PHP)
-
Ich arbeite mit C++ unter Windows.
-
Dieser Thread wurde von Moderator/in Marc++us aus dem Forum Linux/Unix in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
logout schrieb:
Mein Aufruf über *FILE pipe = _popen("php.exe -f script.php", "r"); liefert mit kein Handle zurück.
Bei mir klappt das. Allerdings muss man den vollen Pfad zur
php.exe
und zumscript.php
angeben (doppelte Backslashes!).Informativ:
http://msdn.microsoft.com/en-us/library/96ayss4b.aspx
viele grüße
ralph
-
Hallo,
aus einem Programm mit GUI aufgerufen wird das nicht funktionieren, siehe "Note" in der schon von rkhb angegebenen Dokumentation.
MfG,
Probe-Nutzer
-
Hmm.. ja, tatsächlich. Das ist aber schade. Zumindest läuft es nun halbwegs und ich kann den Rückgabewert in ReadFromPipe() auslesen. Allerdings habe ich noch zwei kleine Fragen:
- Ich möchte den Code in einer Serveranwendung einsetzen (die Indy Bibliothek im C++Builder) die jedoch komplett mit Threads läuft. Ich nehme an, das Beispiel von Microsoft ist nicht Thread-sicher und ich müsste den Code entsprechend anpassen, oder?
- Ich habe nicht ganz verstanden, warum ich eine Eingabedatei (g_hInputFile) benötige? Falls ich das richtig interpretiere, wird der Inhalt (in meinem Fall) an die PHP Instanz gesendet. Das bräuchte ich in meinem Fall aber vermutlich nicht, da ich die Werte als Parameter übergebe. Oder muss ich unbedingt etwas mittels WriteToPipe() senden bevor ich die Antwort lesen kann?
PS: Danke für den Hinweis
-
Vielleicht hilft Dir das hier weiter:
http://www.c-plusplus.net/forum/248213?highlight=pipe
Das habe ich zwar bisher nur aus einem Konsolenprogramm getestet, sollte aber auch in einem Windowsprogramm funktionieren.
-
Probe-Nutzer schrieb:
aus einem Programm mit GUI aufgerufen wird das nicht funktionieren
Ich geb ja zu, das OP nicht gründlich genug gelesen zu haben. Allerdings hatte ich auch irgendwoanders gelesen, dass der Hinweis von MS veraltet ist.
Folgender Quickhack funktioniert bei mir:
#include <windows.h> #include <stdio.h> #include <stdlib.h> #include <tchar.h> HWND hwndMain; LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static TCHAR msgBuffer[4096] = TEXT(""); switch (uMsg) { case WM_CREATE: { FILE* tmp = fopen ("tmp.php","wb"); fputs ("<?php\necho \"Hallo Welt\";\n",tmp); fclose (tmp); TCHAR psBuffer[128] = {0}; FILE *pPipe = _popen( "C:/WAMPPP/PHP/php_5-2-4/php.exe -f tmp.php", "rt" ); if( !pPipe ) exit( 1 ); while(_fgetts(psBuffer, 128, pPipe)) _tcscat(msgBuffer,psBuffer); _pclose (pPipe); remove ("tmp.php"); break; } case WM_PAINT: { PAINTSTRUCT ps; HDC hDC = BeginPaint(hWnd, &ps); RECT rt = { 5, 5, 50, 50 }; DrawText(hDC, msgBuffer, _tcslen(msgBuffer), &rt, DT_CALCRECT); DrawText(hDC, msgBuffer, _tcslen(msgBuffer), &rt, 0); EndPaint( hWnd, &ps ); break; } case WM_CLOSE: { DestroyWindow( hWnd ); PostQuitMessage(0); break; } } return DefWindowProc(hWnd,uMsg,wParam,lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { (void)lpszCmdLine; // suppress warning: unused parameter 'lpszCmdLine' // Register the window class for the main window. WNDCLASS wc = {0}; wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = TEXT("rbMainMenu"); wc.lpszClassName = TEXT("rbWndClass"); if (!RegisterClass(&wc)) return 1; hwndMain = CreateWindow( _T("rbWndClass"),_T("PHP-Output"), WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT, 400,300, NULL, NULL, hInstance, NULL ); if (!hwndMain) return 2; ShowWindow(hwndMain, nCmdShow); UpdateWindow(hwndMain); for (MSG msg; GetMessage(&msg, NULL, 0, 0) > 0; TranslateMessage(&msg),DispatchMessage(&msg)); return 0; }
Ist das nun Zufall, dass der funktioniert, oder nicht?
viele grüße
ralph
-
Seltsam. Könntest du mir bitte sagen, woran das genau lag (oder klappt das wegen dem ganzen Code drum herum (insbesondere CreateWindow)? Ich nutze wie gesagt die VCL die das irgendwo ebenfalls selbst macht, aber auch bei diesem Code springt er bei der Prüfung des File Handlers raus (obwohl sie bei dir mit dem Fenster ja offensichtlich funktioniert
). Ich verstehe nicht ganz was der genaue Grund dafür ist, dass die _popen() Funktion nicht will.
Edit:
Belli schrieb:
Vielleicht hilft Dir das hier weiter:
http://www.c-plusplus.net/forum/248213?highlight=pipe
Das habe ich zwar bisher nur aus einem Konsolenprogramm getestet, sollte aber auch in einem Windowsprogramm funktionieren.Ah, na das klappt ja wunderbar. Vielen Dank!
-
logout schrieb:
Seltsam. Könntest du mir bitte sagen, woran das genau lag (oder klappt das wegen dem ganzen Code drum herum (insbesondere CreateWindow)?
Nein, ich weiß leider auch nichts Genaues. Ich habe noch nicht einmal eine Idee, was eigentlich scheitert und wo ich deshalb suchen muss. Weder ein "invalid handle" noch ein "stop responding" konnte ich bis jetzt provozieren. Ich hatte gehofft, von einem der hier aktiven MVP's einen Hinweis zu bekommen.
viele grüße
ralph
-
Nun muss ich leider doch was an den PHP CGI Prozess senden: die POST-Daten des Clients. Laut CGI-Spezifikation muss ich in die Umgebungsvariablen des Unterprozesses (PHP) "CONTENT_TYPE=" mit der Länge setzen - das funktioniert. Als nächstes muss ich die ganzen POST Daten an den Prozess durch die Pipe senden. Aber durch welche und wo?
Habe den Code von Belli eingesetzt und versuche in startCommandProcess() nach CreateProcess() die Daten reinzuschreiben (der Buffer ist nur ein Beispiel):
// Write post Byte outBuf[19] = "par1=val1&par2=val2"; DWORD nBytesWrite; if (!WriteFile(wrHandle, outBuf, sizeof(outBuf), &nBytesWrite, NULL) || !nBytesWrite) ShowMessage("Error");
Das scheint aber wohl falsch zu sein, da ich zum einen in der PHP-Datei über "print_r($_POST);" oder "var_dump(file_get_contents("php://input"));" keine Daten empfange und zum anderen kommen die geschrieben Daten später in Funktion readToVector() mit raus. Ist es der falsche Handle oder was mache ich falsch?
-
Never mind. Es läuft! :xmas1:
Vielen Dank nochmal allen die hier geantwortet haben. Habe wieder etwas Neues gelernt.