Pour des besoins spécifiques, je fais une IHM en C++ Builder 6 pour utiliser NeroCmd.exe, exécutable fournit avec Nero qui permet de graver des CD en ligne de commande.

J'utilise NeroCmd pour récupérer les caractéristiques du graveur, du CD... Il faut donc que je récupère la sortie console pour la parser et récupérer ce qui m'intéresse.

J'avais d'abord fait un "system(commande_nero);", commande_nero s'occupant également de rediriger la sortie vers un fichier temp ("nerocmd arg > fichier.tmp") que je parsais avant de l'effacer. Ca marche mais :
- c'est pas propre
- ça utilise un fichier temp
- ça affiche une fenêtre DOS pendant 0,2s

J'ai essayé ShellExecute qui permet de masquer la fenêtre (SW_HIDE) mais impossible de récupérer le résultat, du moins dans mes essais.

Et puis je suis tombé sur un code utilisant CreateProcess, qui récupère la sortie standard directement dans un handle. Ca fonctionne, mais j'ai toujours la fenêtre qui s'affiche. Ca utilise un STARTUPINFO, mais si je le paramètre pour cacher la fenêtre (dwFlags=STARTF_USESHOWWINDOW et wShowWindow=SW_HIDE) ça ne me récupère plus la sortie standard.

Ma question est : y'a t-il moyen de combiner les 2, masquer la fenêtre DOS et récupérer la sortie console, si possible sans passer par une redirection et un fichier temporaire ?

Merci !

Pour info, le résultat retourné par NeroCmd peut avoir la tête là :
Drv: Adapter Underrun Protection Technology # type ID
-------------------------------------------------------------------------------
d TSSTcorp CD-ROM TS-H192C <none> 0 atapi 0
e _NEC DVD+-RW ND-3530A JustLink 0 atapi 1
f YO9204R SOU432M <none> 2 dtscsi 0
? Image Recorder <none> -1 Virtual 0

Ok.
Ci-dessous le code que j'ai récupéré et un peu modifié. Le résultat de la commande lancée est sensé se trouver dans strRes.

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
 
void TParseFile::ExecuteCommand(AnsiString strCmd)
{
  const int BUFSIZE = 256;
  AnsiString strRes, procstdout = "", procstderr = "";
  char *CommandLine;
  unsigned long dwExitCode;
  CHAR chBuf[BUFSIZE];
  DWORD dwRead;
  STARTUPINFO siStartupInfo;
  PROCESS_INFORMATION piProcessInfo;
  HANDLE PipeInputRead, PipeInputWrite, PipeOutputRead, PipeOutputWrite;
 
  SECURITY_ATTRIBUTES securityattribs = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
  ZeroMemory(&siStartupInfo, sizeof(siStartupInfo));
 
  CreatePipe(&PipeOutputRead, &PipeOutputWrite, &securityattribs, 0);
  CreatePipe(&PipeInputRead, &PipeInputWrite, &securityattribs, 0);
 
  siStartupInfo.cb = sizeof(siStartupInfo);
 
  // Redirection vers un fichier temp désactivée
  //strCmd = strCmd + " > " + ResultTempFile;
  CommandLine = strCmd.c_str();
 
  // Masquer la fenêtre, mais ne récupére par le résultat
  /*
  siStartupInfo.dwFlags = STARTF_USESHOWWINDOW;
  siStartupInfo.hStdInput = PipeInputRead;
  siStartupInfo.hStdOutput = PipeOutputWrite;
  siStartupInfo.hStdError = PipeOutputWrite;
  siStartupInfo.wShowWindow = SW_HIDE;
  */
 
  // Afficher la fenêtre et récupérer le résultat
  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);
    WaitForSingleObject(piProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess(piProcessInfo.hProcess, &dwExitCode);
    if (dwExitCode != STILL_ACTIVE)
      CloseHandle(piProcessInfo.hProcess); // fermer le handle de process
 
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeInputRead);
    CloseHandle(PipeInputWrite);
 
    while (ReadFile(PipeOutputRead, chBuf, BUFSIZE-1, &dwRead, NULL) && (dwRead != 0))
    {
      chBuf[dwRead] = '\0';
      procstdout += chBuf;
      strRes = chBuf;
    }
 
    while (ReadFile(PipeOutputRead, chBuf, BUFSIZE-1, &dwRead, NULL) && (dwRead != 0))
    {
      chBuf[dwRead] = '\0';
      procstderr += chBuf;
    }
    CloseHandle(PipeOutputRead);
  }
  else
  {
    MessageBox(NULL, CommandLine, "Command Line Error", MB_OK|MB_ICONSTOP);
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeInputRead);
  }
}