Изменить категорию провайдера данных проводника - PullRequest
0 голосов
/ 26 декабря 2011

Как я могу изменить или установить категорию моего расширения оболочки на основе этого примера ?

reference screenshot

На скриншоте расширение находится в категорииMore или на немецком Weitere.

1 Ответ

3 голосов
/ 25 января 2012

Все обработчики расширения оболочки являются объектными объектными моделями (COM) объектов.Им необходимо назначить GUID и зарегистрировать, как описано в разделе «Регистрация обработчиков расширений оболочки».Они реализованы как библиотеки DLL и должны экспортировать следующие стандартные функции: DllMain.Стандартная точка входа в DLL.DllGetClassObject.Выставляет объект класса фабрики.DllCanUnloadNow.COM вызывает эту функцию, чтобы определить, обслуживает ли объект каких-либо клиентов.Если нет, система может выгрузить DLL и освободить связанную с ней память.Как и все COM-объекты, обработчики расширений Shell должны реализовывать интерфейс IUnknown и фабрику классов.Большинство из них также должны реализовывать интерфейс IPersistFile или IShellExtInit в Windows XP или более ранней версии.Они были заменены на IInitializeWithStream, IInitializeWithItem и IInitializeWithFile в Windows Vista.Командная консоль использует эти интерфейсы для инициализации обработчика.Интерфейс IPersistFile должен реализовываться следующим образом:

  • Обработчики значков
  • Обработчики данных
  • Обработчики удаления

Интерфейс IShellExtInit долженбыть реализовано следующим образом:

  • Обработчики контекстного меню
  • Обработчики перетаскивания
  • Обработчики листа свойств

Реализация IPersistFile Интерфейс IPersistFile разработан для того, чтобы позволить объекту быть загруженным или сохраненным в файл на диске.У него есть шесть методов в дополнение к IUnknown, пять собственных и метод GetClassID, который он наследует от IPersist.В случае расширений оболочки IPersist используется только для инициализации объекта-обработчика расширения оболочки.Поскольку обычно нет необходимости читать или записывать на диск, только методы GetClassID и Load требуют реализации без маркеров.Сначала Shell вызывает GetClassID, и функция возвращает идентификатор класса (CLSID) объекта-обработчика расширения.Затем Shell вызывает Load и передает два значения.Первая, pszFile, представляет собой строку Unicode с именем файла или папки, над которыми собирается работать Shell.Вторым является dwMode, который указывает режим доступа к файлу.Поскольку обычно нет необходимости обращаться к файлам, dwMode обычно равен нулю.Метод сохраняет эти значения по мере необходимости для дальнейшего использования.Следующий фрагмент кода иллюстрирует, как типичный обработчик расширения Shell реализует методы GetClassID и Load.Он предназначен для работы с ANSI или Unicode.CLSID_SampleExtHandler - это GUID объекта-обработчика расширения, а CSampleShellExtension - это имя класса, используемого для реализации интерфейса.Переменные m_szFileName и m_dwMode являются закрытыми переменными, которые используются для хранения имени файла и флагов доступа.

class CSampleShellExtension : public IPersistFile
{
    // Method declarations not included

    private:
    WCHAR m_szFileName[MAX_PATH];    // The file name
    DWORD m_dwMode;                  // The file access mode
}

IFACEMETHODIMP CSampleShellExtension::GetClassID(__out CLSID *pCLSID)
{
    *pCLSID = CLSID_SampleExtHandler;
}

IFACEMETHODIMP CSampleShellExtension::Load(PCWSTR pszFile, DWORD dwMode)
{
    m_dwMode = dwMode;
    return StringCchCopy(m_szFileName, ARRAYSIZE(m_szFileName), pszFile); 
}

// Пример реализации продолжается в следующем разделе.Реализация IShellExtInit Интерфейс IShellExtInit имеет только один метод, IShellExtInit :: Initialize, в дополнение к IUnknown.У метода есть три параметра, которые Shell может использовать для передачи различных типов информации.Передаваемые значения зависят от типа обработчика, а некоторые могут быть установлены в NULL.pidlFolder содержит указатель папки на список идентификаторов элементов (PIDL).Это абсолютный PIDL.Для расширений листа свойств это значение равно NULL.Для расширений контекстного меню это PIDL папки, содержащей элемент, контекстное меню которого отображается.Для нестандартных обработчиков перетаскивания это PIDL целевой папки.pDataObject содержит указатель на интерфейс IDataObject объекта данных.Объект данных содержит одно или несколько имен файлов в формате CF_HDROP.hRegKey содержит раздел реестра для файлового объекта или типа папки.Метод IShellExtInit :: Initialize сохраняет имя файла, указатель IDataObject и раздел реестра, необходимые для последующего использования.Следующий фрагмент кода иллюстрирует реализацию IShellExtInit :: Initialize.Для простоты в этом примере предполагается, что объект данных содержит только один файл.В общем случае объект данных может содержать несколько файлов, каждый из которых необходимо извлечь.

 // This code continues the CSampleShellExtension sample shown in the
 // "Implementing IPersistFile" section above.

 class CSampleShellExtension : public IShellExtInit {
     // Method declarations not included

     private:
     // IDList of the folder for extensions invoked on the folder, such as 
     // background context menu handlers or nondefault drag-and-drop handlers. 
     PIDLIST_ABSOLUTE m_pidlFolder;

     // The data object contains an expression of the items that the handler is 
     // being initialized for. Use SHCreateShellItemArrayFromDataObject to 
     // convert this object to an array of items. Use SHGetItemFromObject if you
     // are only interested in a single Shell item. If you need a file system
     // path, use IShellItem::GetDisplayName(SIGDN_FILESYSPATH, ...).
     IDataObject *m_pdtobj;

     // For context menu handlers, the registry key provides access to verb 
     // instance data that might be stored there. This is a rare feature to use 
     // so most extensions do not need this variable.
     HKEY m_hRegKey;              }
      // This method must be very efficient. Do not do any unnecessary work here.  
    // Use Initialize to acquire resources that will be used later.
     IFACEMETHODIMP CSampleShellExtension::Initialize(__in_opt  PCIDLIST_ABSOLUTEpidlFolder,__in_opt IDataObject *pDataObject, __in_opt HKEY hRegKey)  
    { 
     // In some cases,handlers are initialized multiple times. Therefore, 
     // clear any previous state here.
     CoTaskMemFree(m_pidlFolder);
     m_pidlFolder = NULL;

     if (m_pdtobj)
     { 
         m_pdtobj->Release(); 
     }

     if (m_hRegKey)
     {
         RegCloseKey(m_hRegKey);
         m_hRegKey = NULL;
     }

     // Capture the inputs for use later.
     HRESULT hr = S_OK;

     if (pidlFolder)
     {
         m_pidlFolder = ILClone(pidlFolder);   // Make a copy to use later.
         hr = m_pidlFolder ? S_OK : E_OUTOFMEMORY;
     }

     if (SUCCEEDED(hr))
     {
         // If a data object pointer was passed into the method, save it and
         // extract the file name. 
         if (pDataObject) 
         { 
             m_pdtobj = pDataObject; 
             m_pdtobj->AddRef(); 
         }

         // It is uncommon to use the registry handle, but if you need it,
         // duplicate it now.
         if (hRegKey)
         {
             LSTATUS const result = RegOpenKeyEx(hRegKey, NULL, 0, KEY_READ, &m_hRegKey); 
             hr = HRESULT_FROM_WIN32(result);
         }
     }

     return hr; }

Каждый раз, когда вы создаете или изменяете обработчик расширения оболочки, важно уведомить систему о том, что у вас естьвнес изменения.Сделайте это, вызвав SHChangeNotify, указав событие SHCNE_ASSOCCHANGED.Если вы не вызовете SHChangeNotify, изменение может быть не распознано до перезагрузки системы.Есть несколько дополнительных факторов, которые применяются к системам Windows 2000.Подробности см. В разделе «Регистрация обработчиков расширений оболочки в системах Windows 2000».Как и для всех объектов Component Object Model (COM), вы должны создать GUID для обработчика, используя такой инструмент, как Guidgen.exe, который поставляется с Windows Software Development Kit (SDK).Создайте подраздел в HKEY_CLASSES_ROOT \ CLSID, имя которого является строковой формой этого GUID.Поскольку обработчики расширений оболочки являются внутрипроцессными серверами, вы также должны создать подраздел InprocServer32 в этом подразделе GUID со значением (по умолчанию), установленным на путь к DLL обработчика.Используйте модель квартиры.Пример показан здесь:

 HKEY_CLASSES_ROOT    CLSID
       {00021500-0000-0000-C000-000000000046}
          InprocServer32
             (Default) = %windir%\System32\Example.dll
             ThreadingModel = Apartment

Каждый раз, когда оболочка выполняет действие, которое может включать обработчик расширения оболочки, она проверяет соответствующий раздел реестра.Подраздел, под которым зарегистрирован обработчик расширения, определяет, когда он будет вызван.Например, обычной практикой является вызов обработчика контекстного меню, когда оболочка отображает контекстное меню для элемента типа файла.В этом случае обработчик должен быть зарегистрирован в подразделе ProgID типа файла.

...