简体   繁体   中英

AccessViolationException from WebBrowser control with custom IDownloadManager

My .NET application hosts a WebBrowser control, and I've attached a custom download manager. Everything seems to work fine except for requests with the following two HTTP headers:

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

Change or omit the content type header, and everything works fine; it's just application/octet-stream that has the problem. Remove the content disposition header and the download manager isn't used.

Interestingly, this problem only happens on 32 bit machines (I've tested XP and Win 7 32 bit. Win 7/8 64 bit do not crash).

What's so special about application/octet-stream ?

In case it helps, here's a ton of code that registers the custom download manager. It was inspired by this question and answer: Windows Forms Webbrowswer control with IDownloadManager

In my class that derives from WebBrowser :

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

In 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 is my custom download manager. Its implementation of Download is below.

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

It implements IDownloadManager , declared below.

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

To reproduce the crash, I don't need to actually do anything inside that method.

I still don't fully understand why my application was crashing, nor do I fully understand why the following code fixed it, but here's what ended up preventing the crash:

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

So it looks like without these features turned on (MIME handling and MIME sniffing), bad HTTP responses (content type application/octet-stream with text content) cause problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM