| auteur : nico-pyright(c) | Il existe deux solutions, l'une pas très propre qui utilise l'interpréteur de commandes (cmd.exe sous WinNt/2000/XP) ainsi que l'opérateur de redirection > et une qui utilise les pipes pour récupérer la sortie standard.
Dans une fenêtre DOS, on peut faire une commande du genre ipconfig / all > result.txt
|
Pour obtenir le même résultat depuis un programme Windows, on peut soit faire appel à cet interpréteur de command, soit utiliser les pipes pour rediriger la sortie et la récupérer.
1ère Solution :
SHELLEXECUTEINFO execinfo;
memset (& execinfo, 0 , sizeof (execinfo));
execinfo.lpFile = " cmd.exe " ;
execinfo.cbSize = sizeof (execinfo);
execinfo.lpVerb = " open " ;
execinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
execinfo.nShow = SW_SHOWDEFAULT;
execinfo.lpParameters = " /c ipconfig.exe /all >> result.txt " ;
if (! ShellExecuteEx (& execinfo))
{
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL , GetLastError (), 0 ,
(LPTSTR) & lpMsgBuf, 0 , NULL );
MessageBox (NULL ,(LPCTSTR)lpMsgBuf," " ,MB_ICONSTOP);
LocalFree ( lpMsgBuf );
}
WaitForSingleObject (execinfo.hProcess, INFINITE);
|
2ième Solution:
Voici une fonction qui permet de faire une redirection
# define BUFFER 4096
bool executeCmdWithRedirection (char * command, char * fileDest)
{
SECURITY_DESCRIPTOR sd;
SECURITY_ATTRIBUTES sa;
InitializeSecurityDescriptor (& sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl (& sd, true , NULL , false );
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.bInheritHandle = true ;
sa.lpSecurityDescriptor = & sd;
HANDLE hReadPipe;
HANDLE hWritePipe;
if (! CreatePipe (& hReadPipe, & hWritePipe, & sa, NULL ))
return false ;
STARTUPINFO si;
memset (& si, 0 , sizeof (STARTUPINFO));
si.cb = sizeof (STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_SHOW;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
PROCESS_INFORMATION pi;
if ( ! CreateProcess (NULL , command, NULL , NULL , TRUE, 0 , 0 , 0 , & si, & api) )
return false ;
WaitForSingleObject (pi.hProcess, INFINITE);
HANDLE hFichier;
hFichier = CreateFile (fileDest, GENERIC_WRITE, NULL , NULL , CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
if ( hFichier = = INVALID_HANDLE_VALUE)
return false ;
DWORD BytesRead ;
DWORD lu;
char dest[BUFFER];
memset (dest, 0 , BUFFER);
DWORD byteAvail = 0 ;
PeekNamedPipe (hReadPipe, NULL , 0 , NULL , & byteAvail, NULL );
if (! byteAvail)
return true ;
while (ReadFile (hReadPipe, dest, BUFFER, & BytesRead, NULL ))
{
if (! BytesRead)
break ;
WriteFile (hFichier, dest, BytesRead, & lu, NULL );
PeekNamedPipe (hReadPipe, NULL , 0 , NULL , & byteAvail, NULL );
if (BytesRead< BUFFER | | ! byteAvail)
break ;
}
CloseHandle (hFichier);
CloseHandle (hReadPipe);
CloseHandle (hWritePipe);
return true ;
}
|
if (executeCmdWithRedirection (" ipconfig.exe /all " , " sortie.txt " ))
{
}
else
{
}
|
|
| auteur : Farscape | Les Apis 32 fournissent toutes les fonctionnalités pour gérer une application en mode console.
l'exemple suivant est une classe permettant la gestion de l'écran et du clavier avec le support de la couleur .
# include <conio.h>
class CCsleWin
{
public :
CCsleWin ()
{
if (! m_nCountCsle) AllocConsole ();
m_nCountCsle+ + ;
m_hStdOut= m_hStdIn= NULL ;
m_hStdOut = GetStdHandle (STD_OUTPUT_HANDLE);
m_hStdIn = GetStdHandle (STD_INPUT_HANDLE);
SetConsoleMode (m_hStdIn,ENABLE_WINDOW_INPUT);
m_co.X= m_co.Y= 0 ;
m_Color= 7 ;
}
virtual ~ CCsleWin ()
{
CloseHandle (m_hStdIn);
CloseHandle (m_hStdOut);
m_hStdOut= NULL ;
m_hStdIn= NULL ;
m_nCountCsle- - ;
if (! m_nCountCsle) FreeConsole ();
}
void SetSize (int nWidth= 80 ,int nHeight= 25 )
{
m_co.X= nWidth;
m_co.Y= nHeight;
if (! m_hStdOut) return ;
SetConsoleScreenBufferSize (m_hStdOut, m_co);
ClearScreen ();
}
void GetSize (int & rnWidth,int & rnHeight)
{
rnWidth= m_co.X;rnHeight= m_co.Y;
}
int GetWidth ()
{
int nWidth,nHeight;
GetSize (nWidth,nHeight);
return nWidth;
}
int GetHeight ()
{
int nWidth,nHeight;
GetSize (nWidth,nHeight);
return nHeight;
}
void GotoXY (int nx= 0 ,int ny= 0 )
{
COORD co= { ny,nx} ;
if (! m_hStdOut) return ;
SetConsoleCursorPosition (m_hStdOut,co);
}
void GetCursorPos (int & rnx,int & rny)
{
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
rnx= rny= 0 ;
if (! m_hStdOut) return ;
if (! GetConsoleScreenBufferInfo (m_hStdOut, & csbiInfo)) return ;
rnx= csbiInfo.dwCursorPosition.X;
rny= csbiInfo.dwCursorPosition.Y;
}
int GetXPos ()
{
int x,y;GetCursorPos (x,y);return x;
}
int GetYPos ()
{
int x,y;GetCursorPos (x,y);return y;
}
char * ReadScreen (int nLig,int nCol,int nWidth,int nHeight)
{
char * pCarBuf= new char [nWidth* nWidth];
if (! ReadScreen (nLig,nCol,nWidth,nHeight,pCarBuf))
{
delete []pCarBuf;
return NULL ;
}
return pCarBuf;
}
bool ReadScreen (int nLig,int nCol,int nWidth,int nHeight,char * pbuff)
{
DWORD cCharsWritten;
COORD coord;
if (! m_hStdOut) return false ;
coord.Y= nLig;coord.X= nCol;
return (ReadConsoleOutputCharacter (m_hStdOut,
pbuff,
nWidth* nHeight,
coord,
& cCharsWritten)= = TRUE);
}
WORD * ReadScreenAtt (int nLig,int nCol,int nWidth,int nHeight)
{
WORD * pCarBufAtt= new WORD [nWidth* nHeight];
if (! ReadScreenAtt (nLig,nCol,nWidth,nHeight,pCarBufAtt))
{
delete []pCarBufAtt;
return NULL ;
}
return pCarBufAtt;
}
bool ReadScreenAtt (int nLig,int nCol,int nWidth,int nHeight,WORD * pbuff)
{
DWORD cCharsWritten;
COORD coord;
if (! m_hStdOut) return false ;
coord.Y= nLig;coord.X= nCol;
return (ReadConsoleOutputAttribute (m_hStdOut,
pbuff,
nWidth* nHeight,
coord,
& cCharsWritten)= = TRUE);
}
void ScrollLine ()
{
if (! m_hStdOut) return ;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
if (! GetConsoleScreenBufferInfo (m_hStdOut, & csbiInfo)) return ;
csbiInfo.dwCursorPosition.X = 0 ;
if ((csbiInfo.dwSize.Y- 1 ) = = csbiInfo.dwCursorPosition.Y)
{
SMALL_RECT srctWindow;
if (csbiInfo.srWindow.Top > 0 )
{
srctWindow.Top = - 1 ;
srctWindow.Bottom = - 1 ;
srctWindow.Left = 0 ;
srctWindow.Right = 0 ;
if (! SetConsoleWindowInfo (
m_hStdOut,
FALSE,
& srctWindow))
{
return ;
}
}
else
{
char * pCarBuf= new char [GetWidth ()* GetHeight ()];
WORD * pCarBufAtt= new WORD [GetWidth ()* GetHeight ()];
if (ReadScreen (0 ,0 ,GetWidth (),GetHeight (),pCarBuf) & &
ReadScreenAtt (0 ,0 ,GetWidth (),GetHeight (),pCarBufAtt))
{
COORD coord= { 0 ,0 } ;
DWORD cCharsWritten;
memcpy (pCarBuf,pCarBuf+ GetWidth (),
(GetWidth ()* GetHeight ())- GetWidth ());
memcpy (pCarBufAtt,
((char * )pCarBufAtt)+ (GetWidth ()* sizeof (WORD)),
(GetWidth ()* GetHeight ())- GetWidth ()* sizeof (WORD));
memset (pCarBuf+ (GetWidth ()* GetHeight ())- GetWidth (),' ' ,GetWidth ());
memset (((char * )pCarBufAtt)+ (((GetWidth ()* GetHeight ())- GetWidth ())* sizeof (WORD)),
(WORD)GetColor (),GetWidth ()* sizeof (WORD));
WriteConsoleOutputCharacter (m_hStdOut,
pCarBuf,
GetWidth ()* GetHeight (),
coord,
& cCharsWritten);
WriteConsoleOutputAttribute (m_hStdOut,
pCarBufAtt,
GetWidth ()* GetHeight (),
coord,
& cCharsWritten);
}
delete []pCarBuf;
delete []pCarBufAtt;
}
}
else csbiInfo.dwCursorPosition.Y + = 1 ;
if (! SetConsoleCursorPosition (m_hStdOut,csbiInfo.dwCursorPosition))
{
return ;
}
}
bool MessString (const char * szMess,bool bSetColor= false ,int nLenght= 0 )
{
DWORD cCharsWritten;
int nx,ny,nlen;
if (! m_hStdOut) return false ;
nlen= (nLenght?nLenght:strlen (szMess));
if (bSetColor) GetCursorPos (nx,ny);
WriteConsole (m_hStdOut, szMess, nlen, & cCharsWritten, NULL );
if (bSetColor) FillRgnColor (ny,nx,nlen,1 ,GetColor ());
return (cCharsWritten= = (unsigned )nlen);
}
bool PutCh (int c)
{
char sz[2 ];
sprintf (sz," %c " ,c);
return MessString (sz);
}
bool CPuts (const char * pString)
{
return MessString (pString,true );
}
bool CPrintf (const char * fmt, ...)
{
if (! m_hStdOut) return false ;
char * psz= new char [GetWidth ()+ 1 ];
va_list argptr;
int cnt;
va_start (argptr, fmt);
cnt = vsprintf (psz, fmt, argptr);
va_end (argptr);
bool bOk= MessString (psz,true );
delete []psz;
return bOk;
}
bool Printf (const char * fmt, ...)
{
if (! m_hStdOut) return false ;
char * psz= new char [GetWidth ()+ 1 ];
va_list argptr;
int cnt;
va_start (argptr, fmt);
cnt = vsprintf (psz, fmt, argptr);
va_end (argptr);
bool bOk= MessString (psz);
delete []psz;
return bOk;
}
void ClearScreen ()
{
FillRgnColor (0 ,0 ,m_co.Y,m_co.X,0 ,' ' );
GotoXY ();
}
void SetColor (int nColor){ m_Color= nColor;}
int GetColor (){ return m_Color;}
void FillRgnColor (int nLig,int nCol,int nWidth,int nHeight,
int nColor,char nChar= 0 )
{
COORD coord;
if (! m_hStdOut) return ;
for (int nlig= nLig;nlig< nLig+ nHeight;nlig+ + )
{
DWORD cWritten;
coord.Y= nlig;
coord.X= nCol;
FillConsoleOutputAttribute ( m_hStdOut,
nColor,
nWidth,
coord,
& cWritten);
if (nChar)
FillConsoleOutputCharacter (m_hStdOut,
(TCHAR)nChar,
(DWORD)nWidth,
coord,
& cWritten);
}
}
int GetCh ()
{
DWORD i;
int nCarCode;
struct EVENT_KEYBOARD EventKeyBoard;
bool bOk;
if (! m_hStdIn) return 0 ;
bOk= false ;
while (! bOk)
{
ReadConsoleInput (EventKeyBoard);
for (i= 0 ;i< EventKeyBoard.cRead;i+ + )
{
switch (EventKeyBoard.EventType)
{
case KEY_EVENT:
if (EventKeyBoard.wVirtualKeyCode= = 16 ) continue ;
if (EventKeyBoard.wVirtualKeyCode= = 17 ) continue ;
if (EventKeyBoard.wVirtualKeyCode= = 18 ) continue ;
if (EventKeyBoard.bKeyDown)
{
if (EventKeyBoard.AsciiChar)
nCarCode= EventKeyBoard.AsciiChar;
else nCarCode= EventKeyBoard.wVirtualKeyCode;
bOk= true ;
}
break ;
case MOUSE_EVENT:
continue ;
case WINDOW_BUFFER_SIZE_EVENT:
continue ;
case MENU_EVENT:
continue ;
case FOCUS_EVENT:
continue ;
}
}
}
return (nCarCode);
}
private :
struct EVENT_KEYBOARD
{
WORD EventType;
BOOL bKeyDown;
WORD wVirtualKeyCode;
DWORD dwControlKeyState;
unsigned char AsciiChar;
WORD wVirtualScanCode;
DWORD cRead;
} ;
void ReadConsoleInput (struct EVENT_KEYBOARD & rEventKeyBoard)
{
INPUT_RECORD irInBuf[1 ];
:: ReadConsoleInput (m_hStdIn,irInBuf,1 ,& rEventKeyBoard.cRead);
rEventKeyBoard.EventType= irInBuf[0 ].EventType;
rEventKeyBoard.bKeyDown= irInBuf[0 ].Event.KeyEvent.bKeyDown;
rEventKeyBoard.wVirtualKeyCode= irInBuf[0 ].Event.KeyEvent.wVirtualKeyCode;
rEventKeyBoard.dwControlKeyState= irInBuf[0 ].Event.KeyEvent.dwControlKeyState;
rEventKeyBoard.AsciiChar= irInBuf[0 ].Event.KeyEvent.uChar.AsciiChar;
rEventKeyBoard.wVirtualScanCode= irInBuf[0 ].Event.KeyEvent.wVirtualScanCode;
}
private :
HANDLE m_hStdOut,m_hStdIn;
static int m_nCountCsle;
COORDm_co;
intm_Color;
} ;
int CCsleWin:: m_nCountCsle= 0 ;
int main (int argc, char * argv[])
{
CCsleWin Csle;
Csle.SetSize ();
Csle.SetColor (78 );
Csle.MessString (" Hello World!\n " ,true );
int n;
Csle.GotoXY (10 ,0 );
do
{
n= Csle.GetCh ();
if ((Csle.GetXPos ()= = Csle.GetWidth ()- 1 ) | |
(Csle.GetYPos ()= = Csle.GetHeight ()- 1 & &
Csle.GetXPos ()= = Csle.GetWidth ()- 1 )) Csle.ScrollLine ();
Csle.Printf (" %c " ,n);
}
while (n! = 27 );
return 0 ;
}
|
|
| auteur : nico-pyright(c) |
On se sert des API CharToOem et OemToChar pour les conversions.
char maChaine[20 ] = " abcdéùàabc " ;
printf (" %s\n " ,maChaine);
CharToOem (maChaine,maChaine);
printf (" %s\n " ,maChaine);
char saisie[20 ];
scanf (" %s " ,saisie);
printf (" %s\n " ,saisie);
OemToChar (saisie,saisie);
printf (" %s\n " ,saisie);
|
Avec des char, on peut se servir du même pointeur en source et en destination pour la conversion.
En unicode, on ne peut bien sur pas faire de même, car la taille de la chaîne est double (caractères codés sur deux octets) => il faut donc utiliser deux variables.
Pour les CString, le principe est le même, sachant que les CString disposent de méthodes membres : AnsiToOem et OemToAnsi
CString chaine = " abcùàéabc " ;
printf (" %s\n " ,chaine);
chaine.AnsiToOem ();
printf (" %s\n " ,chaine);
scanf (" %s " ,chaine);
printf (" %s\n " ,chaine);
chaine.OemToAnsi ();
printf (" %s\n " ,chaine);
|
|
| auteur : nico-pyright(c) | On peut se servir de la simulation des touches ALT+ENTREE
void altEntree ()
{
keybd_event (VK_MENU,0x38 ,0 ,0 );
keybd_event (VK_RETURN,0x1c ,0 ,0 );
keybd_event (VK_RETURN,0x1c ,KEYEVENTF_KEYUP,0 );
keybd_event (VK_MENU,0x38 ,KEYEVENTF_KEYUP,0 );
}
|
De la même façon, pour revenir en mode fenêtrée, on peut rappeler la fonction ALT+ENTREE
|
| auteur : Farscape | En utilisant les fonctions win32 dédiées au mode console.
L'exemple ci-dessous montre l'implémentation d'une fenêtre de trace debug en mode console, avec le support éventuel d'un fichier trace .
class CMyApp : public CWinApp
{
public :
CMyApp ();
~ CMyApp ();
void StartDebugConsole (int nWidth,int nHeight,const char * pszfname= NULL );
void DebugNewLine (void );
voidDebugPrintf (const char * szfmt,...);
public :
HANDLE m_hStdOut;
CStdioFile m_stdFileDebug;
public :
virtual BOOL InitInstance ();
afx_msg void OnAppAbout ();
DECLARE_MESSAGE_MAP ()
} ;
|
CMyApp:: CMyApp ()
{
m_hStdOut= NULL ;
}
CMyApp:: ~ CMyApp ()
{
# ifdef _DEBUG
if (m_stdFileDebug.m_pStream! = NULL ) m_stdFileDebug.Close ();
if (m_hStdOut)
{
FreeConsole ();
CloseHandle (m_hStdOut);
}
# endif
}
void CMyApp:: StartDebugConsole (int nWidth, int nHeight,const char * pszfname)
{
# ifdef _DEBUG
if (m_hStdOut) return ;
AllocConsole ();
SetConsoleTitle (" Debug Window " );
m_hStdOut = GetStdHandle (STD_OUTPUT_HANDLE);
COORD co = { nWidth, nHeight } ;
SetConsoleScreenBufferSize (m_hStdOut, co);
if (pszfname)
m_stdFileDebug.Open (pszfname,
CFile:: modeCreate | CFile:: modeReadWrite | CFile:: typeText | CFile:: shareDenyWrite);
co.X= co.Y= 0 ;
SetConsoleCursorPosition (m_hStdOut,co);
# endif
}
void CMyApp:: DebugNewLine (void )
{
# ifdef _DEBUG
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
if (! GetConsoleScreenBufferInfo (m_hStdOut, & csbiInfo))
return ;
csbiInfo.dwCursorPosition.X = 0 ;
if ((csbiInfo.dwSize.Y- 1 ) = = csbiInfo.dwCursorPosition.Y)
{
SMALL_RECT srctWindow;
if (csbiInfo.srWindow.Top > 0 )
{
srctWindow.Top = - 1 ;
srctWindow.Bottom = - 1 ;
srctWindow.Left = 0 ;
srctWindow.Right = 0 ;
if (! SetConsoleWindowInfo (
m_hStdOut,
FALSE,
& srctWindow))
{
return ;
}
}
}
else csbiInfo.dwCursorPosition.Y + = 1 ;
if (! SetConsoleCursorPosition (m_hStdOut,
csbiInfo.dwCursorPosition))
{
return ;
}
# endif
}
void CMyApp:: DebugPrintf (const char * szfmt, ...)
{
# ifdef _DEBUG
char s[300 ];
va_list argptr;
int cnt;
va_start (argptr, szfmt);
cnt = vsprintf (s, szfmt, argptr);
va_end (argptr);
DWORD cCharsWritten;
if (m_hStdOut)
{
DebugNewLine ();
WriteConsole (m_hStdOut, s, strlen (s), & cCharsWritten, NULL );
}
if (m_stdFileDebug.m_pStream! = NULL )
{
CString str= s;
str+ = " \r\n " ;
m_stdFileDebug.WriteString (str);
}
# endif
}
|
Utilisation à partir d'un endroit quelconque du programme :
((CMyApp * )AfxGetApp ())- > StartDebugConsole (80 ,25 ," essai.txt " );
for (int i= 0 ;i< 5 ;i+ + )
((CMyApp * )AfxGetApp ())- > DebugPrintf (" Txt Ligne:%d " ,i);
|
|
Consultez les autres F.A.Q.
|
|