urlmon.dll FindMimeFromData()在64位桌面/控制台上运行良好,但在ASP.NET上生成错误
我正在创建一个实用程序库,以便在Web环境中的桌面环境中使用。
它包含我认为在我的应用程序中经常重复的几个function,包括通过其内容(而不是扩展名)获取文件的mime类型的实用程序。
我必须检查的文件是最常见的(jpg,png,pdf,txt)所以我选择使用外部方法FindMimeFromData
(上面的链接)
使用.NET,如何根据文件签名而不是扩展名找到文件的mime类型
该方法效果很好,除了两个不正确的mime类型的JPG( image/pjpg
)和PNG( image/x-png
)之外,通过在return语句之前进行检查很容易解决。
该库是为平台AnyCPU编译的,因为它必须以32位和64位安装在服务器/客户端上。
在桌面环境测试时,所有为x86和x64编译的应用程序都正常工作。
在测试ASP.NET应用程序(带有用于测试的http处理程序的空站点)时发生HRESULT类型的错误,调试器告诉我它无法提供进一步的信息。
经过一些测试配置,包括将池的身份更改为本地系统(没有结果),我已经确定了问题:
池应该允许32位应用程序(见上图)。
为什么?
它不应该加载我们现在的64位系统的dll urlmon.dll
?
这是一个很大的问题,因为FindMimeFromData
方法可以被任何地方调用到这个库中:
结果是,另一个实用程序方法调用此方法可能会抛出此exception,并且通过调试也很难跟踪问题。
任何想法/经验?
用于测试的操作系统
桌面:
- Windows 8 x64 – 有效
- Windows 7 x64 – 有效
- Windows Server 2008 Standard R2 x64 – 有效
- Windows Server 2008 Standard x86 – 有效
- Windows Server 2003 Standard x86 – 有效
- Windows XP Professional SP3 – 有效
url:
- Windows 8 x64 – 发现第一个错误,仅适用于启用32位应用程序
- Windows Server 2008 Standard R2 x64 – 确认错误,仅适用于启用32位应用程序
- Windows Server 2008 Standard x86 – 有效
编辑2(问题解决)
由Noseratio解决:
正确类型的参数ppwzMimeOut
和pBC
必须是System.IntPtr
而不是System.UInt32
。
我知道System.UInt32
会导致完整的64位网络应用程序出现问题,但我不知道为什么。
如果有人知道这些问题的原因,可以在评论中更好地解释一下吗?
提前致谢
如果您使用了链接的答案中的pinvoke签名,那么它的定义如下:
[DllImport(@"urlmon.dll", CharSet = CharSet.Auto)] private extern static System.UInt32 FindMimeFromData( System.UInt32 pBC, [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl, [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer, System.UInt32 cbSize, [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed, System.UInt32 dwMimeFlags, out System.UInt32 ppwzMimeOut, System.UInt32 dwReserverd );
我宁愿使用pinvoke.net的定义:
[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)] static extern int FindMimeFromData(IntPtr pBC, [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl, [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)] byte[] pBuffer, int cbSize, [MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed, int dwMimeFlags, out IntPtr ppwzMimeOut, int dwReserved);
请注意ppwzMimeOut
和pBC
参数的类型差异。 在前一种情况下, System.UInt32
不是64位平台下64位指针的正确类型。 对于pBC
,这可能不是问题(只要它是NULL),但它对ppwzMimeOut
很重要。
请参阅此实施 ,这似乎是正确的。