7
votes

Comment appeler popen () avec un chemin de chemin contenant des espaces sous Windows en C / C ++?

J'essaie d'appeler popen () à l'aide de Mingw comme ceci: xxx

mais je ne peux pas le faire fonctionner. Je pense que c'est un cauchemar Citant ...


1 commentaires

Vous avez demandé à cela autour du temps que j'ai fait les premières rejets publics d'un langage de programmation que j'ai commencé à travailler, il y a presque six ans! J'ai rencontré et j'ai résolu cette question dans le port Windows d'une fonction de bibliothèque de cette langue, qui est maintenant dans sa 105ème version publique. Fondamentalement, j'augmente l'ouverture d'un processus avec une liste d'arguments, mais à l'aide de la fonction popen dans Mingw (qui correspond à la bibliothèque d'exécution Microsoft C _popen ) qui signifie que je dois coder soigneusement le nom du processus et les cordes d'argumentation. Donc, il y a votre réponse.


5 Réponses :


-1
votes

Selon la page d'homme de Popen:

L'argument de commande est un pointeur à un String null terminé contenant un ligne de commande shell. Cette commande est passé à / bin / sh à l'aide du drapeau -c; interprétation, le cas échéant, est effectué par la coquille.

Alors ce que vous voulez, c'est d'échapper à la chaîne pour sh pour analyser. Vous n'avez pas besoin d'échapper à l'argument , et vous pouvez essayer d'échapper aux espaces au lieu de cibler le nom du programme complet. Je n'ai pas de système Windows ici pour tester avec mais je vous suggérerais xxx


1 commentaires

Gardez à l'esprit que c'est Mingw, cependant, donc je ne sais pas que popen transmet la commande à / bin / sh. Pourrait-il y passer à un autre plus de shell de Windows-Y et moins de Posix-y à la place? Celui qui interprétera ces titulaires du dos en tant que séparateurs de chemins plutôt que de s'échapper et qui auront ses propres règles de citation.



4
votes

Jetez un coup d'œil à Quelle est l'équivalent à Posix Popen dans l'API Win32 . J'ai abandonné ma tentative d'utiliser _popen () sous Windows il y a longtemps. La solution pure Win32 fonctionne beaucoup plus de manière fiable.

Si MINGW transmettez vos paramètres sur SH -C au lieu de cmd.exe / c , alors vous voulez probablement changer ces backslashes pour transférer des barres obliques. Quelque chose comme ce qui suit devrait faire l'affaire. xxx


1 commentaires

Un programme compilé par MINGW n'a pas de _popen qui transmet des paramètres à sh -c ; Il est lié à une bibliothèque Windows interne appelée msvcrt.dll dont _popen ne fait certainement aucune chose. La bibliothèque de MSYS de Mingw (utilisée par la boîte à outils elle-même) a probablement un popen qui appelle sh . La DLL Cygwin le fait et MSYS est un dérivé de cygwin. Lorsque vous construisez des programmes avec Mingw, ils ne sont pas liés avec des MSYS.



5
votes

Ce problème s'avère être résoluble. (Bien que, comme avec la plupart des choses sous Windows, pas 100%).

La fonction code> popen code> ouvre une commande système, ce qui signifie qu'il s'agit presque certainement de prendre l'argument de la chaîne et de l'interpoler dans cmd.exe / c code>. p>

après une certaine expérimentation interactive avec cmd.exe / c code> à l'invite de commande Windows, nous avons frappé une manière Pour exécuter un programme qui a des espaces dans son chemin de chemin. p>

tentative naïf avec des citations, Nope: p> xxx pré>

pouvez-nous échapper aux devis avec le circonflexe? xxx pré>

Qu'en est-il de l'espace? p>

#include <stdio.h>

int main()
{
    FILE *in = _popen("C:\\Program\" \"Files\\Internet\" \"Explorer\\iexplore.exe", "r");

    if (in) {
        char line[200];
        printf("successfully opened!\n");
        if (fgets(line, 200, in))
            fputs(line, stdout);
        _pclose(in);
    }

    return 0;
}


0 commentaires

1
votes

J'étais juste face à ce problème et j'ai essayé la solution de Kaz sans succès. La façon dont j'ai résolu était simplement de changer de répertoire, exécuter _popen sans le chemin d'accès à l'exécutable, puis remplacez-le sur le répertoire d'origine.

char cwd[MAX_PATH];
_getcwd(cwd, MAX_PATH);

if (_chdir("C:\\Program Files\\CA\\BrightStor ARCserve Backup") >= 0)
{
    outputPointer = _popen("ca_qmgr.exe \"-list\"", "r");
    _chdir(cwd);
}


0 commentaires

11
votes

Il allume la fonction popen bandes les guillemets autour du tout, par exemple. "C: / Program Files" devient C: / Program Files et "AB CD.EXE" "EF GH" devient AB CD "" EF GH . Vous pouvez contourner cela en ajoutant simplement des guillemets autour du tout, par exemple. "" AB CD.EXE "" EF GH "" qui devient "AB CD.exe" "EF GH" comme prévu.

Cette solution a été inspirée par la réponse de Kaz


1 commentaires

Sa semble stupide que cela fonctionnerait ... mais quand j'ai essayé tout mon citant a soudainement commencé à travailler ...