Почему мой фильтр IE MIME не создается и не вызывается? - PullRequest
2 голосов
/ 26 марта 2009

Я пытаюсь создать фильтр MIME, чтобы выполнить некоторую пользовательскую обработку ресурсов, полученных с веб-страниц, прежде чем передавать их в элемент управления веб-браузера в нашем приложении Windows. Приложение написано на C #, и я хотел бы написать MIME-фильтр также в управляемом коде, если это возможно. У меня проблемы с этим: мой объект фильтра, кажется, вообще не вызывается.

Вот мой код. Извините, это так долго, но я думаю, что я могу неправильно что-то определять в интерфейсах 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 Ответ

1 голос
/ 08 мая 2009

Оказывается, документация MSDN и Visual Studio 2008 не согласны с видимостью COM по умолчанию. В документации MSDN сказано, что все типы .NET по умолчанию видимы для COM, но шаблон проекта библиотеки классов Visual Studio 2008 отключает видимость COM в файле AssemblyInfo.cs.

Решение: удалить строку

[assembly: ComVisible(false)]

из файла AssemblyInfo.cs.

Возможно, у меня также были плохие объявления интерфейса COM. Я заменил их на этого документа CodeProject .

Единственный читаемый образец кода MIME-фильтра, который я нашел, доступен здесь и (кратко) задокументирован здесь .

...