Précédent   Forum du club des développeurs et IT Pro > Environnements de développement > Delphi > Langage
Langage Tout ce qui concerne le langage (POO, syntaxe, message d'erreur...)
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 05/12/2012, 10h59   #1
bvsud
 
Inscription : avril 2004
Messages : 185
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 185
Points : -1
Points : -1
Par défaut Message d'erreur aléatoire sur Form.Visible

Bonjour à tous : )

Suivent deux codes. Apparemment identiques. Mais, à l'exécution du second, j'ai ce message systématique (d'autres si je cache l'application, etc):



Le code fonctionnant :
Code :
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
 
 
Procedure Appel_6;
 
Var  StartInfo   : TStartupInfo;
     ProcessInfo : TProcessInformation;
     Fin         : Boolean;
     Ligne_Cmd : string;
 
begin
 
  FillChar(StartInfo,SizeOf(StartInfo),#0);
  StartInfo.cb     := SizeOf(StartInfo);
  StartInfo.wShowWindow := SW_SHOWMAXIMIZED;
  StartInfo.dwFlags := STARTF_USESHOWWINDOW;
 
  Form1.Visible := False;
 
  Ligne_Cmd := PCHar(Nom_Editeur)  + ' ' + PChar(F_Cible);
 
  If CreateProcess(Nil, PChar(Ligne_Cmd)
                   , Nil, Nil, False, 0, Nil, Nil, StartInfo, ProcessInfo) then
 
  Begin
      Fin := False;
 
      Repeat
        Case WaitForSingleObject(ProcessInfo.hProcess, 200)Of
          WAIT_OBJECT_0 :  Fin := True; { L'application est terminée, on sort }
          WAIT_TIMEOUT  :  ;            { elle n'est pas terminée, on continue d'attendre }
        End;
 
        Application.ProcessMessages;
      Until Fin;
    End
  Else
      begin
          RaiseLastOSError;
          Form1.Visible := True;
      end;
 
  Form1.Visible := True;
  SetForegroundWindow(Handle_App);
 
End;
Celui qui plante :

Code :
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
 
Procedure Appel_Editeur(Nom_Editeur : string; F_Cible : string);
Var   StartInfo   : TStartupInfo;
      ProcessInfo : TProcessInformation;
      Fin         : Boolean;
      Ligne_Cmd : string;
      Num_Err : integer;
 
begin
  FillChar(StartInfo,SizeOf(StartInfo),#0);
  StartInfo.cb     := SizeOf(StartInfo);
  Startinfo.dwFlags := STARTF_USESHOWWINDOW;
  StartInfo.wShowWindow := SW_SHOWMAXIMIZED;
 
  Form1.Visible := False; 
  { Lancement de la ligne de commande }
  Ligne_Cmd := PCHar(Nom_Editeur)  + ' ' + PChar(F_Cible);
 
  If CreateProcess(Nil, PChar(Ligne_Cmd)
                   , Nil, Nil, False, 0, Nil, Nil, StartInfo, ProcessInfo) then
  Begin
      Fin := False;
 
      Repeat
        Case WaitForSingleObject(ProcessInfo.hProcess, 200)Of
          WAIT_OBJECT_0 :  Fin := True; { L'application est terminée, on sort }
          WAIT_TIMEOUT  :  ;            { elle n'est pas terminée, on continue d'attendre }
        End;
 
        Application.ProcessMessages;
      Until Fin;
    End
  Else
      begin
          Form1.Visible := True;   
          RaiseLastOSError;
          Num_Err := GetLastError;
          MessageDlg('ERREUR NUMERO : ' + IntToStr(Num_Err), mtError, [mbOK], 0);
      end;
 
   Form1.Visible := True;   
   SetForegroundWindow(Handle_App);
 
end;
Pourquoi plante-t-il seulement sur le second ?

Merci :hello:
bvsud est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/12/2012, 15h51   #2
Andnotor
Rédacteur/Modérateur
 
Avatar de Andnotor
 
Inscription : septembre 2008
Messages : 2 886
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 2 886
Points : 4 372
Points : 4 372
Dans le premier cas, tu lèves systématiquement une exception avec RaiseLastOSError (même en cas de succès). Les lignes suivantes ne sont jamais exécutées !
__________________
Mes tutoriels Delphi
Andnotor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2012, 15h26   #3
bvsud
 
Inscription : avril 2004
Messages : 185
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 185
Points : -1
Points : -1
Je suis désolé, mais je ne comprends décidément pas CreateProcess().


Parfois ça marche, parfois pas, et je ne comprends pas pourquoi. C'est ici-même que j'ai eu ce code avec WAIT_OBJECT .

J'ai tout essayé. Même avec TRayIcon de Jedi, tout. Rien à faire. J'ai supprimé Form1.Visible := False, bien sûr. J'ai beau faire Application.Minimize, elle n'attend pas la fin du processus appelé : elle continue comme si de rien n'était.

Alors que dans l'exemple 1, elle reste en icône, sans problème... Je "sens" que je ne dois pas être loin de trouver, mais je tourne en rond sur cette procédure-là. Moi, oui

Alors que dans mon lanceur de FireFox, j'appelle un processus fils, un EXE, et l'appelant est bel et bien caché.

Voici ce code qui marche :

Code :
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
 
 
Procedure Appel_Module_ITF_Listes;
Var	Processus : string;
  	StartupInfo: TStartupinfo;
  	ProcessInfo: TProcessInformation;
  	Retour : longbool;
  	Rep : string;
 
begin
 
 
  FillChar(Startupinfo,Sizeof(TStartupinfo),0);
  Startupinfo.cb:=Sizeof(TStartupInfo);
 
	Processus :=     Rep_Instal_Logiciel + '\Lanceur_FF_ITF_Lst.exe';
  Rep :=           Rep_Instal_Logiciel;
 
  Form1.CoolTrayIcon1.IconVisible := True;
  Form1.CoolTrayIcon1.HideMainForm;
 
  Retour := CreateProcess(nil,
                         PChar(Processus),
  			 								 nil,
                         nil,
                         false,
                         normal_priority_class,
                         nil,
                         PChar(Rep),
                         Startupinfo,ProcessInfo);
 
 
  if Retour <> false then
        begin
                WaitforSingleObject(Processinfo.hProcess, infinite);
                CloseHandle(ProcessInfo.hProcess);
        end
  else
        begin
                RaiseLastOSError;
 
        end;
 
  Form1.Visible := True;
  Form1.CoolTrayIcon1.ShowMainForm;
 
  Recuperer_Code_Retour_ITF_Module_Listes;  // A travers un fichier .TMP
  If Code_Retour_ITF_Listes = True then Quitter
  Else
      begin
            SetForegroundWindow(Handle_App);
            Form1.Btn_Demarrage.SetFocus;
      end;
 
 
end;
Bizarre, quand-même...
bvsud est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2012, 15h29   #4
Rayek
Modérateur
 
Avatar de Rayek
 
Homme
Développeur informatique
Inscription : mars 2005
Messages : 5 015
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 39
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : mars 2005
Messages : 5 015
Points : 7 781
Points : 7 781
Normal qu'il n'attende pas tu ne fais pas de boucle d'attente avec le WaitforSingleObject

voir

http://delphi.developpez.com/faq/?pa...oleapplication
__________________
Modérateur Delphi Combattez la brute
Aucune réponse aux sollicitations techniques par MP

Le guide du bon forumeur :__________
[Projet en cours] Des unités pour faciliter l'utilisation d'indy : EasyIndy 1.3
Rayek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2012, 18h57   #5
Andnotor
Rédacteur/Modérateur
 
Avatar de Andnotor
 
Inscription : septembre 2008
Messages : 2 886
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 2 886
Points : 4 372
Points : 4 372
WaitForSingleObject est bloquant et les messages nécessaires à masquer la fiche ne seront gérés effectivement qu'après la sortie de la fonction. Après HideMainForm, il faudrait au moins un Application.ProcessMessages pour forcer leur traitement immédiat.

Sinon, je n'utilise plus CreateProcess depuis longtemps à part si je cible un desktop particulier. Je lui préfère ShellExecuteEx.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
uses ShellApi,
 
function RunAndWait(aApp, aParams, aVerb :string; aShow :integer): boolean;
var
  Info: TShellExecuteInfo;
 
begin
  ZeroMemory(@Info, SizeOf(Info));
  Info.cbSize       := SizeOf(TShellExecuteInfo);
  Info.fMask        := SEE_MASK_NOCLOSEPROCESS;
  Info.lpFile       := PChar(aApp);
  Info.lpParameters := PChar(aParams);
  Info.lpVerb       := PChar(aVerb);
  Info.nShow        := aShow;
 
  Result := ShellExecuteEx(@Info);
 
  if Result then
    WaitForSingleObject(Info.hProcess, INFINITE);
end;
__________________
Mes tutoriels Delphi
Andnotor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2012, 21h44   #6
Montor
Membre émérite
 
Avatar de Montor
 
Homme
Inscription : avril 2008
Messages : 863
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Algérie

Informations forums :
Inscription : avril 2008
Messages : 863
Points : 844
Points : 844
ou simplement exécute ton code sur un autre thread
Montor est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 08h43.


 
 
 
 
Partenaires

Hébergement Web