La création d'un processus représente, de manière simplifiée, le lancement d'une application. Pour illustrer notre example, on va réaliser une application
console qui va se charger de lancer l'application dont on lui fournira le nom en paramètre.
Les I/O standards sont redirigés dans un fichier afin de récupèrer les différents messages qui pourraient être affichés sur la console.
Le fonctionnement du programme est le suivant. Un fichier d'extension CMD est créé et est composé du nom de l'application à exécuter.
La création d'un processus se fait par un appel à l'API Win32 CreateProcess. Cette fonction requiert plusieurs paramètres.
BOOL CreateProcess(
LPCTSTR lpApplicationName, // name of executable module
LPTSTR lpCommandLine, // command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
BOOL bInheritHandles, // handle inheritance option
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCTSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFO lpStartupInfo, // startup information
LPPROCESS_INFORMATION lpProcessInformation // process information
);
Les paramètres qui nous intéressent sont lpCommandLine et lpStartupInfo. Le premier va contenir le nom du fichier d'extension
CMD créé et le second va contenir
le HANDLE du fichier dans lequel sont redirigés les I/O standards. Le fichier
CMD est créé sous le répertoire temp et sera détruit à la fin du programme.
Le programme est écrit de tel manière que le fichier contenant le flux de
données issu des I/O standards est lu et retourné en tant que chaîne de
charactères afin d'être affiché.
#include "windows.h"
#include "stdio.h"
#include "atlbase.h"
BOOL CmdRun(LPSTR lpszCmd, LPSTR * lpszBuffer);
int main(int argc, TCHAR* argv[])
{
if( argc != 2 )
{
printf("CreateP2 cmd\n");
return 0;
}
LPSTR lpsz;
CmdRun(argv[1], &lpsz);
printf("%s\n", lpsz);
return 0;
}
BOOL CmdRun(LPSTR lpszCmd, LPSTR * lpszBuffer)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL bCreated = FALSE;
SECURITY_ATTRIBUTES sa;
memset(π, 0, sizeof(PROCESS_INFORMATION));
memset(&si, 0, sizeof(STARTUPINFO));
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
char szCmdOut[255];
sprintf(szCmdOut, "c:\\temp\\cmd%ld_out.txt", GetCurrentThreadId());
HANDLE hFile = CreateFile(szCmdOut, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL, NULL);
if( hFile == INVALID_HANDLE_VALUE )
{
printf("CreateFile cmd_out.txt failed\n");
return FALSE;
}
char szCmd[255];
sprintf(szCmd, "c:\\temp\\cmd%ld.cmd", GetCurrentThreadId());
HANDLE hCmdFile = CreateFile(szCmd, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL, NULL);
if( hCmdFile == INVALID_HANDLE_VALUE )
{
printf("CreateFile cmd.cmd failed\n");
return FALSE;
}
DWORD dwSize = 0;
WriteFile(hCmdFile, lpszCmd,strlen(lpszCmd), &dwSize,NULL);
CloseHandle(hCmdFile);
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hFile;
si.hStdInput = hFile;
si.hStdError = hFile;
bCreated = CreateProcess(NULL, szCmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, π);
if( bCreated==FALSE )
{
printf("CreateProcess failed\n");
return FALSE;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hFile);
HANDLE hReadCmdFile = CreateFile(szCmdOut, GENERIC_READ, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
dwSize=GetFileSize(hReadCmdFile,NULL);
*lpszBuffer = new char[dwSize];
memset(*lpszBuffer, 0, dwSize);
DWORD dwRead = 0;
ReadFile(hReadCmdFile,*lpszBuffer,dwSize,&dwRead,NULL);
CloseHandle(hReadCmdFile);
DeleteFile(szCmd);
DeleteFile(szCmdOut);
return TRUE;
}
© 2001 Christophe Pichaud. All rights reserved.