Я пытаюсь выяснить, как читать/записывать расширенные свойства файла в С# например Комментарий, скорость передачи битов, доступ к дате, категорию и т.д., Которые вы можете увидеть в проводнике Windows. Есть идеи, как это сделать? EDIT: в основном я буду читать/записывать видеофайлы (AVI/DIVX/...)
Чтение/запись "Расширенные" свойства файла (С#)
Ответ 1
Для тех, кто не сумасшедший относительно VB, здесь он находится в С#:
Обратите внимание, что вы должны добавить ссылку на Microsoft Shell Controls и 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)}");
}
}
}
Ответ 2
Здесь статья CodeProject для чтения ID3. И поток на kixtart.org, который имеет больше информации для других свойств. В принципе, вам нужно вызвать метод GetDetailsOf()
в объекте оболочки папки для shell32.dll
.
Ответ 3
Этот образец в 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 и Automation со вкладки COM диалогового окна "Ссылки".
Ответ 4
Решение 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: реализация обработчиков свойств
Ответ 5
Спасибо, ребята, за эту тему! Это помогло мне, когда я хотел выяснить версию exe файла. Тем не менее, мне нужно было выяснить последний бит о том, что называется Extended Properties.
Если вы открываете свойства файла exe (или dll) в проводнике Windows, вы получаете вкладку "Версия" и представление "Расширенные свойства этого файла". Я хотел получить доступ к одному из этих значений.
Решением этого является индекс индексатора свойств FolderItem.ExtendedProperty, и если вы отбросите все пробелы в имени свойства, вы получите значение. Например. Версия файла идет FileVersion, и там у вас есть.
Надеюсь, это поможет кому-то еще, просто подумал, что я бы добавил эту информацию в эту тему. Ура!
Ответ 6
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);
}
Ответ 7
Ответ Джеркера немного проще. Здесь пример кода, который работает из 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.
}
Ответ 8
- Посмотрев на ряд решений по этой теме и в другом месте, был составлен следующий код. Это только для чтения свойства.
- Я не мог заставить рабочую оболочку Shell32.FolderItem2.ExtendedProperty работать, она должна принимать строковое значение и возвращать правильное значение и тип для этого свойства... это всегда было нулевым для меня, а ресурсы для разработчиков были очень тонкими.
- 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; }
Ответ 9
Я не уверен, какие типы файлов вы пытаетесь записать свойства, но taglib-sharp - отличная теги с открытым исходным кодом библиотека, которая прекрасно дополняет эту функциональность. Он имеет встроенную поддержку большинства популярных типов файлов мультимедиа, но также позволяет выполнять более расширенные тегирования практически с любым файлом.
EDIT: Я обновил ссылку на taglib sharp. Старая ссылка больше не работала.
EDIT: Обновлена ссылка еще раз за комментарий кзу.