VBFileFind : Recherche de fichiers pour remplacer celle de Windows

Documentation : VBFileFind.html

http://patrice.dargenton.free.fr/CodesSources/VBFileFind.html

http://patrice.dargenton.free.fr/CodesSources/VBFileFind.vbproj.html

https://codes-sources.commentcamarche.net/source/52496

Par Patrice Dargenton : patrice.dargenton@free.fr

http://patrice.dargenton.free.fr/index.html

http://patrice.dargenton.free.fr/CodesSources/index.html

Version 1.08 du 01/04/2017

 

Occasionnellement, il arrive qu'on ait besoin de chercher des fichiers sur son disque dur. Il serait absurde de diviser la puissance utile de sa machine par deux juste pour pouvoir utiliser un moteur de recherche local, simplement par négligence à bien ranger ses fichiers ! Mais lorsque malgré tout on a vraiment besoin d'une recherche efficace, rien n'est plus énervant qu'un logiciel qui passe son temps à chercher à l'intérieur des milliers de fichiers zip sur votre disque dur. Qui plus est, lorsque ledit logiciel trouve un fichier dans un dossier, mais qu'il ne le trouve plus lorsqu'on remonte dans le dossier parent (en y incluant bien tous les sous-dossiers) la conclusion est implacable : le système de recherche de Windows XP est quasi-inutile. Celui de Vista a été amélioré avec la possibilité d'exclure la recherche dans les zip, mais là pour le coup, on ne peut pas appeler une amélioration la division par deux des performances générales du système par rapport à XP (je n'ai pas eu l'occasion de tester suffisamment Windows 7). Et comme j'imagine que corriger les bugs de XP est vraiment le dernier des soucis de Microsoft (XP est sur le point d'être placardisé une fois pour toute), alors voici un logiciel pour remplacer le système de recherche de XP. Je suis parti d'une excellente source en C# sur CodeProject. J'y ai notamment ajouté la gestion de l'argument en ligne de commande, ce qui permet de l'appeler depuis l'explorateur de fichier, comme la recherche intégrée de fichiers de XP. J'ai aussi ajouté la prise en compte des recherches insensibles à la casse, en combinant les recherches avec le type d'encodage :

 

 

Fonctionnalités

- Recherche sensible ou insensible à la casse (minuscules/majuscules) ;

- Recherche sur un octet (ASCII/ANSI) ou deux octets (Unicode), ou les deux à la fois ;

- Recherche avec ou sans les sous-dossiers ;

- Recherche par dates min./max. ;

- Mémorisation des options de recherche ;

- Signalement des erreurs (ex.: fichier inaccessible, faut de droit ou parce que utilisé par un autre logiciel) ;

- Ouverture des fichiers trouvés dans le bloc-notes, avec recherche automatique de la 1ère occurrence ;

- Recherche via l'explorateur de fichiers, avec le bouton droit sur un dossier sélectionné.

 

 

Table des matières

Fonctionnalités. 1

Mode d'emploi 2

Comment trier les fichiers dans un ListView ?. 2

Différences entre Recherche et Indexation. 3

Projets. 4

Historique des versions. 4

Version 1.08 du 01/04/2017. 4

Version 1.07 du 19/03/2017. 4

Version 1.06 du 16/10/2016. 4

Version 1.05 du 24/09/2016. 4

Version 1.04 du 25/10/2015. 4

Version 1.03 du 06/07/2014. 4

Version 1.02 du 30/12/2012. 4

Version 1.01 du 21/11/2010 : Première version. 5

Version d'origine en C# du 24/04/2010. 5

Liens. 5

Voir aussi 5

 

 

Mode d'emploi

 

Ajouter le menu contextuel via le bouton +, quitter VBFileFind, puis lancer une recherche via l'explorateur de fichier de Windows, en sélectionnant un dossier avec le bouton droit de la souris, puis en cliquant sur "Rechercher avec VBFileFind".

 

 

Comment trier les fichiers dans un ListView ?

 

Après de multiples recherches plus ou moins laborieuses, j'ai fini par déterminer les spécifications d'un ListView triable (SortableListView) qui va bien (en mode d'affichage détaillé surtout) :

 

- Code VB simple, sans références externes (pas de DirInfo, FileInfo, ... : la ListView doit pouvoir contenir n'importe quel type d'objet, pas seulement des fichiers ou dossiers), générique donc, par exemple une classe ucSortableListView complète dans un seul fichier source (avec interface en mode design, on doit pouvoir passer facilement de VB à C# ou l'inverse) ;

- La classe doit dériver de ListView, de façon à pouvoir remplacer un ListView facilement dans le code source ;

- On doit voir aussi ses propriétés en mode design dans Visual Studio ;

- Tri selon le type de données (Chaîne, Int, Long, Date, ... avec le code source extensible) et non pas selon la chaîne représentant une date, une taille de fichier, ... (si possible définir un CompareTo générique, à condition que cela ne complique pas le code source, cela doit au contraire le simplifier) ;

- Ajout d'élément via un tableau d'objet (car on ne connait pas le type à priori) :

    En fait il y a une astuce : il faut passer par la propriété Tag du ListView :

    Me.sortableListView.Columns.Add("String Field").Tag = GetType(String)

    Me.sortableListView.Columns.Add("DateTime Field").Tag = GetType(DateTime)

    Me.sortableListView.Columns.Add("Int Field").Tag = GetType(Integer)

    Me.sortableListView.Columns.Add("Double Field").Tag = GetType(Double)

- Affichage des flèches haut/bas selon le tri appliqué sur l'une des colonnes : le code doit être simple, pas d'API Win32 ni d'usine à gaz pour afficher une petite image ! Comme dans l'explorateur de Windows, on peut aussi griser légèrement la colonne actuellement triée, à condition de ne pas effacer certaines zones coloriées, par exemple si les items sont des dossiers coloriés (ce qui indique ici des dossiers dont l'accès n'a pas été autorisé) ;

- Taille de fichier : ne doit pas être limité à int32 (comme le DataGridView : 2 Go max., du coup les codes sources qui l'utilisent affichent la taille en Ko au lieu d'octets !). On doit donc pouvoir implémenter le CompareTo avec un Long aussi bien qu'un Int32. Le format d'affichage vient après, la solution est d'utiliser deux colonnes distinctes, une avec la taille du fichier en octets (long = int64), et une autre colonne avec la taille du fichier formatée en mode texte (Octets, Ko, Mo, Go, To), c'est la colonne qui est visible, tandis que l'autre est masquée. Si on clique sur l'entête de la colonne pour trier les fichiers par taille de fichier, alors on applique le tri sur l'autre colonne qui contient la longueur en octets ;

Tips possible (exemple : chemin complet si on laisse la souris sur l'item) : cela est déjà fait dans le ListView de base ;

- Pendant le tri, la classe doit générer un événement Sablier, de façon à suspendre les manipulations externes (cela complique un peu le code, mais c'est nécessaire pour éviter de figer l'application), et pour pouvoir afficher par exemple "Tri en cours...", puis "Tri terminé." ;

- Le tri doit être désactivable (une fonction de désactivation doit enlever le tri : ListViewItemSorter, rétablir les couleurs avant le tri, et enlever l'icône de la colonne triée).

 

 

Différences entre Recherche et Indexation

 

VBFileFind est un logiciel de recherche de fichiers, il n'indexe pas le contenu de vos fichiers : l'avantage, c'est qu'il n'est pas nécessaire de mettre à jour en permanence un index à chaque fois qu'un fichier est modifié sur votre disque dur. L'inconvénient, c'est que lors de la recherche, on est obligé de tenir compte à la volée de plusieurs formats différents de données : ANSI ou Unicode, sensible à la casse ou bien insensible, ce qui oblige à convertir l'ensemble du volume de donnée à comparer sous chacun de ses formats. Avec un logiciel d'indexation, un format unique (ou éventuellement plusieurs) est enregistré dans l'index, et la recherche n'a pas besoin de parcourir les données, il suffit de parcourir l'arborescence de l'index, sous une forme de dictionnaire des mots présents dans l'ensemble du contenu indexé, ce qui est instantané (mais qui peut prendre beaucoup d'espace disque). C'est un peu comme lorsque l'on consulte l'index d'un livre pour savoir si le livre traite de tel sujet et à quelle page, sans avoir besoin de parcourir le livre en totalité (voir VBTextFinder).

 

Google n'indexe jamais les accents ni les majuscules, ni la ponctuation, par contre il conserve en cache le texte complet, d'une part pour afficher correctement un court extrait de l'occurrence trouvée dans son contexte, au-dessous du lien trouvé, et d'autre part dans le cas où la page indexée n'existe plus, la copie cache permet quand même de la consulter dans l'état où elle se trouvait lors de l'indexation. Mais le cache ne sert pas pour la recherche, Google ne peut pas distinguer une recherche avec ou sans accents, majuscules ou ponctuation. Tous les deux mois, la totalité du web accessible (via au moins un lien hypertexte) est automatiquement indexée, il n'y a pas besoin de faire quoi que ce soit pour cela. On peut cependant donner des directives via un fichier Robot.txt situé à la racine d'un site web pour exclure certaines pages, ou demander une fréquence de mise à jour plus élevée, ... En principe, une page web dont vous seul connaissez l'existence sur votre site ne sera jamais indexée (à condition d'avoir laisser un fichier index.html dans le même dossier, ce qui évite la consultation du contenu du dossier). Dans les pages Html, le format d'encodage est précisé en clair dans l'entête du document.

 

L'encodage ASCII/ANSI consiste à utiliser un seul octet pour coder les caractères, comme les américains n'utilise pas les accents, une table de 95 caractères suffit dans la plupart des cas (256 caractères au maximum, soit 2^8 bits = un octet). Cela fait gagner 50% d'espace disque par rapport à l'Unicode, mais ce dernier permet d'encoder tous les caractères de chaque langue, c'est donc ce dernier qui est utilisé dès que l'ASCII est insuffisant. Lors d'une recherche, on ne peut pas toujours savoir si c'est l'un ou l'autre qui est utilisé, les fichiers textes sont souvent en ASCII (mais on peut choisir le format unicode, par exemple pour conserver les caractères exotiques).

 

Dès que le mot est trouvé dans le fichier, la lecture du fichier s'arrête, de sorte que si vous recherchez un texte fréquent, la recherche sera rapide, mais si vous cherchez un texte rare, n'importe où sur votre disque dur, alors la totalité du contenu de votre disque dur sera examinée. La fréquence affichée avec les autres informations de résultat indique justement le volume de données lu par rapport au volume total des données. Une fréquence proche de 100% indique que le mot recherché est toujours présent au début de chaque fichier examiné, alors qu'une fréquence proche de 0% indique que les fichiers ont été parcourus en totalité sans succès.

 

La vitesse de recherche dépend de plusieurs facteurs, le débit de lecture varie entre 1 et 100 Mo/sec. Si vous recherchez à la fois en Unicode et ASCII, la vitesse sera divisée par 2, si vous recherchez en mode insensible à la casse, la vitesse sera divisée par 3, et si vous recherchez avec toutes ces options, elle sera divisée par 6. La première recherche sera assez lente, mais une seconde recherche utilisera le cache disque de Windows, de sorte qu'on pourra atteindre 90 ou 100 Mo/sec., d'après ce que j'ai pu constater (on n'entend plus l'accès au disque dur les fois suivantes), mais il doit bien y avoir une limite, car Windows ne peut pas stocker tout le contenu du disque dur en RAM ! La vitesse semble aussi dépendre de la taille moyenne des fichiers (sans doute du fait que plus le fichier est gros, plus sa fragmentation est probable), mais il n'est pas évident de comprendre tous les facteurs en jeu.

 

 

Projets

 

- Option pour signaler ou pas qu'il y a des dossiers inaccessibles ;

- Option de recherche des fichiers seuls, ou des dossiers seuls, ou alors les deux ;

- Option de recherche des mots entiers (s'il existe, le caractère avant et après le mot n'est pas une lettre ni un chiffre ni le caractère souligné) ;

- Option de recherche en ignorant les accents (voir VBWinDiff) ;

- Option de recherche dans les archives zip ;

- Une fois que la recherche est terminée, affichage de l'icône de chaque fichier trouvé, ainsi que le menu contextuel correspondant au fichier (ou dossier) trouvé, complété par des actions communes : Ouvrir, Ouvrir via le bloc-notes, Ouvrir le dossier (ou Explorer à partir d'ici ou du fichier), Copier, Supprimer ;

- Mémorisation de plusieurs recherches courantes et récurrentes (on indique le nombre de recherche que l'on veut conserver, et un ou deux boutons pour parcourir ces recherches : chaque recherche reprend toutes les options associées à cette recherche).

 

 

Historique des versions

 

Version 1.08 du 01/04/2017

- Si l'application est iconisée, ne pas changer la taille des colonnes de la zone de résultats.

 

Version 1.07 du 19/03/2017

- Passage au .NET Framework 4 Client Profile (puisqu'on n'utilise pas de bibliothèque spécifique au .NET Framework 4 complet) ;

- Optimisation : Queue.Contains -> HashQueue.Contains.

 

Version 1.06 du 16/10/2016

- Sauvegarde de la taille des colonnes ;

- Affichage de la taille des fichiers et dossiers parcourus (qui 'matchent' ou pas) : seulement lorsque l'on fait une recherche dans le contenu ; affichage aussi du nombre de dossiers parcourus (pour voir l'avancement) ;

DoEvents pour l'affichage des messages : inutile à priori ;

BackgroundWorker : option désactivable : inutile à priori.

 

Version 1.05 du 24/09/2016

- Attente lors de la première ouverture du bloc-notes (sinon le SendKeys ne marche pas du premier coup) ;

- Correction du chemin vers le bloc-notes, pour l'ensemble des versions de Windows (et vérification si l'exécutable est bien trouvé) ;

- Configuration des raccourcis clavier pour le bloc-notes (pour ouvrir les fichiers trouvés lorsque VBFileFind est utilisé sur un Windows en anglais par exemple).

 

Version 1.04 du 25/10/2015

- Filtre d'exclusion pour faire des recherches en excluant les fichiers avec certaines extensions.

- Passage en VB 2013.

 

Version 1.03 du 06/07/2014

Dédoublonnage des fichiers trouvés, au cas où les filtres de recherche soient redondants ;

- Passage en VB 2010, avec le DotNet 4.0.

 

Version 1.02 du 30/12/2012

- Correction de l'affichage du temps de recherche (cumul et non total de chaque unité de temps) ;

- Utilisation d'un BackgroundWorker au lieu d'un Thread : c'est plus simple (pas besoin de synchroniser) ; Une tache correspond à un seul sous-dossier et non à une arborescence (+ réactif), il suffit ensuite de rafraîchir souvent la barre d'information sur le fichier en cours, et moins souvent la liste des fichiers trouvés elle-même ;

- Tri des colonnes du résultat de la recherche, par exemple par date, par taille de fichier, ou par nom de fichier : SortableListView.

 

Version 1.01 du 21/11/2010 : Première version

Simplification du code source en C#:

- Pas de thread, et donc pas de synchronisation à faire : les délégués permettent de résoudre le problème classique du fait que seul le thread courant peut modifier les éléments de l'interface (en WinForm/DotNet) : ajouter un fichier trouvé (le code source d'origine en C# à été modifié depuis dans le même sens aussi, mais toujours en utilisant un thread secondaire). Avec un délégué, c'est bien toujours le thread d'origine qui effectue toutes les tâches, il suffit de laisser un DoEvents approprié pour ne pas figer l'interface. L'utilisation de la classe clsAfficherMsg se résume à une déclaration et un appel de fonction : il suffit ensuite de récupérer les événements, c'est tout !

 

Version d'origine en C# du 24/04/2010

- File Searcher in C#, By Manfred Bittersam | 24 Apr 2009

  A freeware file searcher in C#

  http://www.codeproject.com/KB/files/filesearcher.aspx

 

 

Liens

 

Voir aussi

 

- VBTextFinder : un moteur de recherche de mot dans son contexte

  http://patrice.dargenton.free.fr/CodesSources/VBTextFinder.html

 

- VBWinDiff : Interface d'options pour le comparateur WinDiff

  http://patrice.dargenton.free.fr/CodesSources/VBWinDiff.html