Cod*_*key 4 .net c# asp.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
);
Run Code Online (Sandbox Code Playgroud)
我调用这个方法,它返回一个 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);
Run Code Online (Sandbox Code Playgroud)
请注意,maxBytes 被硬编码为 256,缓冲区最多可容纳被检查文件的前 256 个字节。
调用 Marshal.PtrToStringUni(mimeTypePtr) 会引发 AccessViolationException,并显示消息“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”
该逻辑在 Windows 窗体或控制台应用程序中使用时运行良好,因此它似乎是一些仅适用于 ASP.Net 应用程序的安全措施。有谁知道从 ASP.Net 调用这个非托管方法需要什么?我还想找到一种更好的方法来派生文件的 MIME 类型,而不涉及使用 Windows 注册表。我在使用注册表时遇到了一些问题,我试图让它在我不能依赖注册表的时候作为故障转移工作。
这个确切的情况是实际中的问题的注释来解决这里。使用上显示的FindMimeFromData方法的签名pinvoke.net固定我的问题。感谢@Rohland 的原始评论和@MikeHixson 为我指明了正确的方向。