IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

lancer un seul processus en TSE toutes sessions confondues [FAQ]


Sujet :

API, COM et SDKs Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    175
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 175
    Par défaut lancer un seul processus en TSE toutes sessions confondues
    Bonjour,

    j'ai un programme delphi qui ne doit être lancé qu'une seule fois. J'ai donc créé un mutex afin de ne pouvoir lancer qu'un processus. Mon soucis est que je suis sur un serveur TSE et que mon système ne fonctionne que pour une session. J'aimerai pouvoir vérifier que le programme ne tourne pas déjà sur une autre session. J'arrive à voir les processus dans le gestionnaire des clients TSE, il doit donc y avoir un moyen de le voir par programme.

  2. #2
    Membre confirmé
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    175
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 175
    Par défaut
    Personne n'a une idée ?

  3. #3
    Rédacteur
    Avatar de evarisnea
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Juin 2005
    Messages
    1 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 957
    Par défaut
    excuse mon ignorance, mais TSE c'est quoi ?
    :

  4. #4
    Membre confirmé
    Inscrit en
    Février 2003
    Messages
    138
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 138
    Par défaut
    Vu le principe de l'environnement TSE (ou Citrix) le plus simple serait de pouvoir ecrire un fichier qui te permet de savoir si ton appli est lancée dans un repertoire commun à toute les sessions.

    La base de registre est spécifique à chaque session donc le .ini s'impose

  5. #5
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Bonjour,

    Le fichier que l'on écrit au lancement et que l'on supprime à la fin représente une solution simple, mais si le programme crashe, on est bloqué. Pour résoudre ce problème, on peut se servir des attributs datetime du fichier à condition d'actualiser périodiquement les attributs dates.
    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
    procedure TfrMain.Timer1Timer(Sender: TObject);
    begin
    //périodiquement, toutes les nn secondes 
    Deletefile(lockfilename);
    writefile(lockfilename) ;
    // Si ça crashe entre les 2 instructions précédentes : y'aura un problème 
    end;
     
    // Au lancement :
    // on vérifie si le fichier lock existe : il est toujours présent sauf en cours d'écriture du Lock
    if not Renamefile(lockfilename, tempfilename) ;
       then showmessage('process déjà actif') ;
       else begin 
              // ecrit un deuxiéme fichier pour récupérer l'heure d'écrtiture du serveur de fichier
              writefile(tempfilename2) ;
             // vérifie si la différence de datetime entre l'écritutre du temp et 
             // du lock est supérieure à n fois le timer 
           if abs(GetFileDateTime(tempfilename)-GetFileDateTime(tempfilename2))*3600*24 < n*nn 
              then showmessage('process déjà actif')  
              else begin writefile(lockfilename) ; timer1.enabled:=true ; end ;
            deletefile(tempfilename) ;
            deletefile(tempfilename2) ;
            end ;
     
    procedure writefile(filename:string) ;
    var tsl:tstringlist;
    begin
    tsl:=tstringlist.create ; tsl.savetofile(filename) tsl.free ;end;
     
    function GetFileDateTime(filename:string) : TDateTime;
    begin
    // lire les attributs date time du fichier
    if fileexists(filename) 
       then result:=0
       else begin 
              // result:=attributs date time du fichier
              ...
              end ;
    end ;

  6. #6
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Rebonjour,

    J'ai corrigé, complété et simplifié le code du message précédent :
    La seule possibilité de problème est un crash dans la function canStartProcess si il n'y a pas d'autre process actif.

    A l'installation de l'appli, il faut créer le fichier lock (lockfilename), sans quoi aucun process ne demarrera jamais.

    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
    procedure TfrMain.Timer1Timer(Sender: TObject); 
    begin //périodiquement, toutes les nn secondes 
    writefile(lockfilename) ; 
    end; 
     
    function Canstartprocess : boolean; 
    ...
    // Au lancement, on vérifie si le fichier lock existe. 
    // il sera absent si un autre process est aussi en train de démarrer 
    result:=false ;
    if Renamefile(lockfilename, tempfilename) then begin 
       // ecrit un deuxiéme fichier pour récupérer l'heure d'écriture du serveur de fichier 
       writefile(tempfilename2) ; 
       // vérifie si la différence de datetime entre l'écriture du temp et 
       // du lock est supérieure à n fois le timer 
       result:=abs(GetFileDateTime(tempfilename)-GetFileDateTime(tempfilename2))*3600*24 > n*nn 
       writefile(lockfilename) ;
       deletefile(tempfilename) ; 
       deletefile(tempfilename2) ; 
       end ; 
    timer1.enabled:=ok ;
    if not result then showmessage('process déjà actif') ; 
    end;
     
    procedure writefile(filename:string) ; 
    var tsl:tstringlist; 
    begin 
    tsl:=tstringlist.create ; tsl.savetofile(filename) ; tsl.free ; end; 
     
    function GetFileDateTime(filename:string) : TDateTime; 
    begin // lire les attributs date time du fichier 
    if fileexists(filename) 
       then result:=0 
       else result:=FileDateToDateTime(fileAge(filename)) ; 
    end ;

  7. #7
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Attention à ne pas intégrer sous Citrix/TSE une application à coup de marteau !
    Si elle n'est pas prévu pour, on ne peut rien faire si ce n'est de 'bricoler'.
    Pensez aux admins système qui vont subir ce genre d'approche, c'est une solution certes mais à quelle prix ! cf. la remarque de Graffito
    Vous allez créer le lundi vos em****** du vendredi, pensez-y.

    As-tu regardé les API TSE
    wtsenumerateprocesses
    wtsenumeratesessions

    Consulte aussi les providers pour WMI

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 60
    Par défaut
    Si votre application ne necessite aucune interface utilisateur il serait plus sage de developper un service NT ?

  9. #9
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Une autre piste
    http://www.codeproject.com/w2k/LiviuBirjegaCode3.asp
    A vérifier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    CreateMutex
    ..
     
    Terminal Services:  The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces.

  10. #10
    Membre confirmé
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    175
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 175
    Par défaut
    merci pour vos reponses.

    Je pense que Laurent a la solution mais le lien n'est pas facile à déchiffrer.

    J'ai trouvé ce lien qui explique ce que je dois faire. En plus, c'est du Delphi

    http://www.jrsoftware.org/iskb.php?mutexsessions

  11. #11
    Membre confirmé
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    175
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 175
    Par défaut
    Ca marche, le seul truc c'est que j'ai changé le nom du premier Mutex car pour windows, le nom Global\MonNomDeMutex et MonNomDeMutex sont reconnus comme le même et l'appli ne se lance pas. J'ai donc rajouté 'Local' à la fin

    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
    procedure CreateMutexes(const MutexName: String);
    { Creates the two mutexes checked for by the installer/uninstaller to see if
      the program is still running.
      One of the mutexes is created in the global name space (which makes it
      possible to access the mutex across user sessions in Windows XP); the other
      is created in the session name space (because versions of Windows NT prior
      to 4.0 TSE don't have a global name space and don't support the 'Global\'
      prefix). }
    const
      SECURITY_DESCRIPTOR_REVISION = 1;  { Win32 constant not defined in Delphi 3 }
    var
      SecurityDesc: TSecurityDescriptor;
      SecurityAttr: TSecurityAttributes;
    begin
      { By default on Windows NT, created mutexes are accessible only by the user
        running the process. We need our mutexes to be accessible to all users, so
        that the mutex detection can work across user sessions in Windows XP. To
        do this we use a security descriptor with a null DACL. }
      InitializeSecurityDescriptor(@SecurityDesc, SECURITY_DESCRIPTOR_REVISION);
      SetSecurityDescriptorDacl(@SecurityDesc, True, nil, False);
      SecurityAttr.nLength := SizeOf(SecurityAttr);
      SecurityAttr.lpSecurityDescriptor := @SecurityDesc;
      SecurityAttr.bInheritHandle := False;
      CreateMutex(@SecurityAttr, False, PChar(MutexName+'Local'));
      CreateMutex(@SecurityAttr, False, PChar('Global\' + MutexName));
    end;
     
    ...
     
    begin
      CreateMutexes('YourMutexNameGoesHere');
    end;

  12. #12
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Pour ton intégration c'est déjà plus propre
    Bon on place l'info dans la FAQ !
    Merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 16/02/2009, 14h13
  2. [Processus de développement] Tout prévoir ou être agile ?
    Par Promeneur dans le forum Méthodes
    Réponses: 4
    Dernier message: 15/04/2008, 23h15
  3. Processus qui bouffe tout CPU
    Par petchos dans le forum Sécurité
    Réponses: 2
    Dernier message: 13/03/2008, 15h22
  4. Lancer une appli avant l'ouverture de session
    Par yomapoitiers dans le forum Windows
    Réponses: 8
    Dernier message: 12/12/2006, 10h36
  5. lancer 1 seul fois l'exe..
    Par lamalice dans le forum Windows
    Réponses: 8
    Dernier message: 27/10/2004, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo