Чтение / запись "расширенных" свойств файла (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
компания Microsoft -
Microsoft.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, вы получаете вкладку версия и представление расширенных свойств этого файла. Я хотел получить доступ к одной из этих ценностей.
решением этого является индексатор свойств 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, а справочные ресурсы разработчика были очень тонкими.
- на WindowsApiCodePack кажется быть оставленный Microsoft, который приносит нам код ниже.
использование:
string propertyValue = GetExtendedFileProperty("c:\temp\FileNameYouWant.ext","PropertyYouWant");
- вернет вам значение расширенного свойства, которое вы хотите в качестве строка для данного файла и имени свойства.
- только петли, пока он не нашел указанное свойство-не до все свойства обнаруживаются как некоторый пример кода
-
будет работать на версиях Windows, таких как Windows server 2008, где вы получите ошибку " невозможно бросить COM-объект типа System.__ComObject "к интерфейсу типа" Заshell32.Shell'" если просто пытаюсь создать За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: обновил ссылку Еще раз за комментарий kzu.