Un collègue m’a soumis un problème intéressant :
Comment récupérer, depuis une application .NET, les informations inscrites dans les propriétés d’un fichier (bouton droit de la souris, menu propriété). Je précise bien, les propriétés système de fichier d’un fichier, et non pas les propriétés applicatives du fichier (propriétés d’un document Word, Excel ou PDF).
Un rapide coup d’œil sur le namespace System.IO montre que le Framework n’a rien pour gérer celaL. J’étends mes recherches et trouve rapidement que la clé se trouve dans l’objet COM Microsoft Shell Controls And Automation.
Je développe la solution, la test et peux la libellé « Work on my machine ». Test suivant : un poste utilisateur. Et là, malheur, problème d’interop sous .NET, la journée va être longue.
Après troubleshooting, le problème à été rapidement résolut :
Le poste de test ne reconnaissait pas l’interface IShellDispatch5, alors que le poste de développement oui ??? Le Shell n’estt donc pas identique sous XP que sous Vista L, alors que la Shell32.dll fait la même taille.
L’application .Net faisant référence à un objet COM, un wrapper est automatiquement crée par VS : Interop.Shell32.dll. J’ai crée cet Interop sur un poste XP et l’ai mis dans le répertoir de l’application .Net et celle-ci fonctionne comme une fleur autant sous XP que sous Vista !
Reste quelques questions sans réponses :
- Pourquoi cette erreur apparaît, même lorsque je force l’interface (cast) à IShellDispatch4 ?
- Lors de la création dynamique de l’objet COM (Activator.CreateInstance(…)), je ne peux pas invoquer les membres de l’objet (MethodInfo.invokMember(…))
Finalement, voici un exemple de code afin de récupérer la propriété Auteur :
IShellDispatch4 shellDispatch = (IShellDispatch4)new Shell32.ShellClass();
Folder folder = ((IShellDispatch4) shellDispatch).NameSpace(Path.GetDirectoryName(@"c:\\toto.txt"));
FolderItem folderItem = folder.ParseName(Path.GetFileName(@"c:\\toto.txt"));
// 0= le nom
// 1= La taille
// ...
// 9= l'auteur
// 11= objet
// 12= catégorie
return folder.GetDetailsOf(folderItem, 9);