0

I am trying to read and write audio file properties and managed to do so with ShellFile.Properties.GetProperty and ShellFile.Properties.GetPropertyWriter(). The writer accepts string variables for both text (Album Title) and string objects (Contributing Artists) properties. I can read the string properties but string objects result with "System.String[]" instead of values inside.

My code:

using Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
    private void GetData()
    {
        string filePath = "E:\\mySong.mp3";
    
        var shellFile = ShellFile.FromParsingName(filePath);
    
        txtAlbum.Text = shellFile.Properties.GetProperty(SystemProperties.System.Music.AlbumTitle).ValueAsObject.ToString();
        txtArtist.Text = shellFile.Properties.GetProperty(SystemProperties.System.Music.AlbumArtist).ValueAsObject.ToString();
        txtArtists.Text = (string)shellFile.Properties.GetProperty(SystemProperties.System.Music.Artist).ValueAsObject;
      }

How can I read the content of those properties?

bbProg
  • 7
  • 2

2 Answers2

1

Two main things:

  1. When you're capturing these properties, be sure to account for null. So for AlbumTitle and AlbumArtist you can do this:
string albumTitle = shellFile.Properties.GetProperty(SystemProperties.System.Music.AlbumTitle).ValueAsObject?.ToString() ?? "Unknown";
string albumArtist = shellFile.Properties.GetProperty(SystemProperties.System.Music.AlbumArtist).ValueAsObject?.ToString() ?? "Unknown";
  1. The type of the Artist property in the COM object is multivalue string (reference). This, you can cast to a string array in C#:
string[] artist = (string[])(shellFile.Properties.GetProperty(SystemProperties.System.Music.Artist).ValueAsObject ?? new [] {"Unknown"});

I hope that helps!

Mike Bruno
  • 600
  • 2
  • 9
  • 26
0

As mentioned in the comments, try casting the text1.Text to string.

text1.Text = (string)shellFile.Properties.GetProperty(SystemProperties.System.Music.Artist).ValueAsObject.ToString();

If that doesn't work, you may need to use Reflection and GetValue() to pull the values out directly from the string array. I think using something like:

text1.Text = (string)shellFile.Properties.GetProperty(SystemProperties.System.Music.Artist).GetValue();

link to similar answer: How to get values from object in c#

link to Reflections GetValue(): https://learn.microsoft.com/en-us/dotnet/api/system.reflection.propertyinfo.getvalue?view=net-7.0

link to stuff about media files: https://learn.microsoft.com/en-us/windows/win32/medfound/metadata-properties-for-media-files?redirectedfrom=MSDN

west
  • 36
  • 1
  • 8
  • Thanks! I've been struggling with this for almost a week and nothing I found works. Your suggestion produce the error: System.InvalidCastException HResult=0x80004002 Message=Unable to cast object of type 'System.String[]' to type 'System.String'. – bbProg Aug 02 '23 at 17:22
  • I just tweaked the answer, but I think you need to use the .GetValue(). This link has an example. I am trying to formulate your code to work, but without more of your code I am struggling a bit. It looks like the problem is that GetProperty is returning the string array object and you need to then access the data within it. That is why you got that error, you ToString-ed the object so it returned "stytem.string[]". – west Aug 02 '23 at 17:33
  • https://learn.microsoft.com/en-us/dotnet/api/system.reflection.propertyinfo.getvalue?view=net-7.0 – west Aug 02 '23 at 17:33
  • Would it be -> text1.Text = shellFile.Properties.GetProperty(SystemProperties.System.Music).GetValue(Artist); ? – west Aug 02 '23 at 17:37
  • One last thought, I feel like the first answer in this one might have what you need: https://stackoverflow.com/questions/8631546/get-property-value-from-c-sharp-dynamic-object-by-string-reflection Something like: var shellFile = ShellFile.FromParsingName(filePath); var propertyInfo = shellFile.Properties.GetProperty(SystemProperties.System.Music); var artists = propertyInfo.GetValue(Artist); Or something like that. The second solution iterates through the property, so see if you can do something like that as well. – west Aug 02 '23 at 17:40
  • I'll take a look at it. I just updated my code, it's very simple as I'm still trying to make it work before I continue further. – bbProg Aug 02 '23 at 17:48
  • Tried also this one in a few variations, but still not working. The code you suggested raises 2 errors: 1. 'SystemProperties.System.Music' is a type, which is not valid in the given context 2. The name 'Artist' does not exist in the current context – bbProg Aug 02 '23 at 18:03