在ASP.Net应用程序中调用非托管代码时获取受保护的内存异常

时间:2014-06-19 22:16:24

标签: c# asp.net .net access-violation

我从另一个StackOverflow答案中找到了一些代码,用于根据从文件的前几个字节读取的内容来发现文件的MIME类型。该代码引用外部DLL中的非托管方法。

[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
);

我调用此方法,返回一个IntPtr,并使用Marshal.PtrToStringUni读取存储在指定内存地址的字符串。

System.UInt32 mimetype = 0;
FindMimeFromData(0, null, buffer, maxBytes, null, 0, out mimetype, 0);
System.IntPtr mimeTypePtr = new IntPtr(mimetype);
string mime = Marshal.PtrToStringUni(mimeTypePtr);
Marshal.FreeCoTaskMem(mimeTypePtr);

请注意,maxBytes硬编码为256,缓冲区最多可容纳被检查文件的前256个字节。

调用Marshal.PtrToStringUni(mimeTypePtr)会抛出一个AccessViolationException,并显示消息"尝试读取或写入受保护的内存。这通常表明其他内存已损坏。"

逻辑在Windows窗体或控制台应用程序中使用时工作正常,因此似乎只有一些安全措施才适用于ASP.Net应用程序。有谁知道从ASP.Net调用这个非托管方法需要什么?我还想找到一种更好的方法来获取不涉及使用Windows注册表的文件的MIME类型。我在使用注册表时遇到了一些问题,我试图让它在我不能依赖注册表的那些时候作为故障转移工作。

1 个答案:

答案 0 :(得分:4)

在问题here的评论中实际解决了这个确切的情况。使用pinvoke.net上显示的FindMimeFromData方法的签名修复了我的问题。感谢@Rohland的原始评论,感谢@MikeHixson指出我正确的方向。