I have an ASP.NET MVC application that needs to extract certain metadata from image files. I'm currently using the Windows API Code Pack to do this as follows:
var imageShellObject = ShellObject.FromParsingName(filePath);
var title = imageShellObject.Properties.System.Title;
Locally, on my pc, this works fine: it gets a string containing the file's Title property, as expected. Deployed to the web server, however, w3wp.exe crashes when it reaches that second line of code, if the property it is trying to get contains a unicode character like LINE SEPARATOR (U+2028) or LATIN SMALL LETTER THORN (U+00FE). I have no way of catching an exception, so I can't determine what the problem is, and worse, I can't fail gracefully: the IIS process simply crashes immediately. On the server, this pops up the standard Visual Studio Just-In-Time Debugger dialog stating
An unhandled win32 exception occurred in w3wp.exe [3708]. Just-In-Time debugging this exception failed with the following error: No installed debugger has Just-In-Time debugging enabled. In Visual Studio, Just-In-Time debugging can be enabled from Tools/Options/Debugging/Just-In-Time. Check the documentation index for 'Just-in-time debugging, errors' for more information.
The Windows Error Log doesn't show any details about the error either, it just displays a number of Application Errors occurring in w3wp.exe for modules propsys.dll, combase.dll and KERNELBASE.DLL.
The weird thing is that if I run the application locally, it works just fine using the same file. I get the impression that the server is missing some Unicode-related stuff, but I can't imagine why since looking at the file properties in explorer on the server displays those unicode characters just fine.
What's going on here?
I've managed to track down the issue and a fix, so I'm leaving this here for future generations:
The issue was in the Windows API Code Pack's interop call to IShellItem2.GetProperty(). This method has an out method of type PropVariant, which is defined as MS.WindowsAPICodePack.Internal.PropVariant in the code pack's Core project. This type represents the OLE struct PROPVARIANT.
PropVariant has an IntPtr field _ptr2 that's decorated with the FieldOffsetAttribute, specifying the offset as 12. This is incorrect: it should be 16.
There's a Pull Request (https://github.com/aybe/Windows-API-Code-Pack-1.1/pull/5) on the code pack's GitHub page that fixes this issue. Sadly, the code pack is apparently abandoned by its only contributor, so it doesn't look like any pull requests are getting merged. I ended up applying the fix and packing the code pack up as a new NuGet package on a private nuget server.