C# urlmon.dll FindMimeFromData()在64位桌面/控制台上运行良好,但在ASP.NET上生成错误
我正在创建一个实用程序库,用于桌面环境和web环境 它包含一些我认为在我的应用程序中经常重复的特性,包括通过文件内容(而不是扩展名)获取文件mime类型的实用程序 我需要检查的文件是最常见的(jpg、png、pdf、txt),因此我选择使用外部方法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编译的,因为它必须以
findmemefromdata
(上面的链接)
除了JPG(image/pjpg
)和PNG(image/x-PNG
)这两种不正确的mime类型之外,该方法工作得很好,只需在返回语句之前进行检查即可轻松解决
该库是为平台AnyCPU编译的,因为它必须以32位和64位安装在服务器/客户端上
在桌面环境上进行测试时,针对x86和x64编译的两个应用程序都能正常工作
在测试ASP.NET应用程序(带有http处理程序用于测试的空站点)时,发生类型为HRESULT的错误,调试器告诉我它无法提供进一步的信息
经过一些测试配置,包括将池的标识更改为本地系统(没有结果),我发现了问题:
池应该允许32位应用程序(参见上图)
为什么?
它不应该加载我们现在所在的64位系统的dllurlmon.dll
这是一个大问题,因为findmemefromdata
方法可以在库中的任何地方调用:
结果是,由另一个实用程序方法调用此方法可能会引发此异常,并使通过调试跟踪问题变得困难
有什么想法/经验吗
用于测试的操作系统
桌面:
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);