我正在创建一个实用程序库,既可以在桌面环境中使用,也可以在网络环境中使用。
它包含几个我认为在我的应用程序中经常重复的功能,包括通过文件内容(而不是扩展名)获取文件的 MIME 类型的实用程序。
我必须检查的文件是最常见的(jpg、png、pdf、txt)所以我选择使用外部方法 FindMimeFromData
(上面的链接)
Using .NET, how can you find the mime type of a file based on the file signature not the extension
该方法很好用,除了JPG(image/pjpg
)和PNG(image/x-png
)两个不正确的mime类型外,很容易解决返回语句之前的检查。
该库是为 AnyCPU 平台编译的,因为它必须安装在 32 位和 64 位的服务器/客户端上。
在桌面环境中进行测试时,所有为 x86 和 x64 编译的应用程序都可以正常工作。
在测试 ASP.NET 应用程序(带有用于测试的 http 处理程序的空站点)时,发生了 HRESULT 类型的错误,调试器告诉我它无法提供更多信息。
经过一些测试配置,包括将池的身份更改为本地系统(没有结果),我发现了问题:
池应允许 32 位应用程序(见上图)。
为什么?
应该不会加载我们现在所在的64位系统的dllurlmon.dll
吧?
这是一个大问题,因为 FindMimeFromData
方法可以在这个库中的任何地方调用:
结果是另一个实用程序方法调用此方法可能会抛出此异常,并且难以通过调试跟踪问题。
有什么想法/经验吗?
用于测试的操作系统
桌面:
- 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 - 有效
网页:
- 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 位网络应用程序出现问题,但我不知道为什么。
如果有人知道这些问题的原因,可以在评论中更好地解释吗?
提前致谢
最佳答案
如果您使用了 answer 中的 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
很重要。
引用this implementation这似乎是正确的。
关于c# - urlmon.dll FindMimeFromData() 在 64 位桌面/控制台上完美运行,但在 ASP.NET 上生成错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18358548/