通过 Windows API 代码包获取包含 unicode 字符的元数据时应用程序崩溃

Application crashes when getting metadata containing unicode character via Windows API Code Pack

我有一个 ASP.NET MVC 应用程序需要从图像文件中提取某些元数据。我目前正在使用 Windows API 代码包来执行以下操作:

var imageShellObject = ShellObject.FromParsingName(filePath);
var title = imageShellObject.Properties.System.Title;

本地,在我的电脑上,这工作正常:它得到一个包含文件标题 属性 的字符串,正如预期的那样。然而,部署到 Web 服务器后,如果 w3wp.exe 尝试获取的 属性 包含 LINE SEPARATOR (U+2028) 或 LATIN SMALL 等 unicode 字符,则 w3wp.exe 会在到达第二行代码时崩溃字母索恩 (U+00FE)。我无法捕获异常,因此无法确定问题所在,更糟糕的是,我无法优雅地失败:IIS 进程立即崩溃。在服务器上,这会弹出标准 Visual Studio Just-In-Time 调试器对话框,说明

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.

Windows 错误日志也不显示有关错误的任何详细信息,它仅显示模块 propsys.dll、[=30] 在 w3wp.exe 中发生的一些应用程序错误=] 和 KERNELBASE.DLL.

奇怪的是,如果我在本地 运行 应用程序,它使用同一个文件就可以正常工作。我的印象是服务器缺少一些 Unicode-related 东西,但我无法想象为什么在服务器上的资源管理器中查看文件属性显示这些 un​​icode 字符就好了。

这是怎么回事?

我已经设法找到问题并解决了问题,所以我把它留给后代:

问题出在 Windows API 代码包对 IShellItem2.GetProperty() 的互操作调用中。该方法有一个PropVariant类型的out方法,在代码包的Core项目中定义为MS.WindowsAPICodePack.Internal.PropVariant。此类型表示 OLE 结构 PROPVARIANT。

PropVariant 有一个用 FieldOffsetAttribute 修饰的 IntPtr 字段 _ptr2,指定偏移量为 12。这是不正确的:它应该是 16。

代码包的 GitHub 页面上有一个 Pull Request (https://github.com/aybe/Windows-API-Code-Pack-1.1/pull/5) 修复了这个问题。遗憾的是,该代码包显然已被其唯一的贡献者放弃,因此看起来并没有合并任何拉取请求。我最终应用了修复程序并将代码打包为私有 nuget 服务器上的新 NuGet 包。