graywolf's lair

Inhuman being's diary…

Заміна URL для Live search в IE

| 8 Comments

Одразу маленька відмазка: те, що надалі описане мені потрібно було виключно по роботі. Сам я IE не користуюсь – лише Оперою та Файрфоксом 😉

Не дивлячись на те, що сабжева задача здається вельми і вельми тривіальною насправді все не атк просто. Мається на увазі URL, по якому переходить браузер, якщо ви введети якусь маячню в Location Bar (напр. набір слів, або неіснуючий домен). Точніше велику проблему це становить для IE6. Для Internet Explorer 7 все вирішується просто – URL для закачки міняється правкою ключа реєстру:

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\SearchScopes\{0633EE93-D776-472f-A0FF-E1416B8B2E3A}\URL

Міняємо прописаний там майкрософтівський Live search на щось типу:

http://www.google.com.ua/search?hl=uk&q=<strong>{searchTerms}</strong>&meta=

де {searchTerms} – макрос, на місце якого підставляється введені в рядку браузера лексеми. І все ОК. А от в IE6 такого ключа нема. І там все робиться через дупу. Саме цей романтичний шлях і буде далі описано…

Для визначення URL для підстановки в Address bar в разі, коли IE не може знайти протокол по якому потрібно працювати (ви не вказали його, а дреса не містить ніяких підказок, напр. у вигляді префікса “www.”) викликається COM-об’єкт, що реалізує інтерфейс IURLSearchHook. Цей інтерфейс має лише одну член-функцію: Translate. В комплекті з IE6 йде власна реалізація цього інтерфейсу, яка відкриває сторінку auto.search.msn.com. CLSID об’єкта, який відповідатиме за постачання URL прописано в ключі HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\URLSearchHooks. По замовучуванню використовується об’єкт з CLSID {CFBFAE00-17A6-11D0-99CB-00C04FD64497}. Для того, щоб встановити власний URL для пошуку за замовчуванням нам потрібно замінити його своєю реалізацію.

Для цього створюємо звичанйий проект ATL:

Customizing IE live search - Create ATL Project

Параметри залишаємо без змін. Далі в щойноствореному проекті через Class Wizard додаємо ATL Simple Object – клас, який і буде реалізацією інтерфейсу IURLSearchHook.

Customizing IE live search - Create ATL Simple Class

Даємо цьому класу якесь ім’я. Вкладку “Options” можна не чіпати і залишити все по дефолту.

Customizing IE live search - ATL Simple Class Wizard

Class Wizard зробив для нас практично всю брудну роботу і тепер можна, власне, дописувати необхідні дані.

Файл з описанням класу (в нашому прикладі Searcher.h) доводимо до наступного вигляду:

// Searcher.h : Declaration of the CSearcher

#pragma once
#include "resource.h"       // main symbols

#include <..\PlatformSDK\include\comdef.h>
#include <shlobj.h>

// ISearcher
[
    object,
    uuid("A548953B-21A1-490F-A189-0F9FD714BDE2"),
    dual,	helpstring("ISearcher Interface"),
    pointer_default(unique)
]
__interface ISearcher : IDispatch
{
};

// CSearcher
[
    coclass,
    threading("apartment"),
    vi_progid("IESearchHook.Searcher"),
    progid("IESearchHook.Searcher.1"),
    version(1.0),
    uuid("94D618D6-E6E7-4EE9-B1B7-24C0B2327853"),
    helpstring("Searcher Class")
]
class ATL_NO_VTABLE CSearcher : 
    public ISearcher,
    public IURLSearchHook
{
public:
    CSearcher() {}

    DECLARE_PROTECT_FINAL_CONSTRUCT()

    BEGIN_COM_MAP(CSearcher)
        COM_INTERFACE_ENTRY(ISearcher)
        COM_INTERFACE_ENTRY(IDispatch)
        COM_INTERFACE_ENTRY(IURLSearchHook)
    END_COM_MAP()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }
	
    void FinalRelease() {}

public:
    STDMETHODIMP Translate(LPWSTR lpwszSearchURL, DWORD cchBufferSize)
    {
        LPWSTR wszURL = new WCHAR[cchBufferSize];
        ::LoadStringW(_AtlBaseModule.GetModuleInstance(), IDS_URL404, wszURL, cchBufferSize);
        wcsncat(wszURL, lpwszSearchURL, cchBufferSize);

        ZeroMemory(lpwszSearchURL, wcslen(wszURL));
        wcsncpy( lpwszSearchURL, wszURL, cchBufferSize);
        delete [] wszURL;
		        
        return S_OK;
    }
};

Далі створюємо ресурс в String table з ідентифікатором IDS_URL404 і змістом типу: http://www.google.com/search?q= (це пошук по гуглю) і збираємо продукт. Реєстрацію COM-об’єкта Visual Studio зробить за нас, але для того, щоб зареєструвати цю dll-бібліотеку на іншому компі потрібно буде виконати команду:

regsvr32 IESearchHook.dll

До речі, по коду ще прошу звернути увагу на рядок:

#include <..\PlatformSDK\include\comdef.h>

Справа в тому, що принаймні в Visual Studio .NET (2003) є два файли comdef.h і в одному з них не прописано GUID для IURLSearchHook. І тоді при компіляції в рядку:

        COM_INTERFACE_ENTRY(IURLSearchHook)

може видаватись помилка типу:

d:\Work\Other\IESearchHook\Searcher.h(49) : error C2787: 'IURLSearchHook' : no GUID has been associated with this object

Тому для того, щоб використовувати нормальний comdef.h пересвідчіться, що використовується саме той, який лежить в:

PATH_TO_VISUAL_STUDIO\Vc7\PlatformSDK\Include\

Ну і нарешті останній крок – це підстановка нашого COM-об’єкту замість експлорерівського. Для цього в ключі

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\URLSearchHooks

видаляємо параметр, ім’я якого є CLSID поточного об’єкту, що видає рядок пошуку і створюємо параметр з іменем, рівним CLSID нашого об’єкту, обгонувши його в фігурні дужки. Для прикладу вище – це буде “{94D618D6-E6E7-4EE9-B1B7-24C0B2327853}”.

От і все. Запускаємо Internet Explorer і насолоджуємось пошуком в Google замість Live Search 😉 Цей спосіб випробувано для Internet Explorer версій 6 та 7. По ідеї має працювати починаючи з 4-го, але це не перевірялося.

Звісно, для реальної роботи функцію Translate треба буде дещо ускладнити, але то вже більш тривіальна справа.

За реалізацію цього завдання вчасно я мушу подякувати наявності наступних двох ресурсів:

  1. Google Answers: Change Autosearch URL in IE6. Але спосіб описаний тут не зовсім працює 😉 Одна з помилок – це якраз описаний вище прикол з comdef.h
  2. Якийсь китайський ресурс. Там добре, що була купа скрінів та багато коду і я інтуітивно здогадався в цій купі ієрогліфів в чому була лажа 🙂

8 Comments

  1. щось я не зовсім врубився, що ти намагаєшся зробити – але якщо замінити default search engine в інтернет експлорері з live на гугл, то ніяких проблем з цим нема: в 7-му ця фіча просто вбудована (вибираєш будь який пошуковик по замовчанню), а в 6-му – проста правка реєстру http://www.google.com/options/defaults.html

  2. Результуюча мета елементарна: якщо користувач набирає щось в Location Bar і це не існуючий сайт, то його мусить зредіректити на нашу сторінку 🙂 До пошуку це має посереднє відношення – скоріше вже його вимикання…

    P.S. А той спосіб на який ти кинув лінку пробувався самим першим, коли була поставлена така задача. Воно не запрацювало і схоже, що не лише у мене, бо тоді не виникло б оцього питання: Google Answers: Change Autosearch URL in IE6 😉

  3. а, зрозумів… але в 7-му іе ця фіча вбудована – тільки що перевірив, у мене пошук по замовчанню стоїть гугл і я набрав в location bar якусь єрунду, ентер – і викинуло на гуглівські рез-ти… так що ніякі ключі міняти не треба, це точно… та і щодо 6-го я впевнений, існує більш легкий, а головне "легальний" спосіб вирішення проблеми; бо те, що ти тут пропонуєш, це, як влучно тобою ж підмічено "через дупу" (так речі точно не робляться…)

  4. Щодо 7-го то думаю, що ти правий, але навіть якщо користувач міг проставити щось своє – нам же потрібно було б все одно знати куди то все прописується зрештою, щоб ми могли зробити те саме програмно (напр. в setup'ці).

    А своя реалізація COM-об'єкту для пошуку – це і є легальний, але погано задокументований майкрософтом засіб. Я на цю тему багато гуглив і це зрештою виявився єдиний засіб, який зрештою-таки запрацював.

  5. якби у мене був іе6 – міг би заспорити, що все там можна швиденько влаштувати (він займав 95% ринку і ти думаєш, люди не нарили легкий workaround?) щось типу

    Click on the Start button

    Click on Search

    Click on Change Preferences

    Click on Change Internet Search Behavior

    Select Classic Internet Search

    Select Google from the list

    Click ok

    Start IE

    Click on Search button to open the search pane on the left

    Click on customize at the top

    Click on autosearch settings

    Make sure Google is set as the search provider

    Click ok

    Click ok

    та в принципі, ера 6-ого вже пройшла і особливо все це нікому не потрібно 😉

  6. а якщо програмно – то, звісно, так легально (я думав, ти всю цю мороку пропонуєш як "загальний" підхід для звичайного користувача)

    п.с. до речі, гугл вікрив нову фічу, бібліотеку http://books.google.com/googlebooks/mylibrary/ (річ кльова, от як би ще у них там книжок було побільше оцифрованих…)

  7. Ммммм… Цікавий сервіс та бібліотека. Дякаю за наводку ^_^ Як повернусь додому – подивлюся детальніше, а то зараз на роботі часу нема 🙁

Залишити відповідь

Required fields are marked *.