J'essaie de savoir comment lire/écrire dans les propriétés de fichier étendues en C #, par exemple. Commentaire, débit, date d'accès, catégorie, etc. que vous pouvez voir dans l'Explorateur Windows. Des idees pour faire cela? EDIT: Je vais principalement lire/écrire sur des fichiers vidéo (AVI/DIVX/...)
Pour ceux qui ne sont pas fous de VB, le voici en c #:
Notez que vous devez ajouter une référence à Microsoft Shell Controls and Automation à partir de l'onglet COM de la boîte de dialogue Références.
public static void Main(string[] args)
{
List<string> arrHeaders = new List<string>();
Shell32.Shell shell = new Shell32.Shell();
Shell32.Folder objFolder;
objFolder = Shell.NameSpace(@"C:\temp\testprop");
for( int i = 0; i < short.MaxValue; i++ )
{
string header = objFolder.GetDetailsOf(null, i);
if (String.IsNullOrEmpty(header))
break;
arrHeaders.Add(header);
}
foreach(Shell32.FolderItem2 item in objFolder.Items())
{
for (int i = 0; i < arrHeaders.Count; i++)
{
Console.WriteLine(
$"{i}\t{arrHeaders[i]}: {objFolder.GetDetailsOf(item, i)}");
}
}
}
Cet exemple dans VB.NET lit toutes les propriétés étendues:
Sub Main()
Dim arrHeaders(35)
Dim Shell As New Shell32.Shell
Dim objFolder As Shell32.Folder
objFolder = Shell.NameSpace("C:\tmp")
For i = 0 To 34
arrHeaders(i) = objFolder.GetDetailsOf(objFolder.Items, i)
Next
For Each strFileName In objfolder.Items
For i = 0 To 34
Console.WriteLine(i & vbTab & arrHeaders(i) & ": " & objfolder.GetDetailsOf(strFileName, i))
Next
Next
End Sub
Vous devez ajouter une référence à Microsoft Shell Controls and Automation à partir de l'onglet COM de Références dialogue.
Ajoutez les packages NuGet suivants à votre projet:
Microsoft.WindowsAPICodePack-Shell
par MicrosoftMicrosoft.WindowsAPICodePack-Core
par Microsoftusing Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
string filePath = @"C:\temp\example.docx";
var file = ShellFile.FromFilePath(filePath);
// Read and Write:
string[] oldAuthors = file.Properties.System.Author.Value;
string oldTitle = file.Properties.System.Title.Value;
file.Properties.System.Author.Value = new string[] { "Author #1", "Author #2" };
file.Properties.System.Title.Value = "Example Title";
// Alternate way to Write:
ShellPropertyWriter propertyWriter = file.Properties.GetPropertyWriter();
propertyWriter.WriteProperty(SystemProperties.System.Author, new string[] { "Author" });
propertyWriter.Close();
Important:
Le fichier doit être valide, créé par le logiciel spécifique attribué. Chaque type de fichier a des propriétés de fichier étendues spécifiques et toutes ne sont pas accessibles en écriture.
Si vous cliquez avec le bouton droit sur un fichier du bureau et que vous ne pouvez pas modifier une propriété, vous ne pourrez pas le modifier également dans le code.
Exemple:
Author
ou Title
.Donc, assurez-vous d'utiliser try
catch
Sujet supplémentaire: MSDN: Implementing Property Handlers
Merci les gars pour ce fil! Cela m'a aidé lorsque je voulais comprendre la version du fichier d'un exe. Cependant, je devais trouver moi-même le dernier bit de ce que l'on appelle les propriétés étendues.
Si vous ouvrez les propriétés d'un fichier exe (ou dll) dans l'Explorateur Windows, vous obtenez un onglet Version et une vue des propriétés étendues de ce fichier. Je voulais accéder à l'une de ces valeurs.
La solution à cela est l'indexeur de propriété FolderItem.ExtendedProperty et si vous supprimez tous les espaces du nom de la propriété, vous obtiendrez la valeur. Par exemple. La version du fichier va FileVersion, et voilà.
J'espère que cela aidera quelqu'un d'autre, je me suis dit que j'ajouterais cette information à ce fil. À votre santé!
GetDetailsOf()
Method - Récupère les détails d'un élément dans un dossier. Par exemple, sa taille, son type ou l'heure de sa dernière modification. Les propriétés du fichier peuvent varier en fonction du Windows-OS
version.
List<string> arrHeaders = new List<string>();
Shell shell = new ShellClass();
Folder rFolder = Shell.NameSpace(_rootPath);
FolderItem rFiles = rFolder.ParseName(filename);
for (int i = 0; i < short.MaxValue; i++)
{
string value = rFolder.GetDetailsOf(rFiles, i).Trim();
arrHeaders.Add(value);
}
Réponse de Jerker est un peu plus simple. Voici un exemple de code qui fonctionne de MS :
var folder = new Shell().NameSpace(folderPath);
foreach (FolderItem2 item in folder.Items())
{
var company = item.ExtendedProperty("Company");
var author = item.ExtendedProperty("Author");
// Etc.
}
Pour ceux qui ne peuvent pas référencer Shell32 de manière statique, vous pouvez l'invoquer dynamiquement de la manière suivante:
var shellAppType = Type.GetTypeFromProgID("Shell.Application");
dynamic shellApp = Activator.CreateInstance(shellAppType);
var folder = shellApp.NameSpace(folderPath);
foreach (var item in folder.Items())
{
var company = item.ExtendedProperty("Company");
var author = item.ExtendedProperty("Author");
// Etc.
}
Utilisation:
string propertyValue = GetExtendedFileProperty("c:\\temp\\FileNameYouWant.ext","PropertyYouWant");
Fonctionnera sur les versions Windows telles que Windows Server 2008 où vous obtiendrez l’erreur "Impossible de convertir un objet COM de type 'System .__ ComObject' en type d'interface 'Shell32.Shell'" si vous essayez simplement de créer le Shell32 Object normalement.
public static string GetExtendedFileProperty(string filePath, string propertyName)
{
string value = string.Empty;
string baseFolder = Path.GetDirectoryName(filePath);
string fileName = Path.GetFileName(filePath);
//Method to load and execute the Shell object for Windows server 8 environment otherwise you get "Unable to cast COM object of type 'System.__ComObject' to interface type 'Shell32.Shell'"
Type shellAppType = Type.GetTypeFromProgID("Shell.Application");
Object Shell = Activator.CreateInstance(shellAppType);
Shell32.Folder shellFolder = (Shell32.Folder)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, Shell, new object[] { baseFolder });
//Parsename will find the specific file I'm looking for in the Shell32.Folder object
Shell32.FolderItem folderitem = shellFolder.ParseName(fileName);
if (folderitem != null)
{
for (int i = 0; i < short.MaxValue; i++)
{
//Get the property name for property index i
string property = shellFolder.GetDetailsOf(null, i);
//Will be empty when all possible properties has been looped through, break out of loop
if (String.IsNullOrEmpty(property)) break;
//Skip to next property if this is not the specified property
if (property != propertyName) continue;
//Read value of property
value = shellFolder.GetDetailsOf(folderitem, i);
}
}
//returns string.Empty if no value was found for the specified property
return value;
}
Je ne suis pas sûr du type de fichiers pour lequel vous essayez d'écrire les propriétés, mais taglib-sharp est une excellente bibliothèque de balisage open source qui englobe toutes ces fonctionnalités. Il prend en charge de manière intégrée la plupart des types de fichiers multimédias les plus courants, mais vous permet également d'effectuer un balisage plus avancé avec à peu près tous les fichiers.
EDIT: J'ai mis à jour le lien vers taglib sharp. L'ancien lien ne fonctionnait plus.
EDIT: Une fois de plus, le lien a été mis à jour par le commentaire de kzu.
Voici une solution pour lire - et non pour écrire - les propriétés étendues en fonction de ce que j'ai trouvé sur cette page et sur aide sur les objets Shell32 .
Pour être clair c'est un bidouillage. Il semble que ce code fonctionnera toujours sous Windows 10 mais utilisera des propriétés vides. La version précédente de Windows devrait utiliser:
var i = 0;
while (true)
{
...
if (String.IsNullOrEmpty(header)) break;
...
i++;
Sous Windows 10, nous supposons qu’il existe environ 320 propriétés à lire et ignore simplement les entrées vides:
private Dictionary<string, string> GetExtendedProperties(string filePath)
{
var directory = Path.GetDirectoryName(filePath);
var Shell = new Shell32.Shell();
var shellFolder = Shell.NameSpace(directory);
var fileName = Path.GetFileName(filePath);
var folderitem = shellFolder.ParseName(fileName);
var dictionary = new Dictionary<string, string>();
var i = -1;
while (++i < 320)
{
var header = shellFolder.GetDetailsOf(null, i);
if (String.IsNullOrEmpty(header)) continue;
var value = shellFolder.GetDetailsOf(folderitem, i);
if (!dictionary.ContainsKey(header)) dictionary.Add(header, value);
Console.WriteLine(header +": " + value);
}
Marshal.ReleaseComObject(Shell);
Marshal.ReleaseComObject(shellFolder);
return dictionary;
}
Comme mentionné, vous devez faire référence à Com Assembly Interop.Shell32.
Si vous obtenez une exception liée à STA, vous trouverez la solution ici:
Exception lors de l'utilisation de Shell32 pour obtenir les propriétés étendues du fichier
Je n'ai aucune idée de ce que seraient ces noms de propriétés sur un système étranger et je ne pouvais pas trouver d'informations sur les constantes localisables à utiliser pour accéder au dictionnaire. J'ai également constaté que toutes les propriétés de la boîte de dialogue Propriétés n'étaient pas présentes dans le dictionnaire renvoyé.
En passant, cela est terriblement lent et - du moins sous Windows 10 - l’analyse des dates dans la chaîne extraite constituerait un défi; il semble donc que cette solution ne soit pas une bonne idée.
Sous Windows 10, vous devez absolument utiliser la bibliothèque Windows.Storage qui contient les propriétés SystemPhotoProperties, SystemMusicProperties, etc. https: //docs.Microsoft.com/en-us/windows/uwp/files/quickstart-getting-file- propriétés
Et enfin, j'ai posté une solution bien meilleure qui utilise WindowsAPICodePack là