Read/Write 'Extended' File Properties (C#)

Read/Write 'Extended' file properties (C#)

For those of not crazy about VB, here it is in c#:

Note, you have to add a reference to Microsoft Shell Controls and Automation from the COM tab of the References dialog.

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)}");
}
}
}

How to set extended file properties?

Add following NuGet packages to your project:

  • Microsoft.WindowsAPICodePack-Shell by Microsoft
  • Microsoft.WindowsAPICodePack-Core by Microsoft

Read and Write Properties

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();

Important:

The file must be a valid one, created by the specific assigned software. Every file type has specific extended file properties and not all of them are writable.

If you right-click a file on desktop and cannot edit a property, you wont be able to edit it in code too.

Example:

  • Create txt file on desktop, rename its extension to docx. You can't
    edit its Author or Title property.
  • Open it with Word, edit and save
    it. Now you can.

So just make sure to use some try catch

Further Topic:
MS Docs: Implementing Property Handlers

How to read extended file properties / file metadata

If you want to access more file metadata then the .NET framework provides ootb, I guess you need to use a third party library.
Otherwise you need to write your own COM wrapper to access those details.

See this link for a pure C# sample.

Here an example how to read the properties of a file:

Add Reference to Shell32.dll from the "Windows/System32" folder to
your project

List<string> arrHeaders = new List<string>();
List<Tuple<int, string, string>> attributes = new List<Tuple<int, string, string>>();

Shell32.Shell shell = new Shell32.Shell();
var strFileName = @"C:\Users\Admin\Google Drive\image.jpg";
Shell32.Folder objFolder = shell.NameSpace(System.IO.Path.GetDirectoryName(strFileName));
Shell32.FolderItem folderItem = objFolder.ParseName(System.IO.Path.GetFileName(strFileName));


for (int i = 0; i < short.MaxValue; i++)
{
string header = objFolder.GetDetailsOf(null, i);
if (String.IsNullOrEmpty(header))
break;
arrHeaders.Add(header);
}

// The attributes list below will contain a tuple with attribute index, name and value
// Once you know the index of the attribute you want to get,
// you can get it directly without looping, like this:
var Authors = objFolder.GetDetailsOf(folderItem, 20);

for (int i = 0; i < arrHeaders.Count; i++)
{
var attrName = arrHeaders[i];
var attrValue = objFolder.GetDetailsOf(folderItem, i);
var attrIdx = i;

attributes.Add(new Tuple<int, string, string>(attrIdx, attrName, attrValue));

Debug.WriteLine("{0}\t{1}: {2}", i, attrName, attrValue);
}
Console.ReadLine();

You can enrich this code to create custom classes and then do sorting depending on your needs.

There are many paid versions out there, but there is a free one called WindowsApiCodePack

For example accessing image metadata, I think it supports

ShellObject picture = ShellObject.FromParsingName(file);

var camera = picture.Properties.GetProperty(SystemProperties.System.Photo.CameraModel);
newItem.CameraModel = GetValue(camera, String.Empty, String.Empty);

var company = picture.Properties.GetProperty(SystemProperties.System.Photo.CameraManufacturer);
newItem.CameraMaker = GetValue(company, String.Empty, String.Empty);

Reading extended file properties with .NET Core

I don't think these are file attributes. I guess, it is MP3 metadata stored in ID3 tags.

You are using .NET Framework NuGet package WindowsAPICodePack-Shell that can read such metadata.

Option #1

I couldn't find a .NET Core version of the original package.
But I found an unofficial .NET Core fork of the library: Microsoft-WindowsAPICodePack-Shell (it's not authored by Microsoft).

Option #2

For .NET Core you can install the TagLibSharp NuGet package.
And then you just read metadata like this:

var file = new FileInfo("track.mp3");
var tagLibFile = TagLib.File.Create(file.Name);
var title = tagLibFile.Tag.Title;
var album = tagLibFile.Tag.Album;
var albumArtist = tagLibFile.Tag.AlbumArtists;
var genres = tagLibFile.Tag.JoinedGenres;
var length = tagLibFile.Properties.Duration;

.NET: How to set extended file attributes in a cross-platform way?

There is no API (yet). Here's my proposal to add it: https://github.com/dotnet/runtime/issues/49604

Write file extended property Revision Number on all type of files

This information is stored in properties. Here are some of the standard properties. I'm not sure if the .NET Framework provides a wrapper around these interfaces, though.

Read 'Extended' file properties (C++)

Here is some sample code from Microsoft for reading/writing file properties. It's using the WinAPI to read the file properties.

You can find a list of available properties here.

Depending on what you want to do, you may also take a look at these PROPVARIANT functions. For example, when you want to store the value of a property into a string.



Related Topics



Leave a reply



Submit