Для того, чтобы иметь возможность фильтровать URL-адреса, выбранные (включая JS, изображения и т. Д.) С помощью веб-браузера C# (WinForms), единственным доступным вариантом является асинхронный подключаемый Протокол обертывания HTTP (а затем и других). К сожалению, это не удается с InvalidCastException
, вызванным первоначальной первоначальной реализацией протокола после нескольких звонков < - это тоже странная часть, кажется, она преуспела несколько раз перед сбоем.C# Asynchronous Pluggable Protocol wrapting default HTTP Protocol throws InvalidCastException
Теперь некоторый код:
Во-первых, завод по протоколу зарегистрировано и прилагается:
var ep = new FilteredHttpProtocolFactory();
Guid id = Guid.Parse ("E00957BD-D0E1-4eb9-A025-7743FDC8B27B");
session.RegisterNameSpace (ep, ref id, "http", 0, null, 0);
(Фабрика :)
[Guid ("EF474615-8079-4CFA-B114-6D1D28634DD8")]
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.None)]
public class FilteredHttpProtocolFactory : IClassFactory
{
public void CreateInstance (object pUnkOuter, Guid riid, out object ppvObject)
{
ppvObject = new FilteredHttpProtocol();
}
public void LockServer (bool fLock)
{
}
}
Это оригинальный протокол HTTP, используемый IE, при использовании его вместо обертки он отлично работает:
[ComImport]
[Guid ("79eac9e2-baf9-11ce-8c82-00aa004ba90b")]
public class OriginalHttpHandler
{
}
Это сама обертка:
[Guid ("E00957BD-D0E1-4eb9-A025-7743FDC8B27B")]
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.None)]
[AsyncProtocol (Name = "http2", Description = "blah")]
public class FilteredHttpProtocol : IInternetProtocol, IInternetProtocolRoot
{
private readonly IInternetProtocol _wrapped;
public FilteredHttpProtocol()
{
var originalHttpHandler = new OriginalHttpHandler();
_wrapped = (IInternetProtocol) originalHttpHandler;
}
public void Start (string szURL, IInternetProtocolSink Sink, IInternetBindInfo pOIBindInfo, uint grfPI, uint dwReserved)
{
_wrapped.Start (szURL, Sink, pOIBindInfo, grfPI, dwReserved);
}
public void Continue (ref _tagPROTOCOLDATA pProtocolData)
{
_wrapped.Continue (ref pProtocolData); // <- FAILS HERE
}
// .... other methods from IInternetProtocol
public uint Read (IntPtr pv, uint cb, out uint pcbRead)
{
return _wrapped.Read (pv, cb, out pcbRead); // <- OR HERE
}
}
Итак, странная часть, что вызывается конструктор, Start()
называется, даже Read()
и Continue()
называется несколько раз, пока все это не удается (либо с Read()
или Continue()
), когда части страницы уже видны(), но мне кажется, что в основном один конкретный образ отсутствует (в основном):!
Unable to cast COM object of type 'Clients.Windows.Protocol.OriginalHttpHandler'
to interface type 'Clients.Windows.Protocol.IInternetProtocol'. This operation
failed because the QueryInterface call on the COM component for the interface
with IID '{79EAC9E4-BAF9-11CE-8C82-00AA004BA90B}' failed due to the following
error: No such interface supported (Exception from HRESULT: 0x80004002 E_NOINTERFACE)).
Видя, что я уже отдал объект сай d несколько раз (что должно приводить к вызову каждый раз и что он был вызван (проверен через контрольные точки и т. д.) несколько раз, прежде чем он провалится, эта ошибка действительно озадачивает. Если посмотреть на подсчеты ссылок, я уже исключал, что объект находится слишком рано (в любом случае это не имеет смысла).
я пытался несколько вещей:
- Google, но АРР довольно редки
- http://msdn.microsoft.com/en-us/library/aa767916(v=vs.85).aspx
- Наследование объект ComImport'ed - тогда моя реализация игнорируется
- Посмотрите на реф считает
- Листы всех видов
- Проверьте идентификаторы GUID и интерфейсы на наличие ошибок
- Запрашиваемые коллеги
В основном то, что я пытаюсь достичь завернуть реализации протокола по умолчанию HTTP в IE, чтобы отфильтровать URL-адресов, в том числе и тех, где ресурсы извлекаются из. Я также был бы удовлетворен подходящими альтернативами, но они должны быть совместимы с GPLv2, развертываться с помощью приложения-браузера и не выполнять никаких изменений в остальной части системы (т. Е. Без прокси).
Спасибо за помощь;)
Кстати, это будет частью моей магистерской диссертации здесь: http://desktopgap.codeplex.com
Почему у вас ClassInterfaceType None? Я бы убрал его. Кроме того, E_NOINTERFACE может быть проблемой с потоками. Когда ваш объект создан? На какой поток? Что это за тип квартиры? (http://blogs.msdn.com/b/oldnewthing/archive/2004/12/13/281910.aspx) –
Привет! Спасибо за ваш ответ. Действительно, посмотрев на нити, используемые для вызова методов: '# 1 ThreadId: 3 C'tor() # 1 URL: \t HTTP: // ... # 1 исходный поток: 3 вызывающий поток 3 Start() STA # 2 threadID: 3 C'tor() # 2 URL: \t http: // ... # 2 оригинальная резьба: 3 вызывающая нить 3 Start() STA # 1 исходная резьба: 3 вызывающая нить 14 Continue() MTA # 2 исходная резьба: 3 вызывающая нить 13 Continue() MTA Первое исключение случайного типа ' System.InvalidCastException '... ' Однако эти потоки создаются тем, кто их называет, поэтому я не уверен, как я могу изменить квартиру ... – claus
Создаете ли вы каждый экземпляр FilteredHttpProtocol в текущем потоке или вы поделиться экземпляром? –