PDA

Просмотр полной версии : Развести два веббраузера



Хыиуду
24.02.2009, 00:20
Ситуация раз. Открываю два окна IE. Захожу ими на один и тот же сайт, логинюсь под двумя разными аккаунтами. Все отлично, все заходит, аккаунты прекрасно взаимодействуют друг с другом.
Ситуация два. Делаю форму, на нее кладу два TWebBrowser, захожу ими на один и тот же сайт (процедурой Navigate2 без дополнительных параметров) - веббраузеры ведут себя как сиамские близнецы. То есть если я логинюсь в первом, то при обновлении второго он уже залогинен на тот же аккаунт. А если я во втором выхожу и логинюсь под вторым аккаунтом, первый перелогинивается на него же. Как их развести, чтобы они вели себя как отдельные окна ИЕ в ситуации раз?

Naeel Maqsudov
24.02.2009, 08:40
Один экземпляр браузера (iexplore.exe) многопоточный. У каждогоэкземпляра свои собственные куки и все остальное. Два TWebBrowserа ведут себя так один экземпляр iexplore, т.е. как будто первый был просто открыт, а второй открыт через "Open [Link] in a new window".
Все дело в том, что второ экземпляр TWebBrowser не запускает новый COM-сервер, а получает ссылку на уже существующий.
Посмотри исходники VCL, копай в сторону того, как создается экземпляр TWebBrowser. COM позволяет клиентскому приложению иметь выбор, запускать ли новый веделенный COM-сервер, или остаться на существующем.
Тебе нужно добиться, чтобы при запуке твоей проги в таскменедере появлялось два IE.

Хыиуду
25.02.2009, 22:16
Код создания такой:

constructor TOleControl.Create(AOwner: TComponent);
var
I: Integer;
begin
inherited Create(AOwner);
Include(FComponentStyle, csCheckPropAvail);
InitControlData;
Inc(FControlData^.InstanceCount);
{Тут кусок всякого неинтересного про картинки и шрифты}
FEventDispatch := TEventDispatch.Create(Self);
CreateInstance;
InitControlInterface(FOleObject);
OleCheck(FOleObject.GetMiscStatus(DVASPECT_CONTENT , FMiscStatus));
if (FControlData^.Reserved and cdDeferSetClientSite) = 0 then
if ((FMiscStatus and OLEMISC_SETCLIENTSITEFIRST) <> 0) or
((FControlData^.Reserved and cdForceSetClientSite) <> 0) then
OleCheck(FOleObject.SetClientSite(Self));
OleCheck(FOleObject.QueryInterface(IPersistStreamI nit, FPersistStream));
if FMiscStatus and OLEMISC_INVISIBLEATRUNTIME <> 0 then
Visible := False;
if FMiscStatus and OLEMISC_SIMPLEFRAME <> 0 then
ControlStyle := [csAcceptsControls, csDoubleClicks, csNoStdEvents] else
ControlStyle := [csDoubleClicks, csNoStdEvents];
TabStop := FMiscStatus and (OLEMISC_ACTSLIKELABEL or
OLEMISC_NOUIACTIVATE) = 0;
OleCheck(RequestNewObjectLayout);
end;

Как-то ничего кидающегося в глаза на тему того, что оно относится к COM, нету.
Я еще попробовал следующий фокус:


procedure TForm1.FormCreate(Sender: TObject);
const tgd: TGUID='{D30C1661-CDAF-11D0-8A3E-00C04FC9E26E}';
//это тгуид интерфейса IWebBrowser2
begin
{...}
WebBrowser2.PutProperty('ComObject',CreateComObjec t(tgd));
end;
- роняется с эксепшеном "Класс не зарегистрирован". Хотя вроде бы WebBrowser2 - стандартнейший TWebBrowser.
Не подскажете, куда дальше рыть?

Naeel Maqsudov
26.02.2009, 09:02
Как это "ничего кидающегося в глаза"?! А OLE? :)
Попробую посмотреть.

Мимоходом:
А если мы положим на форму один TWebBrowser и запустим 2 таких приложения они ведут себя также?
Если да, то это ж офигенная дырка приложениях на Delphi! Одно приложение сможет получить к сессионным данным браузера в другом (например, чужом приложении)!

Хыиуду
26.02.2009, 14:43
Как это "ничего кидающегося в глаза"?! А OLE? :)
Я искал слово COM. Удивляться наличию OLE в конструкторе OLEControl было бы странно :)
Дыра не обнаружилась, два приложения исправно создают два разных COM-сервера. Правда, если запустить два приложения, они оба логинятся под одним аккаунтом, потом если в одном из них разлогиниться и зайти под вторым аккаунтом, то при перезапуске приложений будет залогинен уже второй аккаунт, но это как раз объяснимо. Видимо, куки одни и те же жрутся.
Кстати, процесс iexplore.exe вообще не создается. Может, если только в дочерних.

Naeel Maqsudov
26.02.2009, 15:53
Да. iexplore не создается. Видимо получает ссылку на экземпляр explore.exe, который ведь тоже умеет отображать, как содержимое папки, так и ftp ресурса, ну и http тоже.

поставил брейк поинт в constructor TOleControl.Create(AOwner: TComponent);
Видно, что при создании очередного TWebBrowser производится нормальный рефкаунтинг. Inc(FControlData^.InstanceCount);
InstanceCount увеличивается.
Надо копать глубже в inherited Create(AOwner);
Пока нету времени на это.

По поводу дыры, как раз она и есть! Раз два (например, два абсолютно разных-преразных) приложения пользуются одними куками то это уже баг. Два приложения подерутся из-за куков лишь потому, что оба используют VCL-ный TWebBrowser.
Нехорошо.

AiK
08.03.2009, 13:21
на нее кладу два TWebBrowser
А пробовал не класть, а создавать ручками?

AiK
08.03.2009, 13:45
В обчем, за 6 лет всё крутенько поменялось, даже домен. Покопай Embedded Web Browser вот на этом сайте: http://www.bsalsa.com/ (бывший http://www.euromind.com/iedelphi). Для начала некоторые компоненты можно заюзать целиком, ну а для развития - подсмотреть как люди делали и сделать самому по образу и подобию.