urlmon.dll FindMimeFromData()在64位桌面/控制台上完美工作,但在ASP.NET上产生错误

我正在创建一个用于Web环境中的桌面环境中的实用程序库。

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

IisAllow32BitApplication

为什么?

它不应该加载我们现在的64位系统的dll urlmon.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解决:

    ppwzMimeOutpBC的正确类型参数必须是System.IntPtr而不是System.UInt32

    我知道System.UInt32问题导入完整的64位Web应用程序,但我不知道为什么。

    如果有人知道这些问题的原因,可以在评论中更好地解释它?

    提前致谢


    如果您在链接的答案中使用了密码签名,那么它就是这样定义的:

    [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参数的类型差异。 在前一种情况下,对于64位平台下的64位指针, System.UInt32不是正确的类型。 对于pBC ,这可能不是问题(只要它是NULL),但它对ppwzMimeOut很重要。

    参考这个看起来是正确的实现。

    链接地址: http://www.djcxy.com/p/46919.html

    上一篇: urlmon.dll FindMimeFromData() works perfectly on 64bit desktop/console but generates errors on ASP.NET

    下一篇: Why does the FindMimeFromData function from Urlmon.dll return MIME type “application/octet