代码之家  ›  专栏  ›  技术社区  ›  Greg

为什么没有创建或调用我的IE MIME过滤器?

  •  2
  • Greg  · 技术社区  · 17 年前

    我正在尝试创建一个MIME过滤器,以便在将网页中接收到的资源传递给Windows应用程序中的web浏览器控件之前,对这些资源进行一些自定义处理。应用程序是用C#编写的,如果可能的话,我还想用托管代码编写MIME过滤器。但是我遇到了麻烦:我的filter对象似乎根本没有被调用。

    这是我的密码。抱歉,太长了,但是我想我可能在COM接口中定义了一些错误的东西,所以我也包括了这些。知道我做错了什么吗?

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("00000001-0000-0000-C000-000000000046")]
    public interface IClassFactory
    {
        void CreateInstance([MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, ref Guid riid, out IntPtr ppvObject);
        void LockServer(bool fLock);
    }
    
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B")]
    public interface IInternetProtocol : IInternetProtocolRoot
    {
        void LockRequest(Int32 dwOptions);
        [PreserveSig]
        Int32 Read(IntPtr pv, UInt32 cb, out UInt32 pcbRead);
        void Seek(Int64 dlibMove, UInt32 dwOrigin, out UInt64 plibNewPosition);
        void UnlockRequest();
    }
    
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("79EAC9E3-BAF9-11CE-8C82-00AA004BA90B")]
    public interface IInternetProtocolRoot
    {
        void Abort(Int32 hrReason, Int32 dwOptions);
        void Continue(IntPtr pProtocolData);
        void Resume();
        void Start([MarshalAs(UnmanagedType.LPWStr)] string szUrl, IInternetProtocolSink pOIProtSink,
                   IntPtr pOIBindInfo, UInt32 grfPI, IntPtr dwReserved);
        void Suspend();
        void Terminate(Int32 dwOptions);
    }
    
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("79EAC9E5-BAF9-11CE-8C82-00AA004BA90B")]
    public interface IInternetProtocolSink
    {
        void Switch(IntPtr pProtocolData);
        void ReportProgress(UInt32 ulStatusCode, [MarshalAs(UnmanagedType.LPWStr)] string szStatusText);
        void ReportData(UInt32 grfBSCF, UInt32 ulProgress, UInt32 ulProgressMax);
        void ReportResult(Int32 hrResult, UInt32 dwError, [MarshalAs(UnmanagedType.LPWStr)] string szResult);
    }
    
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("79eac9e7-baf9-11ce-8c82-00aa004ba90b")]
    public interface IInternetSession
    {
        void CreateBinding(); // Not Implemented
        void GetCache(); // Not Implemented
        void GetSessionOption(); // Not Implemented
        void RegisterMimeFilter([MarshalAs(UnmanagedType.Interface)] IClassFactory pCF, ref Guid rclsid, [MarshalAs(UnmanagedType.LPWStr)] string pwzType);
        void RegisterNameSpace([MarshalAs(UnmanagedType.Interface)] IClassFactory pCF, ref Guid rclsid, [MarshalAs(UnmanagedType.LPWStr)] string pwzProtocol,
                               UInt32 cPatterns, [MarshalAs(UnmanagedType.LPWStr)] string ppwzPatterns, UInt32 dwReserved);
        void SetCache(); // Not Implemented
        void SetSessionOption(); // Not Implemented
        void UnregisterMimeFilter(IClassFactory pCF, [MarshalAs(UnmanagedType.LPWStr)] string pwzType);
        void UnregisterNameSpace(IClassFactory pCF, [MarshalAs(UnmanagedType.LPWStr)] string pwzProtocol);
    }
    
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("C3ED53DA-EC0E-4625-AB0C-9837D0D0D59D")]
    public interface _MimeFilter : IClassFactory, IInternetProtocol, IInternetProtocolRoot, IInternetProtocolSink
    {
    }
    
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("C3ED53DA-EC0E-4625-AB0C-9837D0D0D59D")]
    public class MimeFilter : _MimeFilter
    {
        #region [ IClassFactory ]
        public void CreateInstance([MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, ref Guid riid, out IntPtr ppvObject)
        {
            ... // This is never called
        }
    
        ...
    }
    
    internal class FilterUtils
    {
        /// <summary>
        /// Registers the MIME filter for the current process
        /// </summary>
        public static void RegisterFilter()
        {
            IInternetSession session = null;
            int status = NativeMethods.CoInternetGetSession(0, ref session, 0);
            MimeFilter mf = new MimeFilter();
            Guid id = new Guid("C3ED53DA-EC0E-4625-AB0C-9837D0D0D59D");
            session.RegisterMimeFilter(mf, ref id, "text/html; charset=UTF-8");
        }
    
        private static class NativeMethods
        {
            [DllImport("urlmon.dll")]
            public static extern int CoInternetGetSession(UInt32 dwSessionMode /* = 0 */, ref IInternetSession ppIInternetSession, UInt32 dwReserved /* = 0 */);
        }
    }
    

    据我所知,接下来应该发生的事情是调用MimeFilter.CreateInstance()方法。它不会被调用,MimeFilter中的任何其他方法也不会被调用。

    我很感激任何人能提供的帮助。谢谢

    1 回复  |  直到 17 年前
        1
  •  1
  •   Greg    17 年前

    事实证明,MSDN文档和Visual Studio 2008在默认COM可见性方面存在分歧。MSDN文档说明默认情况下所有.NET类型对COM都可见,但Visual Studio 2008类库项目模板在AssemblyInfo.cs文件中禁用COM可见性。

    解决方案:删除该行

    [assembly: ComVisible(false)]
    

    从AssemblyInfo.cs文件。

    我可能也有不好的COM接口声明。我已经把它们换成了 this CodeProject document .

    我找到的唯一可读的MIME过滤器示例代码是可用的 here 和(简要地) documented here .