Чтение / запись 'расширенные' свойства файла (C#)
Я пытаюсь узнать, как читать / писать в расширенные свойства файла в C# например, комментарий, скорость передачи данных, Дата доступа, категория и т. д., которые вы можете увидеть в проводнике Windows. Есть идеи, как это сделать? EDIT: я буду в основном читать / писать в видеофайлы (AVI / DIVX/...)
9 ответов:
для тех, кто не без ума от VB, вот он в c#:
Примечание, Вы должны добавить ссылку на Microsoft Shell управления и автоматизации на вкладке COM диалогового окна ссылки.
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)}"); } } }
здесь статья CodeProject для чтения ID3. И резьба на kixtart.org это имеет больше информации для других свойств. В принципе, вам нужно позвонить
GetDetailsOf()
метод на папку объект оболочки дляshell32.dll
.
этот пример в VB.NET читает все расширенные свойства:
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
вы должны добавить ссылку Microsoft Shell управления и автоматизации С COM на ссылки диалог.
решение 2016
добавьте следующие пакеты NuGet в свой проект:
Microsoft.WindowsAPICodePack-Shell
компания MicrosoftMicrosoft.WindowsAPICodePack-Core
компания Microsoftчтение и запись свойств
using 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();
важно:
файл должен быть действительным, созданные определенным программным обеспечением. Каждый тип файла имеет определенные расширенные свойства файла, и не все из них доступны для записи.
если вы щелкните правой кнопкой мыши файл на рабочем столе и не можете редактировать свойство, вы не сможете редактировать его в коде тоже.
пример:
- создать txt файл на рабочем столе, переименовать его расширение в docx. Вы не можете отредактируйте его
Author
илиTitle
собственность.- откройте его с помощью Word, редактировать и сохранять оно. Теперь можешь.
так что просто убедитесь, что использовать некоторые
try
catch
Далее Тему: MSDN: реализация свойства Обработчики
спасибо вам ребята за эту тему! Это помогло мне, когда я хотел выяснить версию файла exe. Однако мне нужно было выяснить последний бит того, что называется расширенными свойствами.
Если вы откроете свойства exe (или dll) файла в Проводнике Windows, вы получите вкладку версия и представление расширенных свойств этого файла. Я хотел получить доступ к одному из этих значений.
решением этой проблемы является свойство indexer FolderItem.ExtendedProperty и если вы упадете все пробелы в имени свойства, вы получите значение. Например, версия файла идет FileVersion, и там у вас есть это.
надеюсь, это поможет кому-нибудь еще, просто подумал, что я добавлю эту информацию в эту тему. Ура!
GetDetailsOf()
метод-извлекает сведения об элементе в папке. Например, его размер, тип или время последнего изменения. Свойства файла могут отличаться в зависимости отWindows-OS
версия.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); }
плачем все немного проще. Вот пример кода, который работает от MS:
var folder = new Shell().NameSpace(folderPath); foreach (FolderItem2 item in folder.Items()) { var company = item.ExtendedProperty("Company"); var author = item.ExtendedProperty("Author"); // Etc. }
для тех, кто не может ссылаться на shell32 статически, вы можете вызвать его динамически следующим образом:
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. }
- после просмотра ряда решений в этой теме и в других местах следующий код был собран вместе. Это только для чтения свойства.
- Я не мог получить Заshell32.FolderItem2.Предполагается, что функция ExtendedProperty будет работать чтобы взять строковое значение и вернуть правильное значение и тип для этого свойство... это всегда было null для меня, и справочные ресурсы разработчика были очень тонкими.
- The WindowsApiCodePack кажется были оставленный Microsoft, который приносит нам код ниже.
использование:
string propertyValue = GetExtendedFileProperty("c:\temp\FileNameYouWant.ext","PropertyYouWant");
- вернет вам значение расширенного свойства, которое вы хотите в качестве строка для данного файла и имени свойства.
- только петли, пока он не нашел указанное свойство - не до все свойства обнаруживаются как некоторый пример кода
будет работать на версиях Windows, как Windows server 2008, где вы получите ошибку "не удается привести COM-объект типа System.__ComObject 'to interface type' Shell32.Оболочка'" если просто пытается создать объект Shell32 нормально.
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; }
Я не уверен, какие типы файлов вы пытаетесь написать свойства, но taglib-sharp это отличная библиотека тегов с открытым исходным кодом, которая прекрасно обертывает всю эту функциональность. Он имеет много встроенной поддержки для большинства популярных типов файлов мультимедиа, но также позволяет вам делать более продвинутые теги с почти любым файлом.
EDIT: я обновил ссылку на taglib sharp. Старой ссылки больше нет работал.
EDIT: обновил ссылку Еще раз за комментарий КЗУ.