C# urlmon.dll FindMimeFromData()在64位桌面/控制台上运行良好,但在ASP.NET上生成错误

C# urlmon.dll FindMimeFromData()在64位桌面/控制台上运行良好,但在ASP.NET上生成错误,c#,32bit-64bit,dllimport,urlmon,C#,32bit 64bit,Dllimport,Urlmon,我正在创建一个实用程序库,用于桌面环境和web环境 它包含一些我认为在我的应用程序中经常重复的特性,包括通过文件内容(而不是扩展名)获取文件mime类型的实用程序 我需要检查的文件是最常见的(jpg、png、pdf、txt),因此我选择使用外部方法findmemefromdata(上面的链接) 除了JPG(image/pjpg)和PNG(image/x-PNG)这两种不正确的mime类型之外,该方法工作得很好,只需在返回语句之前进行检查即可轻松解决 该库是为平台AnyCPU编译的,因为它必须以

我正在创建一个实用程序库,用于桌面环境和web环境

它包含一些我认为在我的应用程序中经常重复的特性,包括通过文件内容(而不是扩展名)获取文件mime类型的实用程序

我需要检查的文件是最常见的(jpg、png、pdf、txt),因此我选择使用外部方法
findmemefromdata
(上面的链接)

除了JPG(
image/pjpg
)和PNG(
image/x-PNG
)这两种不正确的mime类型之外,该方法工作得很好,只需在返回语句之前进行检查即可轻松解决

该库是为平台AnyCPU编译的,因为它必须以32位和64位安装在服务器/客户端上

在桌面环境上进行测试时,针对x86和x64编译的两个应用程序都能正常工作

在测试ASP.NET应用程序(带有http处理程序用于测试的空站点)时,发生类型为HRESULT的错误,调试器告诉我它无法提供进一步的信息

经过一些测试配置,包括将池的标识更改为本地系统(没有结果),我发现了问题:

池应该允许32位应用程序(参见上图)

为什么?

它不应该加载我们现在所在的64位系统的dll
urlmon.dll

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

结果是,由另一个实用程序方法调用此方法可能会引发此异常,并使通过调试跟踪问题变得困难

有什么想法/经验吗

用于测试的操作系统

桌面:

  • Windows8x64-works
  • Windows 7 x64-works
  • Windows Server 2008标准R2 x64-正常工作
  • Windows Server 2008标准x86-工作正常
  • Windows Server 2003标准x86-工作正常
  • Windows XP Professional SP3-工作正常
  • 网站:

  • Windows 8 x64-发现第一个错误,仅在启用32位应用程序时有效
  • Windows Server 2008标准R2 x64-已确认错误,仅在启用32位应用程序的情况下工作
  • Windows Server 2008标准x86-工作正常
  • 编辑2(问题已解决)

    解决者:

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

    我知道
    System.UInt32
    会给64位的web应用程序带来问题,但我不知道为什么

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


    提前感谢

    如果您使用链接中的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
    );
    
    我宁愿使用以下定义:

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


    请参阅看似正确的

    这就是为什么对
    URLMon.dll
    like使用回退方法很好的原因。或者在你的情况下,完全支持Winista嘿伙计。。。在更改参数pBC和ppwzMimeOut的类型后,现在它可以在任何地方工作!非常感谢!没问题,很高兴有帮助:]顺便说一句,别忘了在
    ppwzMimeOut
    上调用
    Marshal.FreeCoTaskMem
    (如图所示),否则它会泄漏。
    [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);