Bonjour,

Voila quelques jours que je cherche la cause du problème suivant :
Je travail avec Delphi sous Windows 2000
J'effectue un appel a CreateProcess() en redirigeant les e/s selon le code ci dessous. Une fois le processus fils terminé je souhaite exploiter le fichier généré par la redirection de stdout.
Je précise que cette fonction est appelée par plusieurs thread et qu'il y a donc exécution simultanée de plusieurs process identiques.
Le problème est que je récupère une erreur lors de l'ouverture du fichier résultat.
D'après cette erreur, le fichier serait "utilisé par un autre processus."
Il est bien évident que chaque thread lance le process avec des noms de fichiers différent pour stdout, stdin et stderr et que par consequent chaque fichier de sortie a un nom unique.
Se pourrait il que l'application lancée avec CreateProcess ne soit pas complétement terminée malgré le WaitForSingleObjet ?

Toute idée ou début de piste est la bienvenue.
Forte récompense


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
function TProcessControl.StartProcess() : Integer;
var
  si      : StartupInfo;
  pi      : Process_Information;
  sattr   : TSecurityAttributes;
begin
  fIsLoaded:=false;
  result:=0;
  ZeroMemory(@sattr,sizeof(sattr));
  sattr.nLength:=sizeof(TSecurityAttributes);
  sattr.lpSecurityDescriptor:=Nil;
  sattr.bInheritHandle:=true;

  fhdlStdOutWr:=CreateFile(PChar(fOutputFile),GENERIC_WRITE or GENERIC_READ,FILE_SHARE_READ,@sattr,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL+FILE_FLAG_NO_BUFFERING,0);
  if fhdlStdOutWrTmp = INVALID_HANDLE_VALUE
    then raise EControllerException.Create('stdout file: '+SysErrorMessage(GetLastError()));

  fhdlStdInRd:=CreateFile(PChar(fInputFile),GENERIC_READ,FILE_SHARE_READ,@sattr,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  if fhdlStdInRd = INVALID_HANDLE_VALUE
    then raise EControllerException.Create('stdin file: '+SysErrorMessage(GetLastError()));

  fhdlStdErrWr:=CreateFile(PChar(fErrFile),GENERIC_READ,FILE_SHARE_READ,@sattr,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  if fhdlStdErrWr = INVALID_HANDLE_VALUE
    then raise EControllerException.Create('stderr file: '+SysErrorMessage(GetLastError()));

  fillChar(si,sizeOf(StartupInfo),0);
  si.cb:=sizeOf(StartupInfo);
  si.hStdError:=fhdlStdErrWr;
  si.hStdInput:=fhdlStdInRd;
  si.hStdOutput:=fhdlStdOutWr;
  si.dwFlags:=STARTF_USESHOWWINDOW or	STARTF_USESTDHANDLES;
  si.wShowWindow:=SW_SHOWMINNOACTIVE;
  si.lpTitle:=PChar(fcmdLine);

  if CreateProcess(nil,PCHar(fcmdLine),Nil,Nil,true,CREATE_NEW_CONSOLE ,Nil,Nil,si,pi)
  then begin
    CloseHandle(pi.hThread);
    WaitForSingleObject(pi.hProcess,INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(fHdlStdOutWr);
    CloseHandle(fHdlStdOutRd);
    CloseHandle(fHdlStdInWr);
    CloseHandle(fHdlStdInRd);
    CloseHandle(fHdlStdErrWr);
    CloseHandle(fHdlStdErrRd);
    With TStringList.Create() do
    Try
       LoadFromFile();  // CA PLANTE ICI !!! 
    Finally
    end
  end
end;