c# - urlmon.dll FindMimeFromData() 在 64 位桌面/控制台上完美运行,但在 ASP.NET 上生成错误

标签 c# 32bit-64bit dllimport urlmon

我正在创建一个实用程序库,既可以在桌面环境中使用,也可以在网络环境中使用。

它包含几个我认为在我的应用程序中经常重复的功能,包括通过文件内容(而不是扩展名)获取文件的 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 位应用程序(见上图)。

IisAllow32BitApplication

为什么?

应该不会加载我们现在所在的64位系统的dllurlmon.dll吧?

这是一个大问题,因为 FindMimeFromData 方法可以在这个库中的任何地方调用:

结果是另一个实用程序方法调用此方法可能会抛出此异常,并且难以通过调试跟踪问题。

有什么想法/经验吗?

用于测试的操作系统

桌面:

  1. Windows 8 x64 - 工作
  2. Windows 7 x64 - 工作
  3. Windows Server 2008 Standard R2 x64 - 有效
  4. Windows Server 2008 Standard x86 - 有效
  5. Windows Server 2003 Standard x86 - 有效
  6. Windows XP Professional SP3 - 有效

网页:

  1. Windows 8 x64 - 发现第一个错误,仅适用于启用的 32 位应用程序
  2. Windows Server 2008 Standard R2 x64 - 已确认错误,仅适用于启用的 32 位应用程序
  3. Windows Server 2008 Standard x86 - 有效

编辑 2(问题已解决)

Noseratio 解决:

参数 ppwzMimeOutpBC 的正确类型必须是 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);

请注意 ppwzMimeOutpBC 参数的类型差异。在前一种情况下,System.UInt32 不是 64 位平台下 64 位指针的正确类型。对于 pBC,这可能不是问题(只要它为 NULL),但它对 ppwzMimeOut 很重要。

引用this implementation这似乎是正确的。

关于c# - urlmon.dll FindMimeFromData() 在 64 位桌面/控制台上完美运行,但在 ASP.NET 上生成错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18358548/

相关文章:

c# - Asmx Web 服务有时不会响应

将两个 32 位 float 转换为一个 64 位数字,反之亦然

c++ - 64 位与 32 位环境中 C++ 数组的大小

c# - 从 dll 构建 C# 项目

python - 导入 PyQt5 时 DLL 加载失败

function - 如何使用 GetProcAddress 函数调用 MessageBox?

c# - 处理窗体上所有控件的单击

c# - 在 nhibernate 中 Linq-ing 计算属性无法解析属性错误

c# - 如何从用户的机器上获取有用的 WPF .NET 错误信息?

performance - double 运算 : 32-bit vs 64-bit machines