0

I am attempting to get the metadata from a few music files and failing miserably. Online, there seems to be absolutely NO HOPE in finding an answer; no matter what I google. I thought it would be a great time to come and ask here because of this.

The specific error I got was: Error HRESULT E_FAIL has been returned from a call to a COM component. I really wish I could elaborate on this issue, but I'm simply getting nothing back from the COMException object. The error code was -2147467259, and it in hex is -0x7FFFBFFB, and Microsoft have not documented this specific error.

I 70% sure that its not the file's fault. My code will run through a directory full of music and convert the file into a song, hence the ConvertFileToSong name. The function would not be running if the file were to not exist is what I'm trying to say.

The only thing I can really say is that I'm using Dotnet 6, and have a massive headache.

Well, I guess I could also share another problem I had before this error showed up. Dotnet6 has top level code or whatever its called, this means that I can't add the [STAThread] attribute. To solve this, I simply added the code bellow to the top. Not sure why I have to set it to unknown, but that's what I (someone else on Stack Overflow) have to do. That solved that previous problem that the Shell32 could not start, but could that be causing my current problem? Who knows... definitely not me.

Thread.CurrentThread.SetApartmentState(ApartmentState.Unknown);
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);

Here is the code:

        // Help from: https://stackoverflow.com/questions/37869388/how-to-read-extended-file-properties-file-metadata
        public static Song ConvertFileToSong(FileInfo file)
        {
            Song song = new Song();

            List<string> headers = new List<string>();

            // initialise the windows shell to parse attributes from
            Shell32.Shell shell = new Shell32.Shell();
            Shell32.Folder objFolder = null;

            try 
            {
                objFolder = shell.NameSpace(file.FullName); 
            }
            catch (COMException e) 
            {
                int code = e.ErrorCode;
                string hex = code.ToString();
                Console.WriteLine("MESSAGE: " + e.Message + ", CODE: " + hex);

                return null;
            }

            Shell32.FolderItem folderItem = objFolder.ParseName(file.Name);

            // the rest of the code is not important, but I'll leave it there anyway


            // pretty much loop infinetly with a counter better than
            // while loop because we don't have to declare an int on a new
            // line
            for (int i = 0; i < short.MaxValue; i++)
            {
                string header = objFolder.GetDetailsOf(null, i);

                // the header does not exist, so we must exit
                if (String.IsNullOrEmpty(header)) break;

                headers.Add(header);
            }

            // Once the code works, I'll try and get this to work
            song.Title = objFolder.GetDetailsOf(folderItem, 0);

            return song;
        }

Good night,

Diseased Finger

Diseased Finger
  • 107
  • 2
  • 9
  • *"Dotnet6 has top level code or whatever its called, this means that I can't add the [STAThread] attribute"*. You can choose whether to use top-level statements or not when you create the project. – jmcilhinney Oct 16 '22 at 08:55
  • Have you tried this in a .NET Framework project to see whether it behaves the same way? – jmcilhinney Oct 16 '22 at 08:55
  • Hi @jmcilhinney, I just tried using .NET framework as you said and it worked? Could I please ask... Why? – Diseased Finger Oct 19 '22 at 02:43
  • I'm not sure but that something works against .NET Framework and not .NET Core is useful information in diagnosing the problem. I'll have a closer look when I get the chance but not yet. – jmcilhinney Oct 19 '22 at 03:09
  • Hi again @jmcilhinney. I've been diving in a bit more into the problem, and it seems to be something wrong with the strings themselves. – Diseased Finger Oct 19 '22 at 03:16
  • (sorry for the replies @jmcilhinney , I keep pressing enter by accident). By "something wrong with the strings," I mean that when I use FileInfo.FullName, it throws a bunch of errors. But when I place the directory in a string object, it seems to work fine. And no, I can't just use `string dir = fileInfoObject.FullName` sadly. – Diseased Finger Oct 19 '22 at 03:18
  • Ok I fixed it... and as usual... it was simple. For `objFolder = shell.NameSpace(file.FullName`, I changed `file.FullName` to... watch this... `file.DirectoryName`! Wow! Who would have thought? If only I had eyes. Anyway, thanks for the help anyway. – Diseased Finger Oct 19 '22 at 03:31

1 Answers1

0

Ok, so the solution isn't that hard. I used file.FullName which includes the file's name, but Shell32.NameSpace ONLY requires the directory name (discluding the file name).

This is the code that fixed it:

        public static Song ConvertFileToSong(FileInfo file)
        {
            // .....

            Shell32.Shell shell = new Shell32.Shell();
            Shell32.Folder objFolder = file.DirectoryName;
            Shell32.FolderItem folderItem = objFolder.ParseName(file.Name);

            // .....

            return something;
        }
Diseased Finger
  • 107
  • 2
  • 9