2010-06-29 10 views
3

J'utilise la commande ShellExecute pour exécuter un fichier exe qui obtient un fichier texte d'entrée et retourne un fichier texte en sortie. Je l'ai écrit comme ceci:Lecture du fichier de sortie de ShellExecute() dans Delphi 2010?

ShellExecute(mainFormHandle, 'open', 'Test.exe', 
    'input.txt output.txt', nil, sw_shownormal); 

//Read the output file... 
S_List.LoadFromFile('output.txt'); 
Writeln(S_List[0]) 

Je fournis le fichier input.txt avant d'exécuter cette commande. Dans chaque exécution de mon programme, le fichier d'entrée change, tout comme le fichier de sortie.

Le problème est le suivant: Je ne vois pas les changements dans le fichier de sortie! La ligne écrite dans la console provient du fichier précédent, pas celle qui vient d'être modifiée. Je veux dire, le fichier dans l'explorateur est changé mais le fichier que j'ai lu est toujours l'ancien fichier.

Cela semble un peu bizarre, mais je me demandais s'il y avait un moyen d'actualiser le fichier de sortie avant de le lire? Ou il me manque quelque chose ici?

Merci d'avance.

Répondre

11

ShellExecute n'attend pas que votre programme pour terminer le travail. Voilà ce qui arrive:

  • Test.exe commence
  • vous lisez dans sortie.txt
  • Test.exe écrit nouvelle sortie.txt

Essayez quelque chose comme ceci:

var 
    StartUpInfo : TStartUpInfo; 
    ProcessInfo : TProcessInformation; 
    CreationFlags : Cardinal; 
begin 
    FillChar(StartUpInfo, SizeOf(TStartupInfo),0); 
    StartupInfo.cb := SizeOf(TStartupInfo); 
    CreationFlags := Normal_Priority_Class; 

    if CreateProcess(nil, 'test.exe input.txt output.txt', 
       nil, nil, False, CreationFlags, 
       nil, 0, StartupInfo, ProcessInfo) then 
    begin 
    WaitforSingleObject(ProcessInfo.HProcess, INFINITE); 
    CloseHandle(ProcessInfo.HProcess); 

    //Read the output file... 
    S_List.LoadFromFile('output.txt'); 
    end; 

Avec WaitForSingleObject, vous pouvez attendre la fin d'un processus.

+0

Merci pour votre réponse. Je l'ai mis dans mon projet, mais il me donne cette exception: Exception de première chance à 75819617 $. Classe d'exception EAccessViolation avec message 'Violation d'accès à l'adresse 75BB9783 dans le module' kernel32.dll '. Ecrire à l'adresse 004F70C2 ' Avez-vous une idée de ce qu'est le problème? Je suis complètement perdu ici! – Mahm00d

+0

Delphi 2010 utilise la version Unicode de CreateProcess() (aka CreateProcessW()). NE PAS passer les littéraux de chaîne à CreateProcessW()! MSDN dit qu'il peut modifier la chaîne d'entrée, ce qui serait très mauvais (comme vous l'avez déjà découvert). Vous devez d'abord affecter votre littéral à une variable String comptée par référence: var S: String; S: = 'test.exe input.txt output.txt'; UniqueString (S); si CreateProcess (nil, PChar (S), ...); –

+0

Merci beaucoup Rémy! Tu as fait ma journée, mec. Ça a marché comme sur des roulettes! Dans un million d'années je ne devinerais pas que c'était le problème! Je déteste les exceptions de Delphi! Je ne comprends jamais ce qu'ils signifient et se réfèrent à. – Mahm00d