Чтение / запись 'расширенные' свойства файла (C#)


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

9 88

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, редактировать и сохранять оно. Теперь можешь.

так что просто убедитесь, что использовать некоторые trycatch

Далее Тему: 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");
  1. вернет вам значение расширенного свойства, которое вы хотите в качестве строка для данного файла и имени свойства.
  2. только петли, пока он не нашел указанное свойство - не до все свойства обнаруживаются как некоторый пример кода
  3. будет работать на версиях 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: обновил ссылку Еще раз за комментарий КЗУ.