使用自定义IDownloadManager从WebBrowser控件访问AccessViolationException

我的.NET应用程序托管了一个WebBrowser控件,并且我附加了一个自定义下载管理器。 除了具有以下两个HTTP标头的请求之外,一切似乎都能正常工作:

Content-Type: application/octet-stream Content-Disposition: attachment; filename=blahblahblah 

更改或省略内容类型标题,一切正常; 它只是具有问题的application / octet-stream。 删除内容处置标头,不使用下载管理器。

有趣的是,这个问题只发生在32位机器上(我测试过XP和Win 7 32位.Win 7/8 64位不会崩溃)。

application/octet-stream什么特别之处?

如果它有帮助,这里有大量代码注册自定义下载管理器。 它的灵感来自于这个问题和答案: Windows Forms Webbrowswer控件与IDownloadManager

在我的类中,派生自WebBrowser

 protected override WebBrowserSiteBase CreateWebBrowserSiteBase() { var site = new DownloadWebBrowserSite(this); return site; } 

DownloadWebBrowserSite

  DownloadManager _manager = new DownloadManager(); public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject) { if (guidService.CompareTo(ComInteropConstants.IID_IDownloadManager) == 0 && riid.CompareTo(ComInteropConstants.IID_IDownloadManager) == 0) { IntPtr punk = Marshal.GetIUnknownForObject(_manager); return Marshal.QueryInterface(punk, ref riid, out ppvObject); } ppvObject = IntPtr.Zero; return ComInteropConstants.E_NOINTERFACE; } 

DownloadManager是我的自定义下载管理器。 它的Download实现如下。

 public int Download(IMoniker pmk, IBindCtx pbc, uint dwBindVerb, int grfBINDF, IntPtr pBindInfo, string pszHeaders, string pszRedir, uint uiCP) { return ComInteropConstants.S_OK; } 

它实现了IDownloadManager ,如下所示。

 [ComVisible(false), ComImport] [Guid("988934A4-064B-11D3-BB80-00104B35E7F9")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDownloadManager { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int Download( [In, MarshalAs(UnmanagedType.Interface)] IMoniker pmk, [In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc, [In, MarshalAs(UnmanagedType.U4)] uint dwBindVerb, [In] int grfBINDF, [In] IntPtr pBindInfo, [In, MarshalAs(UnmanagedType.LPWStr)] string pszHeaders, [In, MarshalAs(UnmanagedType.LPWStr)] string pszRedir, [In, MarshalAs(UnmanagedType.U4)] uint uiCP); } 

为了重现崩溃,我不需要在该方法中实际执行任何操作。

我仍然不完全理解为什么我的应用程序崩溃,也不完全理解为什么下面的代码修复它,但这里最终防止了崩溃:

 [DllImport("urlmon.dll"), PreserveSig] [return: MarshalAs(UnmanagedType.Error)] static extern int CoInternetSetFeatureEnabled(int FeatureEntry, [In, MarshalAs(UnmanagedType.U4)]uint dwFlags, bool fEnable); CoInternetSetFeatureEnabled(ComInteropConstants.FEATURE_MIME_HANDLING, (uint)ComInteropConstants.SET_FEATURE_ON_PROCESS, true); CoInternetSetFeatureEnabled(ComInteropConstants.FEATURE_MIME_SNIFFING, (uint)ComInteropConstants.SET_FEATURE_ON_PROCESS, true); 

所以看起来没有启用这些function(MIME处理和MIME嗅探),错误的HTTP响应(带有文本内容的内容类型应用程序/八位字节流)会导致问题。