IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Apache Discussion :

CGI sous Windows XP : récupérer la sortie d'un .exe appelé depuis un CGI .bat


Sujet :

Apache

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 7
    Points : 4
    Points
    4
    Par défaut CGI sous Windows XP : récupérer la sortie d'un .exe appelé depuis un CGI .bat
    Bonjour,
    je suis sous win xp,avec apache 2.2, et je développe en local des services web.

    j'ai configuré apache pour avoir dans mon répertoire cgi-bin la possibilité d'executer des exe et des .bat.
    Je parviens à executer mon .exe, je parviens a executer mon .bat contenant que du 'echo'
    par contre si je lance un.bat qui lance lui même le .exe je n'arrive pas à récuérer le texte du .exe à l'intérieur du .bat.

    exemple:
    voici le cgi .EXE:
    http://localhost/cgi-bin/cgi1.exe?tata=tutu
    detected 1 variables
    tata = tutu
    ++++tata=tutu++++
    voici le cgi .BAT lancant le .EXE (dont j'ai pas la sortie)
    http://localhost/cgi-bin/prog3.bat?tata=tutu
    C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin>cgi1.exe 2>&1 C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin>cgi1.exe

    Le volume dans le lecteur C n'a pas de nom.
    Le numéro de série du volume est C451-245D

    Répertoire de C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin

    26/01/2010 00:01 .
    26/01/2010 00:01 ..
    30/12/2009 09:02 630 cgi.doc.lnk
    25/01/2010 23:17 54 784 cgi1.exe
    25/01/2010 23:17 54 784 cgi1.x
    24/01/2010 15:23 56 320 cgi_demo.x
    28/12/2009 21:32 625 default_cgi.bat
    24/01/2010 11:21 863 httpd.conf.lnk
    28/12/2009 15:38 878 prog1.bat
    24/01/2010 02:55 1 284 prog2.bat
    31/12/2009 13:48 1 200 prog2.bat.bak
    26/01/2010 00:09 709 prog3.bat
    24/01/2010 15:11 697 prog3.bat.bak
    11 fichier(s) 172 774 octets
    2 Rép(s) 3 729 924 096 octets libres
    avec le contenu du .bat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    @echo off
    rem .#################################
    rem HTTP HEADER : contains <variable_names>:<values>
    rem the most important one is "Content-type" variable
    rem #################################
     
    rem echo Content-type: text/html; charset=utf-8
    echo Content-type: text/html; charset="ISO-8859-1"
    echo Server: Apache/1.3.27 (Unix)
    echo.
     
    rem #################################
    rem HTTP Content
    rem This is the HTML code that client will display
    rem special HTML codes : '<' and'>' must be previxed by '^' on windows
    rem #################################
    @echo on
    cgi1.exe 2>&1
    cgi1.exe
    @echo off
    echo ^<br^>^<pre^>
    dir
    echo ^</pre^>
    rem returns 0 : it indicates success of script
    exit /b 0
    Dans le .bat je lance deux fois cgi1.exe avec la première fois une tentative de rediriger stderr. grace à la directive echo on, je vois bien que le chemin est correct.
    Le pire est qu'un commande de windows: "DIR" permet d'avoir la sortie !
    de plus j'ai fait un programme qui fait un MessageBeep(), et j'ai bien un bip quand le .bat lance le .Exe...

    comment parvenir à lancer le .exe via le .bat en ayant la sortie console ?

    Merci
    Thierry Brémard

  2. #2
    Rédacteur
    Avatar de _Mac_
    Profil pro
    Inscrit en
    Août 2005
    Messages
    9 601
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 9 601
    Points : 12 977
    Points
    12 977
    Par défaut
    Et si tu fais
    ?

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Salut,

    j'ai mis le call devant l'exe et j'ai:
    http://localhost/cgi-bin/prog3.bat?tata=toto
    donne:
    C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin>call cgi1.exe

    Le volume dans le lecteur C n'a pas de nom.
    Le numéro de série du volume est C451-245D

    Répertoire de C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin

    27/01/2010 00:09 .
    27/01/2010 00:09 ..
    30/12/2009 09:02 630 cgi.doc.lnk
    27/01/2010 00:01 54 784 cgi1.exe
    25/01/2010 23:17 54 784 cgi1.x
    24/01/2010 15:23 56 320 cgi_demo.x
    28/12/2009 21:32 625 default_cgi.bat
    ...
    Le programme est bien executé car j'ai mis un MessageBeep dans le main, mais aucune sortie.
    plus le temps passe plus je me dis que je ne vais pas appeler le .bat , mais directement mes exe...

    j'ai aussi essayé "cgi1.exe >&" comme quelqu'un m'a conseillé, ca marche pas.

  4. #4
    Rédacteur
    Avatar de _Mac_
    Profil pro
    Inscrit en
    Août 2005
    Messages
    9 601
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 9 601
    Points : 12 977
    Points
    12 977
    Par défaut
    Je parlais de mettre call cgi1.exe dans le .bat. Je n'ai pas bien compris si c'est ce que tu as fait.

    Pour 2>&1, c'est une syntaxe Unix, pas surprenant que ça ne marche pas sous Windows.

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    oui, la dernière saisie est ce que j'ai sur mon client http après avoir fait la requête sur l'url terminant par .bat ( un peu comme le deuxième écran du tout début du post)

    on m'a dit que ce problème est du au fait que quand on lance un .bat : apache spawn cmd.exe et récupère les handles qu'il faut, mais que lorsque le .bat (donc cmd.exe) lance des .exe, a priori il y aurait un truc du genre :

    "les stdout du .exe ne sont pas redirigées vers les stdin de cmd.exe et par conséquent n'apparaissent pas dans les stdout de cmd.exe donc n'apparaissent pas dans ce que recoit apache, donc ce n'est pas envoyé au client http": c'est l'idée que j'ai compris.

    alors qu'en executant directement l'exe on a directement le stdout du test_cgi.exe comme on veut, permettant la récupération effective par le client http du contenu du stdout.

    curieux curieux.
    surout que sous linux avec des .sh c'est possible d'avoir la sortie de binaires dans des cgi..
    C'est l'explication ?
    auquel cas on pourrait affirmer définitivement qu'un code classique C avec du printf ne peut définitivement pas être utilisé à partir d'un .bat dans un module cgi pour apache/winXP ?

    .. notons que la commande "DIR" marche quand même : elle fait probablement autre chose que du printf() simple. une autre commande comme netstat ne provoque en revanche pas non plus d'affichage pour le client http.

  6. #6
    Rédacteur
    Avatar de _Mac_
    Profil pro
    Inscrit en
    Août 2005
    Messages
    9 601
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 9 601
    Points : 12 977
    Points
    12 977
    Par défaut
    Citation Envoyé par phoneuss Voir le message
    .. notons que la commande "DIR" marche quand même : elle fait probablement autre chose que du printf() simple. une autre commande comme netstat ne provoque en revanche pas non plus d'affichage pour le client http.
    Intéressant : les commandes Windows n'ont pas toutes le même comportement. Windows ne gère clairement pas les entrées et sorties que sous Unix. Tu as regardé sur le site de Microsoft s'il y avait des astuces concernant les pipes, stdout et trucs du genre ?

    Truc idiot : ça donne quoi en installant et utilisant (comment ?) un truc du genre Cygwin et faire du .sh ?

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    je n'ai pas regardé sur le site de microsoft pour voir si il traitait de cela. oui surement il y a du pipe la dedans... clairement ca me gonfle

    cygwin, peut être, mais meme si ca marcherai c'est pas comme ca que je veux faire. pour moi j'attends une syntaxe spécifique à mettre dans le .bat pour etre capable de récupérer correctement le stdout des .exe fils.

  8. #8
    Rédacteur
    Avatar de _Mac_
    Profil pro
    Inscrit en
    Août 2005
    Messages
    9 601
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 9 601
    Points : 12 977
    Points
    12 977
    Par défaut
    Le .exe, c'est toi qui l'a écrit ? Regarde cette page, peut-être y a-t-il une technique particulière pour écrire sur le stdout.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    hum, je lirai cela de temps en temps,
    de toute évidence la réponse n'est pas une simple commande ou syntaxe à mettre dans le .bat

    oui c'est moi qui fait le .exe.

    je travaille actuellement en C pur Ansi pour faire des exe puissants et rapides pour du web.
    j'estime que le php n'est pas suffisamment un langage discipliné et le controle des ressources processeur n'a rien à voir quand on a le processeur au bout des doigts comme le C le permet.

    a+
    Thierry

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    bon,

    les .bat ont un problème sous apache : non seulement on n'a pas le stdout des exe fils, mais en plus un exe fils dont la sortie est redirigée vers un fichier ne marche pas:

    cgi1.exe >cgi.txt

    ==> le fichier créé est vide.

    ( je suis sous win pour faire du dev pour moi, .. dire que si je part en production un jour ca sera sous linux, et tout ces problèmes disparaitrons ! mais bon c'est garder la forme dans les bidouilles!

    j'appelle donc sous win mes .exe via cgi : et curieusement dans un premier instant j'ai eu la meme surprise que les .bat ! :
    les exe fils n'ont pas leur sortie redirigée sur le client web !
    par contre, là le parent , comme il est en C je lui fait faire ce que je veux :

    effectivement avec des créations de pipe et un CreateProcess et avec des startup info qui conviennent, je suis parvenu à récupérer la sortie d'un exe à partir d'un autre exe.
    voila c'est cool.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
     
    // Thierry Bremard
    // spawner code
    // to get child process output to http client under apache cgi modules
    // January 2010
    #include <custom/all.h>
     
    #define bzero(a) memset(a,0,sizeof(a)) //easier -- shortcut
     
    BOOL IsWinNT(void);
    void ErrorMessage(char *str);
     
    BOOL IsWinNT(void)  //check if we're running NT
    {
      OSVERSIONINFO osv;
      osv.dwOSVersionInfoSize = sizeof(osv);
      GetVersionEx(&osv);
      return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
    }
     
    void ErrorMessage(char *str)  //display detailed error info
    {
      LPVOID msg;
      FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &msg,
        0, NULL );
      printf("%s: %s\n",str,msg);
      LocalFree(msg);
    }
     
     
    void ReadProcessStdout(HANDLE read_stdout)
    {
        char buffer[1024];
        unsigned long bread;   //bytes read
        unsigned long avail; 
     
        bzero(buffer);    
     
        PeekNamedPipe(read_stdout,buffer,1023,&bread,&avail,NULL);
        //check to see if there is any data to read from stdout
        if (bread != 0)
        {
     
            if(!ReadFile(read_stdout,buffer,4,&bread,NULL))  //read the stdout pipe
            {
                puts("Error reading the stdout pipe in the thread");
            }
     
            // prints on stdout the output of process
            fwrite(buffer,bread,1, stdout);
     
        }
        return 0;
    }
     
    int SpawnProcess(void)
    {
      char buf[1024];           //i/o buffer
      int len;
      char *app_spawned;
      STARTUPINFO si;
      SECURITY_ATTRIBUTES sa;
      SECURITY_DESCRIPTOR sd;               //security information for pipes
      PROCESS_INFORMATION pi;
      HANDLE newstdin,newstdout,write_stdin;  //pipe handles
      unsigned long exit=0;  //process exit code
      unsigned long bread;   //bytes read
      unsigned long avail;   //bytes available
      BOOL read;
      HANDLE read_stdout;
      BOOL PROCESS_ON, bValue ;
      LPTSTR  lpCommandLine ;
     
        if (IsWinNT())        //initialize security descriptor (Windows NT)
        {
            InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
            SetSecurityDescriptorDacl(&sd, true, NULL, false);
            sa.lpSecurityDescriptor = &sd;
        }
        else
        {
            sa.lpSecurityDescriptor = NULL;
        }
     
        sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        sa.bInheritHandle = true;         //allow inheritable handles
     
      if (!CreatePipe(&newstdin,&write_stdin,&sa,0))   //create stdin pipe
      {
        ErrorMessage("CreatePipe");
        return 0;
      }
      if (!CreatePipe(&read_stdout,&newstdout,&sa,0))  //create stdout pipe
      {
        ErrorMessage("CreatePipe");
        CloseHandle(newstdin);
        CloseHandle(write_stdin);
        return 0;
      }
     
      GetStartupInfo(&si);      //set startupinfo for the spawned process
      /*
      The dwFlags member tells CreateProcess how to make the process.
      STARTF_USESTDHANDLES validates the hStd* members. STARTF_USESHOWWINDOW
      validates the wShowWindow member.
      */
      si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
      si.wShowWindow = SW_HIDE;
      si.hStdOutput = newstdout;
      si.hStdError = newstdout;     //set the new handles for the child process
      si.hStdInput = newstdin;
     
     
      //spawn the child process
        app_spawned="D:\\Prog\\google\\searcher_6\\searcher_5\\searcher.exe";
        lpCommandLine = NULL;/*"searcher.exe download&mp3"*/;
        lpCommandLine = "searcher.exe \"president&sarkozy\"";
     
        bValue = CreateProcess(app_spawned, lpCommandLine ,
            NULL,
            NULL,
            TRUE,
            0,      // No creation flags CREATE_NEW_CONSOLE,
            NULL,   // Use parent's environment block
            NULL,   // Use parent's starting directory 
            &si,    // Pointer to STARTUPINFO structure
            &pi);   // Pointer to PROCESS_INFORMATION structure
     
        if (! bValue)
        {
            ErrorMessage("CreateProcess");
            CloseHandle(newstdin);
            CloseHandle(newstdout);
            CloseHandle(read_stdout);
            CloseHandle(write_stdin);
            return 0;
        }
     
        PROCESS_ON=1;
     
        while(PROCESS_ON)
        {
            GetExitCodeProcess(pi.hProcess,&exit);      //while the process is running
            if (exit != STILL_ACTIVE)
            {
                PROCESS_ON=0;
            }
            ReadProcessStdout(read_stdout);
     
        }
     
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        CloseHandle(newstdin);            //clean stuff up
        CloseHandle(newstdout);
        CloseHandle(read_stdout);
        CloseHandle(write_stdin);
        return 1;
    }
     
    /*
    int main()
    {
        SpawnProcess();
        return 0;
    }
    */

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 05/11/2014, 22h38
  2. Réponses: 17
    Dernier message: 28/03/2007, 11h50
  3. Réponses: 1
    Dernier message: 12/01/2007, 10h19
  4. redirection entrée/sortie sous windows en C
    Par alexlecool dans le forum C
    Réponses: 3
    Dernier message: 08/12/2006, 09h05
  5. Réponses: 10
    Dernier message: 09/03/2006, 13h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo