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

  1. #1
    Rédacteur

    Savoir si un fichier est déjà ouvert par une autre application
    Bonjour,

    Je vous propose un nouvel élément à utiliser : [Delphi]Tester si fichier déjà ouvert

    Tester si un fichier est déjà ouvert par une autre application.



    NOTES : Le principe de détection est basé sur un essai d'ouverture et le test du code d'erreur 32 indiquant une violation de partage.

    Qu'en pensez-vous ?

  2. #2
    Membre émérite
    Bonjour,

    Pour ma part, j'utilise cette fonction (qui peut surement être perfectionnée) :

    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
    { ============================================================================== }
    function FichierOuvert(NomFichier : string; CodeRetour:Integer):Boolean;
    //Test si un fichier est ouvert ou indisponible
    // CodeRetour = 0 pas ouvert - 32 : violation de partage - sinon autre erreur
    Var
       F:TextFile;
    begin
      FichierOuvert := True ;
      // Test du fichier
      AssignFile(F,NomFichier);
      {$I-}
      Reset(F);
      {$I+}
      CodeRetour := IOResult ;
      Case IOResult Of
        // Pas d'erreur
        0 :Begin
             CloseFile(F);
             FichierOuvert := False ;
    //         ShowMessage('Le fichier existe et n''est pas ouvert.');
           End;
    //         L'erreur 32 est une violation de partage
        32:
           Begin
    //          ShowMessage('Le fichier est déjà ouvert.');
           End ;
      Else
        // Autre erreur
    //    ShowMessage('Erreur '+IntToStr(IOResult));
      End;
    End;


    A+

    Charly

  3. #3
    Membre éprouvé
    Aussi un truc de genre
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    GetFileAttributes(PChar(Filename))<>INVALID_FILE_ATTRIBUTES

  4. #4
    Rédacteur/Modérateur

    Ce code ne dit pas que le fichier est déjà ouvert, mais qu'il peut l'être en écriture
    Un fichier ouvert en lecture ne sera pas détecté, à moins qu'il l'ait été en mode exclusif (fmShareExclusive).

    A noter aussi que Reset ne renvoi pas d'erreur sur un fichier ouvert en mode fmOpenRead or fmShareDenyWrite (Par contre Write se plante normalement !)

    Enfin une erreur autant dans le code de Nono40 que dans celui de Charly910 (mais en pire puisque le case ne fonctionne plus du tout) : IOResult ne peut être lu qu'une seule fois. Il est reseté après le premier appel !

    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
    var
       F :TextFile;
       IORes :integer;
     
    begin
      AssignFile(F, NomFichier);
      {$I-}
      Reset(F);
      {$I+}
      IORes := IOResult;
     
      case IORes of
        0 :; //Pas ouvert ou en lecture seule
        32:; //Ouvert en écriture ou exclusif
        else ShowMessage('Erreur ' +IntToStr(IORes));
      end;
    end;

  5. #5
    Membre éprouvé
    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
     
     
    type
      foNotFound    = $00;
      foNotReadable = $01;
      foNotWritable = $02;
      foReadable    = $04;
      foWritable    = $08;
     
     
    function isOpenableFile(const aFileName: string): integer;
    var H: integer;
     
    begin
      if not FileExists(aFileName) then
      begin
        result := foNotFound;
        exit;
      end;
     
      H := FileOpen(aFileName, fmOpenRead);
      if H >= 0 then
      begin
        FileClose(H);
        result := result or foReadable;
      end
      else
        result := result or foNotReadable;
     
      H := FileOpen(aFileName, fmOpenWrite);
      if H >= 0 then
      begin
        FileClose(H);
        result := result or foWritable;
      end
      else
        result := result or foNotWritable;
    end;
    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  6. #6
    Membre éprouvé
    Salut,

    Sur mon programme pour empêcher d'ouvrir 2 fois l'application sur le même poste je fais ceci dans le DPR du programme.

    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
    var
    	H : THandle;
    	Erreur: Integer;
    begin
      SetLastError(NO_ERROR);
      H := CreateMutex(nil, False,'MONAPPLI');
      Erreur := GetLastError;
      if ( Erreur = ERROR_ALREADY_EXISTS ) or ( Erreur = ERROR_ACCESS_DENIED )
        then
        begin
        MessageDlg('MONAPPLI est déjà utilisé sur votre poste.'+#13+
        'Vous ne pouvez pas ouvrir 2 fois l''application.',mtInformation,[mbOK],0);
        CloseHandle(H);
        Exit;
      end;
     
    //...
     
    end;

  7. #7
    Futur Membre du Club
    [Delphi]Tester si fichier déjà ouvert
    Dans la proposition de Dr.Who, je suggère d'initialiser result à 0 lorsque le fichier existe. Sinon, result s'incrémente à chaque appel de la fonction.

  8. #8
    Membre émérite
    Bonjour,
    c'est impossible. En voici la preuve :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TF_Princ.Button3Click(Sender: TObject);
    Var
      I : Integer ;
    begin
      I := isOpenableFile('D:\DESSIN\44304.jpg') ;
      ShowMessage('Result : '+IntToStr(I)) ;
      I := isOpenableFile('D:\DESSIN\6094672.jpg') ;
      ShowMessage('Result : '+IntToStr(I)) ;
      I := isOpenableFile('D:\DESSIN\44304.jpg') ;
      ShowMessage('Result : '+IntToStr(I)) ;
    end;


    I n'est pas incrémenté ..

    A+
    Charly

  9. #9
    Expert éminent sénior
    Une exécution en DEBUG ou en RELEASE peut différencier
    Result peut en RELEASE contenir une valeur aléatoire alors que c'est bcp plus rare en DEBUG
    Cela dépend du contexte mémoire et peut-être même d'options du compilateur, le warning n'est pas là pour rien !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre régulier
    Bonjour,

    J'ai voulu tester le code de Dr Who, avec Delphi 7.
    J'ai une erreur avec le code suivant :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    type
      foNotFound    = $00;
      foNotReadable = $01;
      foNotWritable = $02;
      foReadable    = $04;
      foWritable    = $08;


    J'ai les erreurs suivantes :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [Erreur] Main.pas(11): '..' attendu(e) mais ';' trouvé(e)
    [Erreur] Main.pas(12): '..' attendu(e) mais ';' trouvé(e)
    [Erreur] Main.pas(13): '..' attendu(e) mais ';' trouvé(e)
    [Erreur] Main.pas(14): '..' attendu(e) mais ';' trouvé(e)
    [Erreur] Main.pas(15): '..' attendu(e) mais ';' trouvé(e)


    Je ne vois pas comment corriger le code.

  11. #11
    Modérateur

    essaye const au lieu de type
    Delphi 5 Pro - Delphi 10.3.2 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  12. #12
    Membre régulier
    Merci, je comprends mieux le code du coup !