Was ist das Äquivalent zu Posix popen() in der Win32-API?
Lesezeit: 4 Minuten
dsimcha
Gibt es ein ungefähres Äquivalent zur Linux/Unix-Funktion stdio.h popen() in der Win32-API? Wenn ja, wo finde ich es?
Bearbeiten: Ich muss dies wissen, um eine Auslassung in der D-Standardbibliothek zu beheben. Jede Antwort muss verwenden nur Standard-Win32-API, keine MSVC-spezifischen Funktionen. Außerdem würde ich etwas bevorzugen, das nicht schrecklich niedrig ist, falls es existiert.
_popen ist Teil der Standard-C-Bibliothek unter Windows und steht jedem zur Verfügung, der mit der Standard-C-Bibliothek verknüpft/verwendet.
– Jason Coco
16. Januar 2009 um 17:10 Uhr
Ok, nun, ich konnte es anscheinend nicht von D aus zum Laufen bringen, das C ABI unterstützt, aber das würde wahrscheinlich den Rahmen dieser Frage sprengen.
– dsimcha
16. Januar 2009 um 17:11 Uhr
Windows ist nicht Linux; Es gibt keine Standard-C-Bibliothek im Betriebssystem. KERNEL32.DLL hat kein printf()
– MSalter
23. Januar 2009 um 13:08 Uhr
Johannes Schaub – litb
MSDN erklärt, wie Sie das tun, was popen mit der Windows-API in tut Pipe-Handle-Vererbung . Hier es bietet ein gut dokumentiertes Beispiel. Es ist viel niedriger als das _popen Funktion, die in der von Jason verlinkten Laufzeitbibliothek zu finden ist, verwendet jedoch ausschließlich die Win32-API.
Oh, diese Antwort gefällt mir viel besser als meine 🙂
– Jason Coco
16. Januar 2009 um 16:22 Uhr
Es sieht sehr interessant aus, und wenn ich nicht 2 Tage zu spät mit meiner Lieferfrist gewesen wäre, wäre ich vielleicht daran interessiert, diese Lösung zu implementieren 🙂 . Aber für meine Bedürfnisse (ich möchte nur stdout erfassen), _popen ist mehr als genug.
– Guss
1. Oktober 2013 um 15:17 Uhr
Haben Sie vergessen, einen Link zur MSDN-Seite zu posten? Wo ist dieses gut dokumentierte Beispiel?
Ich mag deine auch, Kumpel. passt genau zu dem, was der Typ will, denke ich 🙂
– Johannes Schaub – litb
16. Januar 2009 um 16:24 Uhr
Beachten Sie, dass dies keine Leerzeichen im Pfad behandelt 🙁
– Phönix87
28. August 2021 um 16:18 Uhr
Leider ist es nicht besonders einfach.
Sie müssen eine Pipe mit der win32-Funktion (CreatePipe) erstellen, dann müssen Sie normalerweise das Ende der Pipe (DuplicateHandle) duplizieren, das Sie dem Unterprozess übergeben, damit es vererbt werden kann, andernfalls wird es nicht sein und kann daher nicht verwendet werden.
Dann müssen Sie einen Prozess mit CreateProcess erstellen (der viele Strukturzeiger benötigt, einschließlich einer STARTUPINFO) und in STARTUPINFO das Handle übergeben, das Sie als Standardausgabe dupliziert haben.
Dann können Sie vom Leseende der Pipe lesen (ReadFile usw.), bis Sie eof erreichen, dann müssen Sie aufräumen, indem Sie alle verschiedenen Win32-Handles schließen.
Grab mal einen alten Thread aus…
Als Reaktion auf Jason Cocos obige Antwort und im Gegensatz zu dem, was die verlinkte MSDN-Seite behauptet, ist es heutzutage anscheinend möglich, _popen() von Nicht-Konsolen-Apps aufzurufen. Ich rufe es von einer QuickTime-Importer-Komponente aus auf, im Grunde eine getarnte DLL. Es öffnet ein Konsolenfenster, zeigt aber ansonsten das erwartete Verhalten. Beim Kompilieren eines Standard-Konsolentools mit der Option -mwindows von mingw32, um es zu einer GUI-App zu machen, funktioniert _popen weiterhin ordnungsgemäß (aber ein Konsolenfenster wird geöffnet, selbst wenn das Tool von einer anderen Konsole aus ausgeführt wird.
ryyker
Dies ist ein alter Beitrag, aber ich hatte auch vor einigen Jahren Bedarf, einen zu verwenden Popen() wie Anruf in einer Windows-Umgebung. Wie mehrere Kommentare in der Antwort hier festgestellt haben, verwenden Sie die Windows-API, um alles zu implementieren, was dem klassischen POSIX nahe kommt popen() ist interessant.
Ich habe eine Implementierung erstellt, die ich eingereicht habe Code-Review . Diese Implementierung verwendet pipes zu stdin und von stdoutsowie Windows-Methoden für CreateProcess(...).
Der verknüpfte Code ist so konzipiert, dass er in eine DLL mit einer sehr kleinen API eingebaut werden kann.
int __declspec(dllexport) cmd_rsp(const char *command, char **chunk, unsigned int size);
Es nimmt irgendeinen Befehl entgegen, der zum Beispiel ausgegeben werden kann stdin, erstellt einen separaten Prozess zum Ausführen des Befehls und gibt dann den gesamten Antwortinhalt (sofern vorhanden) an einen Puffer zurück, ohne das Popup-Fenster des CMD-Fensters anzuzeigen. Der Puffer wächst nach Bedarf, um die Größe der Antwort aufzunehmen.
13871500cookie-checkWas ist das Äquivalent zu Posix popen() in der Win32-API?yes
_popen ist Teil der Standard-C-Bibliothek unter Windows und steht jedem zur Verfügung, der mit der Standard-C-Bibliothek verknüpft/verwendet.
– Jason Coco
16. Januar 2009 um 17:10 Uhr
Ok, nun, ich konnte es anscheinend nicht von D aus zum Laufen bringen, das C ABI unterstützt, aber das würde wahrscheinlich den Rahmen dieser Frage sprengen.
– dsimcha
16. Januar 2009 um 17:11 Uhr
Windows ist nicht Linux; Es gibt keine Standard-C-Bibliothek im Betriebssystem. KERNEL32.DLL hat kein printf()
– MSalter
23. Januar 2009 um 13:08 Uhr