Regsvr32

Метки:  , , , , , , ,

Regsvr32 (Microsoft Windows Register Server) — это системная утилита, предназначающаяся для регистрации и отмены регистрации элементов управления ActiveX, компонентов фильтров (кодеков) и компонентов библиотек DLL в системе Windows посредством внесения изменений в реестр.

DLL (Dynamic Link Library, Библиотека Динамической Компоновки) - динамически подключаемый набор подпрограмм (функций), логически объединенных в единый бинарный файл, которые могут быть многократно/одновременно динамически загружены (использованы) различными приложениями, требующими для своего функционирования данные функции.

Концепция динамических библиотек значительно упрощает архитектуру приложения, ведь вместо того, чтобы каждой программе использовать один и тот же дублирующий код, к примеру, диалоговых окон, проще вынести его в отдельный файл (системную библиотеку DLL), обеспечивающий данный функционал для множества приложений. Поэтому, характерная особенность динамической библиотеки заключается в том, что она может использоваться сразу несколькими приложениями, а система обеспечивает присутствие в памяти только одной копии кода динамической библиотеки для всех приложений, которые содержат ссылки на функции данной библиотеки.
Начиная с Windows XP, в зависимости от разрядности ОС, утилита regsvr32.exe располагается либо только в директории %SystemRoot%\System32 для 32-битных систем, либо в папках %SystemRoot%\System32 и %SystemRoot%\SysWOW64 для 64-битных (присутствуют две разные версии программы). Представляет собой утилиту командной строки, то есть, иными словами, работает с консолью и может использоваться в сценариях.

Смысл регистрации библиотек и элементов управления

По какой причине для использования функций DLL в системе непременно требуется их регистрация? Я думаю, вполне уместно будет привести аналогию с системной переменной пути (%PATH%). Как Вы помните, файлы, которые располагаются в директориях, указанных в переменной %PATH%, можно запускать из командной строки без указания полного пути к файлу, в противном случае их невозможно будет запустить из произвольной директории системы, командный интерпретатор их попросту не найдет. По аналогии и библиотеки, которые содержат функции, широко используемые различными программами, должны быть "объявлены" в системе, иначе программы не смогут их найти. Можно утверждать, что при вызове функции из образа исполняемого файла, загрузчик Windows (менеджер, который отвечает за выделение памяти, подключение различных функций из образов памяти и прч.) должен знать откуда можно подгрузить библиотеку, содержащую требуемую функцию.
Но что такое регистрация в системе применительно к библиотеке DLL? Это определенный алгоритм действий по модификации различных разделов реестра и каталогов файловой системы, результатом которого является "видимость" библиотеки приложениями. Если библиотека "сторонняя" (не системная), то регистрация библиотеки выполняется на этапе инсталляции приложения, для обслуживания функций которого она предназначается. В большинстве случаев сам процесс регистрации библиотеки выполняется при помощью вызова внешних специализированных системных утилит, либо определенной последовательности специализированных функций Windows API.

Зачастую нет необходимости самостоятельно (вручную) регистрировать DLL, практически всегда это выполняется автоматически при инсталляции компонентов системы/программы. Необходимость в ручной регистрации возникает, как правило, в случае каких-либо ошибок в системе: проблем инсталляции/деинсталляции программ, сбоях, либо в случае самостоятельно разрабатываемых DLL, которые необходимо оттестировать.

Можно рассмотреть простой пример, когда произвольно установленная в системе программа использует функцию из библиотеки, не "объявленной" в системе. В подобной ситуации загрузчик Windows на начальной стадии инициализации виртуального адресного пространства процесса выполняет импорт всех библиотек, требуемых загружаемой на выполнение программе. Если одна из библиотек, прописанных в таблице импорта исполняемого образа, отсутствует, то загрузчик выдает такое вот сообщение об ошибке:

regsvr32 запуск программы невозможен

Ошибка сообщает нам о том, что загрузчик образа cDSsvc.exe не смог найти библиотеку MFC71.DLL, необходимую ей для функционирования. Один из способов устранения данного класса ошибок состоит в повторной инсталляции программы, в ситуации, когда файл искомой библиотеки входит в состав какого-либо дистрибутива, поскольку библиотека инсталлируется автоматически скриптом инсталляции. Если библиотека входит в состав другого пакета, например Microsoft Visual C++ 2010 x64 Redistributable, то переустановить необходимо именно его. Если же описанными способами ошибку исправить все же не удается, тогда нам на помощь приходит утилита Regsvr32.

Алгоритм регистрации библиотеки

Regsvr32 при помощи функции LoadLibrary загружает библиотеку и, в зависимости от того, хотите вы зарегистрировать либо разрегистрировать (отменить регистрацию) библиотеку, пытается найти точку входа и вызвать функцию DllRegisterServer() либо DllUnRegisterServer() данной библиотеки и смотрит на результат. Более того, при запуске утилиты с параметром "/i" работает дополнительная логика и regsvr32 будет искать в библиотеке уже точку входа функций DllInstall / DllUnInstall. Все это говорит в пользу того, что существуют определенные требования к структуре DLL, которую вы хотите регистрировать с помощью regsvr32. Для того, чтобы управляющий элемент можно было зарегистрировать с помощью regsvr32, в DLL должны быть, как минимум, реализованы (экспортированы) функции DllRegisterServer, DllUnregisterServer, а при необходимости выполнения специфичных действий еще и функции DllInstall, DllUnInstall. Функции DllRegisterServer / DllUnregisterServer содержат логику, которая фактически и выполняет регистрацию библиотеки в системе, добавляя записи в реестр, требующиеся для управляющего элемента. Функции DllInstall / DllUnInstall служат для выполнения дополнительных действий, которые планирует произвести автор DLL. Поэтому помните, что:

Далеко не все DLL могут быть зарегистрированы при помощи regsvr32!

Давайте посмотрим, что же происходит в случае, когда, к примеру, не определена функция DllRegisterServer:

regsvr32 точка входа DllRegisterServer не найдена

В этом случае мы видим на экране ошибку: "Модуль ????????.??? загружен, но точка входа DllRegisterServer не найдена". Но, давайте как перейдем, непосредственно, к самому процессу регистрации.

Новый метод

Как мы уже говорили, для регистрации библиотеки используется функция DllRegisterServer(). Функция проверяет 128-битный глобальный идентификатор (GUID, Global Unique ID) всех объектов COM/ActiveX, обнаруженных в библиотеке и последовательно прописывает информацию о них в реестр. GUID ни что иное как 128-битный глобальный идентификатор (GUID, Global Unique ID), идентифицирующий конкретный объект класса библиотеки. Регистрация объектов необходима, поскольку программы работают не с самими файлами DLL/OCX/ACX, а с объектами, представляющими определенный набор интерфейсов.
Для целей регистрации DLL используется следующие ветви реестра:

  • ветвь HKLM\SOFTWARE\Classes\CLSID при регистрации COM-объектов библиотек для всех пользователей системы;
  • ветвь HKCU\SOFTWARE\Classes\CLSID при регистрации COM-объектов библиотек только лишь для текущего пользователя;
  • ветвь HKLM\SOFTWARE\Wow6432Node\Classes\CLSID для регистрации 32-битных DLL в 64-битных ОС Windows;
  • Следует помнить, что некоторые расположения в реестре являются всего-лишь ссылками:

    HKEY_CLASSES_ROOT (HKCR) объединяет в себе HKEY_LOCAL_MACHINE\SOFTWARE\Classes и HKEY_CURRENT_USER\SOFTWARE\Classes, и оставлена в системе для совместимости с более ранними версиями СОМ.

    В ветви HKEY_CLASSES_ROOT\CLSID создается ключ с именем, эквивалентным идентификатору GUID. GUID применительно к СОМ называется идентификатором класса. Чтобы отличать идентификаторы классов от других идентификаторов, для них используют наименование CLSID. Примером значения CLSID может служить строка вида {2DB47AE5-CF39-43C2-B4D6-0CD8D90946F4}. В глобальном смысле данные уникальные номера "не повторяются" и уникально идентифицируют компоненты системы, что говорит нам об уникальности объекта класса библиотеки в пределах системы. Подразделами в этих ветках реестра могут быть:

    То есть (default) значения этих ключей соответствуют полному пути к зарегистрированной библиотеке.

    Таким образом можно сделать вывод, что процесс регистрации библиотеки заключается в информировании операционной системы о том, что реализация интерфейсов, предоставляемых объектом с определенным идентификатором, располагается в соответствующем файле.

    Если вам необходимо поменять расположение библиотеки DLL в системе (например, поменять директорию размещения), то потребуется её перерегистрация.

    Старый метод

    В дополнение к современному методу в реестре присутствует еще и ветка HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs. Могу предположить, что она относится к устаревшему методу регистрации общих библиотек DLL, основанному на подсчете количества ссылок на библиотеку. Эта ветка предназначена для регистрации библиотек, которые будут использоваться многими программами системы? В этой ветке имеются параметры типа REG_DWORD, имена которых содержат полный путь зарегистрированным в системе общим библиотекам (например: C:\Windows\system32\VBAME.DLL). Значение параметра может варьироваться от 1 до 65535. Дело в том, что значение это - счетчик использования или, как еще называют, количество ссылок. Зачастую этот метод регистрации использовался не-MSI инсталляторами. Каждый раз, когда какой-либо подобный инсталлятор самостоятельно регистрирует в системе библиотеку, которая до этого уже была зарегистрирована кем-либо еще (то есть присутствует в SharedDLLs), он увеличивает счетчик использования на 1, когда же (например, при удалении) библиотека разрегистрируется, то счетчик уменьшается на 1. Подобная логика была реализована в первых версиях Windows для борьбы с таким явлением как "DLL Hell". У параметров некоторых библиотек можно наблюдать достаточно большие значения (4096), полагаю, таким образом маркируются критичные для системы библиотеки, и счетчик искусственно увеличен с той целью, чтобы разнообразные пользовательские пакеты при своем удалении, случайно не уменьшили счетчик использования до 0 и не выключили DLL.
    В соответствии со всем вышесказанным, в теории, регистрацию можно провести и в ручном режиме самостоятельно, если знать, какие ключи и значения прописываются в реестр.

    32-битные и 64-битные версии regsvr32

    В данный момент более активно начали использоваться 64-битные версии Windows. Если в 32-битных версиях Windows всё было достаточно прозрачно и присутствовало только одна версия программы, то в 64-битных версиях ОС имеются две версии утилиты regsvr32:

    • 64-разрядная версия утилиты — %SystemRoot%\System32\regsvr32.exe (используется по-умолчанию при запуске без конкретизации пути);
    • 32-разрядная версия утилиты — %systemRoot%\SysWoW64\regsvr32.exe

    Получается, в 64-битной системе разработчики сохранили прежнюю систему именования каталогов, однако поместили туда уже "родные" 64-битные приложения. Объясняется это обеспечением совместимости приложений и уменьшением временных затрат на трансляцию кода из 32- в 64-разрядную версию Windows. Таким образом, в 64-битной версии Windows могут работать как 32-битные, так и 64-битные версии программ, соответственно, и DLL могут использоваться и 32- и 64-разрядные.
    Когда вы запускаете regsvr32 в 64-битной версии ОС для регистрации DLL, вы по-умолчанию используете 64-битную версию утилиты.

    Для 64-битных ОС Windows существует золотое правило: директория System32 системы предназначается для родных 64-битных приложений, директория SysWOW64 для 32-битных. Немного не интуитивно, однако это сложившийся факт!! WOW64 (windows on windows 64) - 32-битная подсистема, которая запускается в 64-битной среде.

    Поэтому, если вам требуется зарегистрировать 32-разрядную версию библиотеки DLL в 64-разрядной ОС, и у вас возникает ошибка, то можно поступить следующим образом:

    1. Открыть командную строку с правами администратора;
    2. Если требуемая для регистрации 32-разрядная библиотека DLL находится в директории %SystemRoot%\System32, переместить ее в папку %SystemRoot%\SysWoW64;
    3. Выполнить команду:
      %SystemRoot%\SysWoW64\regsvr32 <полный путь к библиотеке DLL>

      то есть, к примеру: %SystemRoot%\SysWoW64\regsvr32 %SystemRoot%\SysWOW64\test.dll

    Если же перед вами стоит задача зарегистрировать 64-битную DLL в 64-разрядной ОС:

    1. Открыть командную строку с правами администратора;
    2. Если требуемая для регистрации 64-разрядная библиотека DLL находится в директории %SystemRoot%\SysWOW64, переместить ее в папку %SystemRoot%\System32
    3. Выполнить команду:
      %SystemRoot%\System32\regsvr32 <полный путь к библиотеке DLL>

      то есть, например: %SystemRoot%\System32\regsvr32 %SystemRoot%\System32\test.dll

    Синтаксис regsvr32

    Как уже говорилось выше, regsvr32 - это утилита командной строки, поэтому в целях практического использования может запускаться из-под всем уже знакомой cmd, либо использоваться в сценариях.

    В большинстве случаев, для регистрации DLL требуются повышенные привилегии, то есть права локального администратора.

    Утилита regsvr32.exe имеет следующие параметры командной строки:

    Regsvr32 [/u] [/s] [/n] [/i[:cmdline]]

    Список ключей утилиты и описание их действия приведем в следующей таблице:

    Параметр Описание

    /u

    Отменяет регистрацию DLL. Отменить можно только регистрацию DLL, команда не применима к элементам управления и фильтрам.

    /i

    вызывает функцию DllInstall, передавая ей в качестве параметра необязательную строку команд cmdline; Вызов DllInstall приводит к вызову стандартных функций регистрации DllRegisterServer/DllUnRegisterServer, однако позволяет передать строку параметров, которые могут изменить поведение регистрации, например провести регистрацию DLL более одного раза. Ключ /i при использовании с ключом /u вызывает DllUnInstall.

    /n

    не вызывает DllRegisterServer, то есть вызывается только DllInstall; это может быть использовано с ключом /i для передачи дополнительных параметров для регистрации.

    /s

    "тихий" режим; сообщения не отображаются.

    В общем случае, регистрация библиотеки DLL при помощи regsvr32 может быть выполнена следующей командой:

    regsvr32 <имя_библиотеки>.dll

    Например:

    regsvr32 "C:\Windows\System32\schmmgmt.dll"

    Напоминаю, будьте внимательны с версиями утилиты regsvr32 под Windows различной разрядности. В некоторых случаях приходится уточнять путь к утилите при запуске.
    Более того, практически всегда, когда регистрируемый компонент лежит вне путей, включенных в переменную %PATH% (к примеру, если он не находится в %SystemRoot%\System32), путь к компоненту приходится уточнять!
    Пример:

    %SystemRoot%\System32\Regsvr32 %SystemRoot%\System32\macromed\Flash\Flash10a.ocx

    *Составные пути к файлу должны заключаться в кавычки по правилам синтаксиса командной строки Windows.

    • Поделиться:

    20 комментариев:

    1. Alofa

      Автору Respect и огромное Спасибо.
      Все коротко и содержательно.

      Для 64-битных ОС Windows существует золотое правило: директория System32 системы предназначается для 64-битных версий, директория SysWOW64 для 32-битных. Немного не интуитивно, не находите? Но тем не менее это сложившийся факт!! WOW (windows on windows) - 32-битная подсистема, которая запускается под 64-битной подсистемой.

      А эта особенно ценная информация (по крайней мере для меня).
      Делая дальнейшие выводы нетрудно догадаться что это касается не только "Regsvr32".

      • einaare

        Рад что смог помочь! На самом деле статья еще не полностью доработана, никак не могу к ней вернуться :)

    2. Рамиль

      Регистрирую 2 dll(Scaner1C.dll и _Scaner1C.dll) с одинаковым AddIn. Это Файлы разных версий, выпусков. При регистрации пишет, что успешно зарегистрированы. Одна перезарегистрирует другую или обе будут зарегистрированы?

      • einaare

        зарегистрированы они будут обе, потому как с большой вероятностью у них разные GUID. а вот как будут работать экспортируемые функции, это уже другой вопрос.
        а подробнее про эти dll можете рассказать? какие у них пространства имен? или кроме того, что у них одинаковые addin, более ничего не известно?

    3. Рамиль

      Больше ничего не известно. Решили все таки обойтись одной более новой версией.

      • einaare

        спасибо за комментарий. повод модифицировать статью как будет время :)

    4. Евгений

      В 64-битной версии Windows 8.1 Pro в режиме "коммандной строки" не получается запустить реестр (с локальными правами) с помощью 32-битной утилиты PsExec. Команда: psexec.exe -s -i 0 regedit.exe
      Пишет: "Отсутствует подсистема, необходимая для поддержки данного типа образа."

      • einaare

        Как мне кажется, у вас проблема с загрузчиком исполняемых файлов. 32-битные программы в системе вообще работают? Может пакет WOW64 отсутствует или поврежден? Что за версия? Были ли заражения системы?

    5. Света

      У мeня тaкaя пpoблeмa: нa кoмпьютepe двe oчeнь нyжныe пpoгpaммы иcпoльзyют oдин и тoт жe фaйл МV14.ОСХ, нo paзныx вepcий. Ecли зapeгиcтpиpoвaть oдин, тo втopaя пpoгpaммa нe зaпycтитcя (и нaoбopoт). Бeз peгиcтpaции МV14.ОСХ ни oднa из пpoгpaмм нe зaпycкaeтcя. Пoпpoбoвaлa пpocтo пoлoжить фaйл в пaпкy c пpoгpaммoй - нe cpaбoтaлo. Kaк зapeгиcтpиpoвaть OБA фaйлa?

      • einaare

        есть несколько путей решения проблемы, всё зависит от используемой ОС и самого софта. Я так понимаю, если это было бы что-то свежее, использующее side-by-side технологию, то проблем бы не возникло. Поэтому, я так понимаю, этот компонент из какого-то старого софта? Тогда самым простым выходом будет написать скрипт/батник запуска для каждой программы. выглядеть он будет примерно так:

        regsvr32 c:\program files\Programma\mv14.ocx
        C:\Program Files\Programma\program.exe

        соответственно, замените пути и имена.

        другие способы состоят в изменении CLSID библиотеки и прч. Но там придется лезть в бинарные файлы.

        • Света

          Eіnааrе, Bы aбcoлютнo пpaвы. Этo cтapыe пpoгpaммы, нo вcё жe oчeнь мнoю любимыe и пoлeзныe. Paбoтaю c ними нa XP. A paбoтaть пpиxoдитcя oднoвpeмeннo. Boт oбa фaйлa ОСХ: http://www.datafilehost.com/d/6738e8cb Boзмoжнo ли кaк-тo зacтaвить иx paбoтaть пapaллeльнo? Фaйл из пepвoй пaпки лeжит y мeня в ѕуѕtеm32, гдe eгo нaxoдит пepвaя пpoгpaммa, a втopoй фaйл ОСХ - нeпocpeдcтвeннo в диpeктopии втopoй пpoгpaммы. Ho тa eгo бeз peгиcтpaции чepeз rеgѕvr32 вcё paвнo нe видит :(

          • einaare

            А какие именно ошибки выдают программы при использовании "не своих" библиотек? просто не запускаются?

          • einaare

            В разделе реестра
            HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths

            есть подразделы для обеих Ваших программ?

            • Света

              Eіnааrе, пepвaя пpoгpaммa выдaёт cooбщeниe: «Bыxoд зa пpeдeлы диaпaзoнa». Пoтoм зaгpyжaeтcя cмятый интepфeйc пpoгpaммы, a caмa oнa нe paбoтaeт. Bo втopoй пpoгpaммe зaгpyзкa пpoxoдит нopмaльнo, нo oкнo пoиcкa пo инфopмaции внyтpи пpoгpaммы oтcyтcтвyeт, a пpи пoпыткe зaпycтить пoиcк выдaётcя cooбщeниe: «Run-tіmе еrrоr '31037' Еrrоr lоаdіng frоm fіlе» и пpoгpaммa выpyбaeтcя. B yкaзaннoм Baми paздeлe peecтpa пpиcyтcтвyeт лишь пepвaя пpoгpaммa. Oбa пapaмeтpa («Пo yмoлчaнию» и «Раth») вeдyт нa пaпкy c EXE-фaйлoм.

          • einaare

            Светлана, тут без эксперимента не обойтись. В следствии чего система МОЖЕТ прийти в нестабильное или неработоспособное состояние. Если Вас это не пугает, то смогли бы Вы:
            1. Прописать в реестр и вторую программу по аналогии с первой. Соответственно, оба параметра новой записи должны уже вести на рабочую папку второй программы. Для обеих программ mv14.ocx должны лежать в папках программ, которые обозначены в параметрах Path.
            2. Произвести удаление всех ДРУГИХ записей в реестре о mv14.ocx. Конечно, лучше бы сделать бэкап реестра перед экспериментом. Можно было бы просто провести разрегистрацию через regsvr32 с параметром /u, но он не для всех ситуаций работает.

            • Света

              Я cмeлaя дeвyшкa, вeдь eщё Ииcyc гoвopил: «He чeлoвeк для Wіndоwѕ, a Wіndоwѕ для чeлoвeкa» :)))) Пpoдeлaлa oбa экcпepимeнтa. Peзyльтaт, к coжaлeнию, тoт жe: либo paбoтaeт пpoгpaммa A, либo - Б. Bмecтe - никaк :(

              • einaare

                ну а тогда в чем проблема запускать софт батниками, в которых регистрируется своя dll?

              • einaare

                а если удалить mv14.ocx из папки c:\windows\system32 ?

                • Света

                  Еіnааrе, oбe пpoгpaммы дoлжны paбoтaть oднoвpeмeннo - в этoм и бeдa (бeз mv14.осх из пaпки Sуѕtеm32 ничeгo вooбщe нe зaпycкaeтcя). Я пoпpoбoвaлa пepeимeнoвaть mv14.осх в mv15.осх и зapeгиcтpиpoвaть ОСХ. Hичeгo, кoнeчнo, нe пoлyчилocь, тaк кaк (oчeвиднo) cpaвнeниe пpoиcxoдит c чeм-тo внyтpи фaйлa, кaкoй-нибyдь тaм элeктpoннoй пoдпиcью или кoдoм, я ocoбo в этoм нe paзбиpaюcь.

              • einaare

                Светлана? Могли бы Вы описать иерархии обеих директорий. Полные пути, наименования запускных файлов, библиотек.. где лежат библиотеки mv14.ocx в обеих директориях, если лежат.. и еще, где в обеих директориях находится библиотека mvcl14n.dll? Если комментарии к статье закроются - пишите в разделе "О сайте".

    Добавить комментарий

    Ваш e-mail не будет опубликован. Обязательные поля помечены *