Was ist das Äquivalent zu Posix popen() in der Win32-API?

Lesezeit: 4 Minuten

Benutzeravatar von dsimcha
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 - Benutzerbild der litb
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?

    – Gregor Leban

    21. April 2015 um 12:21 Uhr

Du kannst anrufen _popen wenn Sie eine Konsolenanwendung schreiben. Weitere Informationen finden Sie in der Dokumentation auf der MSDN-Site: http://msdn.microsoft.com/en-us/library/96ayss4b(VS.80).aspx

  • 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.

Benutzeravatar von ryyker
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); 

Einfaches Anwendungsbeispiel:

#include "cmd_rsp.h"
int main(void)
{
    char *buf = {0};
    buf = calloc(100, 1);
    if(!buf)return 0;
    cmd_rsp("dir /s", &buf, 100);
    printf("%s", buf);
    free(buf);
    //or a custom exe
    char *buf2 = {0};
    buf2 = calloc(100, 1);
    cmd_rsp("some_custom_program.exe arg_1 arg_2 arg_n", &buf2, 100);
    printf("%s", buf2);
    free(buf2);
    
    return 0;
}

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.

1387150cookie-checkWas ist das Äquivalent zu Posix popen() in der Win32-API?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy