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

C++Builder Discussion :

R�cup�rer le retour d'une commande MS-DOS dans une variable sous C++ Builder XE2 [Langage/Algorithme]


Sujet :

C++Builder

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2007
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2007
    Messages : 164
    Par d�faut R�cup�rer le retour d'une commande MS-DOS dans une variable sous C++ Builder XE2
    Bonjour,

    J'aimerais ex�cuter et r�cup�rer le retour d'une commande MS-DOS sous C++ Builder XE2. Je n'ai pas trouv� beaucoup d'informations concernant ce sujet sur le forum, c'est pourquoi je poste ce message.

    J'ai le code suivant :

    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
    wchar_t* __fastcall TForm5::RunDOScmd(wchar_t* CommandLine)
    {
        STARTUPINFO siStartupInfo;
        PROCESS_INFORMATION piProcessInfo;
        unsigned long dwExitCode;
     
        HANDLE PipeInputRead;
        HANDLE PipeInputWrite;
        HANDLE PipeOutputRead;
        HANDLE PipeOutputWrite;
     
        SECURITY_ATTRIBUTES securityattribs =
        {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
     
        ZeroMemory(&siStartupInfo, sizeof(siStartupInfo));
        // initialisation de la taille
        siStartupInfo.cb = sizeof(siStartupInfo);
     
        // Create pipe for standard output redirection
        CreatePipe(&PipeOutputRead, &PipeOutputWrite, &securityattribs, 0);
        // Create pipe for standard input redirection.
        CreatePipe(&PipeInputRead, &PipeInputWrite, &securityattribs, 0);
     
        siStartupInfo.dwFlags = STARTF_USESTDHANDLES;
        siStartupInfo.hStdInput = PipeInputRead;
        siStartupInfo.hStdOutput = PipeOutputWrite;
        siStartupInfo.hStdError = PipeOutputWrite;
     
        bool pSuccess = CreateProcess(NULL, CommandLine, NULL, NULL, true, 0, NULL, NULL, &siStartupInfo, &piProcessInfo);
     
        if (pSuccess)
        {
            CloseHandle(piProcessInfo.hThread); // fermer le handle de thread dès qu'il devient inutile
            WaitForSingleObject(piProcessInfo.hProcess, INFINITE);
            GetExitCodeProcess(piProcessInfo.hProcess, &dwExitCode);
            if (dwExitCode != STILL_ACTIVE)
                CloseHandle(piProcessInfo.hProcess); // fermer le handle de process
        }
        else
        {
            CloseHandle(PipeOutputWrite);
            CloseHandle(PipeInputRead);
            return (L"perdu");
        }
     
        CloseHandle(PipeOutputWrite);
        CloseHandle(PipeInputRead);
        CloseHandle(PipeInputWrite);
     
        // Read output from the child process.
        DWORD dwRead;
        CHAR chBuf[4096];
        String procstdout = "", procstderr = "";
     
        while (ReadFile(PipeOutputRead, chBuf, 4095, &dwRead, NULL) && (dwRead != 0))
        {
            chBuf[dwRead] = '\0';
            procstdout += chBuf;
            Edit2->Text = chBuf;
        }
     
        while (ReadFile(PipeOutputRead, chBuf, 4095, &dwRead, NULL) && (dwRead != 0))
        {
            chBuf[dwRead] = '\0';
            procstderr += chBuf;
        }
        CloseHandle(PipeOutputRead);
    }
    Par contre, la commande "CreateProcess(NULL, CommandLine, NULL, NULL, true, 0, NULL, NULL, &siStartupInfo, &piProcessInfo);" me renvoie toujours faux ...

    Merci beaucoup pour votre aide si vous avez des id�es,

  2. #2
    R�dacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par d�faut
    Salut Mercusyo
    Un lien sur l'execution d'une commande MSDOS
    Ce n'est pas tout a fait ce que tu cherche mais cela peut etre une piste

  3. #3
    Membre exp�riment�
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2012
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 164
    Par d�faut
    Salut,

    Ma petite exp�rience avec ce genre de fonctions.

    Pour ex�cuter une commande de type DOS, j'ai utilis� pendant des ann�es la fonction "WinExec". Puis je suis tomb� l�-dessus (dans MSDN):

    Note This function (WinExec)is provided only for compatibility with 16-bit Windows. Applications should use the CreateProcess function.

    Alors j'ai suivi leur conseil et j'ai fini par trouver comme faire (ciel que je d�teste quand c'est compliqu�)

    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
     
    oid TGenTools::ExecuteProcess(AnsiString applicationName,
                                   AnsiString commandLine,
                                   AnsiString startDir,
                                   bool showWindow, bool modalWindow)
     // http://www.tek-tips.com/faqs.cfm?fid=1954
     // ApplicationName: Nom de l'Application. Peut être vide, alors la commandLine
     //                  doit contenir le nom de l'application
     // commandLine: ligne de commande
     
     {
      int res ;
      char* cmd ;
      char* dir ;
      STARTUPINFO StartInfo; // name structure
      PROCESS_INFORMATION ProcInfo; // name structure
     
     
      if (!applicationName.IsEmpty())
        commandLine = applicationName + " " + commandLine ;
      cmd = StgToCharPtr(commandLine) ;  // NULL si vide
      dir = StgToCharPtr(startDir) ;
      memset(&ProcInfo, 0, sizeof(ProcInfo)); // Set up memory block
      memset(&StartInfo, 0 , sizeof(StartInfo)); // Set up memory block
      StartInfo.cb = sizeof(StartInfo); // Set structure size
      StartInfo.dwFlags = STARTF_USESHOWWINDOW ;  // Necessary for wShowWindow to work
      if (showWindow)
         StartInfo.wShowWindow = SW_SHOW; // Hide window
      else
         StartInfo.wShowWindow = SW_HIDE; // Hide window
     
      res = CreateProcess(NULL, cmd, NULL, NULL, NULL, NULL, NULL,
                          dir,
                          &StartInfo, &ProcInfo);
      if (res && modalWindow)
       WaitForSingleObject(ProcInfo.hThread, INFINITE); // wait forever for process to finish
    }
    �a fonctionnait jusqu'� je tombe en Window 7. Puis, je suis tomb� sur la fonction ShellExecute qui fonctionne � merveille, au del� de mes esp�rances m�me. Peut-�tre qu'elle ferait l'affaire dans ton cas***.

    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    Tiens j'en profite pour vous refiler un petit truc juste au cas o�...

    Dans votre boite de dialogue "� propos..." , vous avec un label (lbLink) qui contient le lien de votre site. Voici le code qui va lancer le browser par d�faut avec le lien pass� en param�tre:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    #include <windows.h>
    void __fastcall TfrmAbout::lbLinkClick(TObject *Sender)
    {
    ShellExecute(NULL, L"open",lbLink->Caption.c_str(),NULL, NULL, SW_SHOWNORMAL);
    }
    *** J'en doute, apr�s avoir bien relu ton post

  4. #4
    Expert �minent
    Avatar de ShaiLeTroll
    Homme Profil pro
    D�veloppeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 44
    Localisation : France, Seine Saint Denis (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur C++\Delphi
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par d�faut
    Si tu utilises PipeOutputWrite comme Pipe pour hStdOutput et hStdError, tu ne pourras pas faire la diff�rence entre les deux et seul la 1ere boucle de ReadFile fonctionnera

    regarde la MSDN How to spawn console processes with redirected standard handles \ Comment appeler un processus console avec une redirection des canaux standards.


    J'ai fait ceci en Delphi, tout doit se jouer sur les diff�rents NULL que tu passe, j'ai utilis� ce code pour lancer PHP.exe et d'autres programmes consoles comme ceux de DCMTK

    tu as pr�par� un siStartupInfo mais tu ne l'utilises pas ?
    le chemin est-il exacte ?

    Tu es bien en mappage wchar_t, as-tu test� CreateProcessW
    un projet BCB6 ou 2007 migr� en 2009 � XE2 reste Ansi !

    piProcessInfo, moi, je lui ai fait un ZeroMemory, mais comme c'est out �a devrait pas poser probl�me

    on a eu un sujet proche r�cemment Cr�er un GUI pour une application console compil�e
    Aide via F1 - FAQ - Guide du d�veloppeur Delphi devant un probl�me - Pensez-y !
    Attention Troll M�chant !
    "Quand un homme a faim, mieux vaut lui apprendre � p�cher que de lui donner un poisson" Confucius
    Mieux vaut se taire et para�tre idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la m�diocrit� !

    L'exp�rience, c'est le nom que chacun donne � ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2007
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2007
    Messages : 164
    Par d�faut
    Merci beaucoup pour vos r�ponses ,

    J'ai avanc� de mon c�t� �galement, mon code ci-dessous fonctionne correctement :

    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
    char* __fastcall TForm5::RunDOScmd(wchar_t* CommandLine)
    {
    	STARTUPINFO siStartupInfo;
    	PROCESS_INFORMATION piProcessInfo;
    	unsigned long dwExitCode;
     
    	HANDLE PipeInputRead;
    	HANDLE PipeInputWrite;
    	HANDLE PipeOutputRead;
    	HANDLE PipeOutputWrite;
     
    	SECURITY_ATTRIBUTES securityattribs = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
     
    	ZeroMemory(&siStartupInfo, sizeof(siStartupInfo));
    	// initialisation de la taille
    	siStartupInfo.cb = sizeof(siStartupInfo);
     
    	// Create pipe for standard output redirection
    	CreatePipe(&PipeOutputRead, &PipeOutputWrite, &securityattribs, 0);
    	// Create pipe for standard input redirection.
    	CreatePipe(&PipeInputRead, &PipeInputWrite, &securityattribs, 0);
     
    	siStartupInfo.dwFlags = STARTF_USESTDHANDLES;
    	siStartupInfo.wShowWindow = SW_HIDE;
    	siStartupInfo.hStdInput = PipeInputRead;
    	siStartupInfo.hStdOutput = PipeOutputWrite;
     
    	bool pSuccess = CreateProcess(NULL, CommandLine, NULL, NULL, true, 0, NULL, NULL, &siStartupInfo, &piProcessInfo);
     
    	if (pSuccess)
    	{
    		CloseHandle(piProcessInfo.hThread); // fermer le handle de thread dès qu'il devient inutile
    		WaitForSingleObject(piProcessInfo.hProcess, INFINITE);
    		GetExitCodeProcess(piProcessInfo.hProcess, &dwExitCode);
    		if (dwExitCode != STILL_ACTIVE)
    			CloseHandle(piProcessInfo.hProcess); // fermer le handle de process
    	}
    	else
    	{
    		CloseHandle(PipeOutputWrite);
    		CloseHandle(PipeInputRead);
    		return "";
    	}
     
    	CloseHandle(PipeOutputWrite);
    	CloseHandle(PipeInputRead);
    	CloseHandle(PipeInputWrite);
     
    	// Read output from the child process.
    	DWORD dwRead;
    	CHAR chBuf[SIZEBUF];
     
    	bool isReadFile = ReadFile(PipeOutputRead, chBuf, SIZEBUF-1, &dwRead, NULL);
     
    	CloseHandle(PipeOutputRead);
    	return chBuf;
    }
    Seul petit b�mol, j'ai toujours une fen�tre MS-DOS qui appara�t, m�me avec la commande
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    siStartupInfo.wShowWindow = SW_HIDE;
    Pour info, c'est pour appeler une commande de DCMTK (dcmftest.exe)

    J'ai �galement essay� avec le premier param�tre "lpApplicationName" de la m�thode "CreateProcess", mais l�, plus rien ne fonctionne ... j'envoie pour
    "lpApplicationName = dcmftest" et pour "lpCommandLine = D:\\1.dcm"

    Comment faire pour rendre invisible cette fen�tre en esp�rant que ce soit possible ...

    Merci,

  6. #6
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2007
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2007
    Messages : 164
    Par d�faut
    Je viens de trouver la r�ponse seul en regardant MSDN, voici donc le code en mappage wchar_t :


    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
    char* __fastcall TForm5::RunDOScmd(wchar_t* CommandLine)
    {
    	STARTUPINFO siStartupInfo;
    	PROCESS_INFORMATION piProcessInfo;
    	unsigned long dwExitCode;
     
    	HANDLE PipeInputRead;
    	HANDLE PipeInputWrite;
    	HANDLE PipeOutputRead;
    	HANDLE PipeOutputWrite;
     
    	SECURITY_ATTRIBUTES securityattribs = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
     
    	ZeroMemory(&siStartupInfo, sizeof(siStartupInfo));
    	// initialisation de la taille
    	siStartupInfo.cb = sizeof(siStartupInfo);
     
    	// Create pipe for standard output redirection
    	CreatePipe(&PipeOutputRead, &PipeOutputWrite, &securityattribs, 0);
    	// Create pipe for standard input redirection.
    	CreatePipe(&PipeInputRead, &PipeInputWrite, &securityattribs, 0);
     
    	siStartupInfo.dwFlags = STARTF_USESTDHANDLES;
    	siStartupInfo.hStdInput = PipeInputRead;
    	siStartupInfo.hStdOutput = PipeOutputWrite;
     
    	bool pSuccess = CreateProcess(NULL, CommandLine, NULL, NULL, true, CREATE_NO_WINDOW, NULL, NULL, &siStartupInfo, &piProcessInfo);
     
    	if (pSuccess)
    	{
    		CloseHandle(piProcessInfo.hThread); // fermer le handle de thread dès qu'il devient inutile
    		WaitForSingleObject(piProcessInfo.hProcess, INFINITE);
    		GetExitCodeProcess(piProcessInfo.hProcess, &dwExitCode);
    		if (dwExitCode != STILL_ACTIVE)
    			CloseHandle(piProcessInfo.hProcess); // fermer le handle de process
    	}
    	else
    	{
    		CloseHandle(PipeOutputWrite);
    		CloseHandle(PipeInputRead);
    		return "";
    	}
     
    	CloseHandle(PipeOutputWrite);
    	CloseHandle(PipeInputRead);
    	CloseHandle(PipeInputWrite);
     
    	// Read output from the child process.
    	DWORD dwRead;
    	CHAR chBuf[SIZEBUF];
     
    	bool isReadFile = ReadFile(PipeOutputRead, chBuf, SIZEBUF-1, &dwRead, NULL);
     
    	CloseHandle(PipeOutputRead);
    	return chBuf;
    }
    J'ai modifi� la ligne :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
     bool pSuccess = CreateProcess(NULL, CommandLine, NULL, NULL, true, CREATE_NO_WINDOW, NULL, NULL, &siStartupInfo, &piProcessInfo);
    au lieu de mettre 0 � "dwCreationFlags" j'ai pr�cis� "CREATE_NO_WINDOW" et en supprimant l'instruction
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    siStartupInfo.wShowWindow = SW_HIDE;
    Voilou, si cela peut aider et merci !

  7. #7
    Expert �minent
    Avatar de ShaiLeTroll
    Homme Profil pro
    D�veloppeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 44
    Localisation : France, Seine Saint Denis (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur C++\Delphi
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par d�faut
    En fait pour que wShowWindow soit pris en compte, il faut mettre STARTF_USESHOWWINDOW

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // Active wShowWindow et hStdOutput/hStdError
    StartupInfo.wShowWindow := SW_HIDE;
    Aide via F1 - FAQ - Guide du d�veloppeur Delphi devant un probl�me - Pensez-y !
    Attention Troll M�chant !
    "Quand un homme a faim, mieux vaut lui apprendre � p�cher que de lui donner un poisson" Confucius
    Mieux vaut se taire et para�tre idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la m�diocrit� !

    L'exp�rience, c'est le nom que chacun donne � ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [D�butant] Variable dans une commande MS-DOS en vb.net
    Par Barbe-Bleu dans le forum VB.NET
    R�ponses: 2
    Dernier message: 18/11/2012, 15h17
  2. [XL-2010] Int�grer une commande SQL (complexe) dans une macro
    Par urbandot dans le forum Macros et VBA Excel
    R�ponses: 0
    Dernier message: 14/11/2011, 10h50
  3. R�ponses: 8
    Dernier message: 25/09/2008, 20h22
  4. executer une commande cl� contenue dans une cellule
    Par herji dans le forum Macros et VBA Excel
    R�ponses: 5
    Dernier message: 08/09/2008, 17h12
  5. [MySQL] executer une commande php contenu dans une variable
    Par Stopher dans le forum PHP & Base de donn�es
    R�ponses: 4
    Dernier message: 23/11/2006, 15h44

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