Чтение / запись расширенных свойств файла (C #) - PullRequest
94 голосов
/ 21 октября 2008

Я пытаюсь выяснить, как читать / записывать в расширенные свойства файла в C # например Комментарий, битрейт, дата обращения, категория и т. Д., Которые вы можете увидеть в проводнике Windows. Есть идеи, как это сделать? РЕДАКТИРОВАТЬ: Я буду в основном читать / писать в видеофайлах (AVI / DIVX /...)

Ответы [ 9 ]

78 голосов
/ 19 января 2010

Для тех, кто не без ума от VB, вот он в c #:

Обратите внимание, что вы должны добавить ссылку на Microsoft Shell Controls and Automation на вкладке 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)}");
        }
    }
}
27 голосов
/ 21 октября 2008

Есть статья CodeProject для читателя ID3. И поток на kixtart.org , который содержит больше информации для других свойств. По сути, вам нужно вызвать GetDetailsOf() метод для папки объекта оболочки для shell32.dll.

24 голосов
/ 28 ноября 2008

Этот пример в 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 Controls and Automation на вкладке COM диалогового окна Ссылки .

23 голосов
/ 23 июня 2016

Решение 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: Реализация обработчиков свойств

8 голосов
/ 27 февраля 2013

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);
 }
8 голосов
/ 23 августа 2010

Спасибо, ребята за эту ветку! Это помогло мне, когда я хотел выяснить версию файла exe. Тем не менее, мне нужно было самостоятельно выяснить, что называется расширенными свойствами.

Если вы откроете свойства exe (или dll) файла в проводнике Windows, вы получите вкладку Version и просмотр расширенных свойств этого файла. Я хотел получить доступ к одному из этих значений.

Решением этой проблемы является индексатор свойства FolderItem.ExtendedProperty, и если вы удалите все пробелы в имени свойства, вы получите значение. Например. Версия файла идет FileVersion, и там у вас есть.

Надеюсь, это кому-нибудь еще поможет, просто подумал, что я добавлю эту информацию в эту ветку. Ура!

4 голосов
/ 09 октября 2017

ответ Джеркера немного проще. Вот пример кода, который работает от 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.
}
3 голосов
/ 23 апреля 2018
  • После просмотра ряда решений в этой теме и в других местах следующий код был составлен. Это только для чтения свойства.
  • Я не мог получить Shell32.FolderItem2.ExtendedProperty функция для работы, как предполагается, взять строковое значение и вернуть правильное значение и тип для этого свойство ... это всегда было для меня пустым, а справочные ресурсы для разработчиков были очень тонкими.
  • WindowsApiCodePack кажется был заброшен Microsoft, что приводит нам код ниже.

Использование:

string propertyValue = GetExtendedFileProperty("c:\\temp\\FileNameYouWant.ext","PropertyYouWant");
  1. Вернет вам значение расширенного свойства, которое вы хотите, как строка для данного файла и имени свойства.
  2. Только зацикливается, пока не найдет указанное свойство - не до все свойства обнаруживаются как пример кода
  3. Будет работать в версиях 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;
    }
    
1 голос
/ 21 октября 2008

Я не уверен, для каких типов файлов вы пытаетесь написать свойства, но taglib-sharp - это отличная библиотека тегов с открытым исходным кодом, которая прекрасно сочетает в себе все эти функции. Он имеет встроенную поддержку для большинства популярных типов медиафайлов, но также позволяет выполнять более сложные теги практически для любого файла.

РЕДАКТИРОВАТЬ: Я обновил ссылку на Taglib Sharp. Старая ссылка больше не работает.

РЕДАКТИРОВАТЬ: Обновил ссылку еще раз для комментария кзу.

...