Ошибка PHP — не удалось создать COM-объект, класс не зарегистрирован
В настоящее время я переносю веб-сайт PHP с сервера под управлением Windows Server 2003 и PHP 5.2 на сервер под управлением Windows Server 2012 R2 и PHP 5.6.35. Один скрипт выдает ошибку «Class Not Registered» при создании COM-объекта:
$obj = new COM('DllName.ClassName') or die ("Unable to create COM object");
Я проверил вышеуказанные вопросы и могу подтвердить, что:
- COM DLL регистрируется на сервере (как путем проверки реестра, так и с помощью PowerShell)
- Установка PHP является 32-битной (PHP_INT_SIZE — 4).
Я думаю, что следующей вещью для меня является диалог «Расширенные настройки», упомянутый в ответе на первый вопрос выше, но где я могу его найти? Фактический используемый сервер — Apache, установленный как часть WAMP, но я думаю, что проблема находится на более низком уровне.
Решение
Это может быть связано с изменением функции, называемой изоляцией сеанса 0.
В результате до Windows Server 2003 COM мог использоваться в обслуживании.
Его нельзя использовать из Windows Server 2008.
А в Windows Vista, являющейся стороной рабочей станции, COM нельзя использовать из программ, запускаемых как сервисы.
В Windows XP, Windows Server 2003 и более ранних версиях Windows все службы работают в сеансе 0 вместе с приложениями. Эта ситуация создает угрозу безопасности. В Windows Vista, Windows Server 2008 и более поздних версиях Windows операционная система изолирует службы в сеансе 0 и запускает приложения в других сеансах, поэтому службы защищены от атак, происходящих из кода приложения.
Пожалуйста, не используйте COM на стороне сервера, как показано в следующей статье офиса.
Другие решения
Исправление состояло в том, чтобы использовать взлом реестра, описанный в сообщении в блоге, связанном с первым связанным вопросом. Полный процесс:
- Скопируйте ActiveX DLL в C:\Windows\SysWOW64 (не System32).
- Откройте командную строку и зарегистрируйте DLL: C:\Windows\SysWOW64>regsvr32
- Откройте реестр (введите regedit в командной строке) и найдите имя DLL в HKEY_CLASSES_ROOT\WOW6432Node\CLSID , DLL должна быть найдена в ключе с именем HKEY_CLASSES_ROOT\WOW6432Node\CLSID\ , Скопируйте GUID в буфер обмена.
- Создайте новое строковое значение с именем AppID в этом ключе (не в любом из его подразделов). Установить AppID значение для GUID (включая фигурные скобки).
- Создайте новый ключ: HKEY_CLASSES_ROOT\WOW6432Node\AppID\ ,
- В этом новом ключе создайте строковое значение с именем DllSurrogate , Оставьте значение пустым.
Теперь объект ActiveX должен создаваться из PHP с использованием функций COM.
Класс не зарегистрированной ошибки из PHP
Мы создали сборку библиотеки классов C # и сделали ее COM видимой, чтобы иметь возможность вызывать ее методы с PHP. Это работало нормально, но теперь мы хотели установить его на сервере Windows Server 2008, и мы продолжаем идти по ошибке «Класс не зарегистрирован».
Чтобы исключить любые проблемы с зависимостями, я сделал небольшую небольшую библиотеку тестовых классов в C #. Библиотека классов построена для любого процессора, и она видима COM (также устанавливается COMVisible в true в AssemblyInfo.cs). Библиотека тестового класса содержит только один класс с одним методом. Класс называется TestLib, а пространство имен также называется TestLib. Метод называется Test и возвращает строку.
Мы сделали следующее: – построил TestLib.dll – скопировал его на машину Windows Server 2008 – зарегистрировал dll с помощью: regasm / codebase TestLib.dll – инструмент regasm возвращает сообщение об успешном завершении – на PHP мы просто пытаемся создать новый экземпляр COM:
try < $test = new COM("TestLib.TestLib"); >catch (Exception $e) < die($e->getMessage()); >
- когда мы называем этот тестовый скрипт либо из браузера, либо из командной строки (php -f test.php), мы получаем ошибку «Класс не зарегистрирован» в обоих случаях
Я также попытался добавить TestLib в GAC, используя gacutil -i, но безрезультатно; еще не зарегистрированная ошибка класса.
Затем я попытался скомпилировать тестовую библиотеку с .NET 2.0 вместо 4.0 в качестве целевой структуры, такой же результат. Кстати, .NET Framework 4.0 установлен на сервере.
Хорошо, поэтому после нескольких исследований я понял это. Процесс php.exe – 32 бит. COM-видимая сборка скомпилирована для любого CPU, поэтому она должна быть доступна как для 32, так и для 64-битных приложений.
Проблема заключается в том, что на 64-битной ОС php.exe и любом 32-разрядном процессе, в этом случае, выполняется поиск в HKEY_CLASSES_ROOT \ Wow6432Node \ CLSID вместо HKEY_CLASSES_ROOT \ CLSID и в HKEY_LOCAL_MACHINE \ Software \ Classes \ Wow6432Node \ CLSID вместо HKEY_LOCAL_MACHINE \ Software \ Classes \ CLSID. Записи реестра в ключах Wow6432 не создаются regasm, которые поставляются с .NET framework v4 на Windows Server 2008. В Windows 7 они созданы, не спрашивайте меня, почему.
Также выяснилось, что, если я создам небольшую тестовую сборку для .NET v2.0 и зарегистрирую ее с regasm, которая поставляется с .NET framework v2.0, она создает записи Wow6432Node в Windows 2008. Странно.
Поэтому я хочу создать основной файл реестра на сервере, используя:
regasm /regfile MyClassLib.dll
Это создает файл MyClassLib.reg только с «нормальными» 64-битными записями. Затем я экспортировал ключи Wow6432Node с компьютера Windows 7 и добавил его в этот .reg-файл. Теперь, когда я импортирую этот файл reg в реестр Windows 2008, все работает нормально.
Для получения дополнительной информации о записях Wow6432Node выполните следующие действия: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724072%28v=vs.85%29.aspx
Надеюсь, это спасет кого-то еще некоторое время и головные боли.
Если вы пытаетесь вызвать 32-bit COM DLL в 64-битной Windows, вам необходимо ее зарегистрировать.
- Скопируйте 32-разрядную DLL в C: \ Windows \ sysWOW64
- Запустите C:\Windows\sysWOW64\regsvr32.exe your_com_32.dll
Немного больше информации со скриншотами .
Класс не зарегистрированная ошибка из PHP
Мы создали сборку библиотеки классов С# и сделали ее COM видимой, чтобы иметь возможность вызывать ее методы с PHP. Это работало нормально, но теперь мы хотели установить его на сервере Windows Server 2008, и мы продолжаем идти по ошибке «Класс не зарегистрирован». Чтобы исключить любые проблемы с зависимостями, я сделал небольшую небольшую библиотеку тестовых классов в С#. Библиотека классов построена для любого процессора, и она видима COM (также устанавливается COMVisible в true в AssemblyInfo.cs). Библиотека тестового класса содержит только один класс с одним методом. Класс называется TestLib, а пространство имен также называется TestLib. Этот метод называется Test и возвращает строку. Мы сделали следующее: — построил TestLib.dll — скопировал его на машину Windows Server 2008 — зарегистрировал dll с помощью: regasm/codebase TestLib.dll — инструмент regasm возвращает сообщение об успешном завершении — в PHP мы просто пытаемся создать новый экземпляр COM:
try < $test = new COM("TestLib.TestLib"); >catch (Exception $e) < die($e->getMessage()); >
- когда мы вызываем этот тест script из браузера или командной строки (php -f test.php), мы получаем ошибку «Класс не зарегистрирован» в обоих случаях
Я также попытался добавить TestLib к GAC с помощью gacutil -i, но безрезультатно; еще не зарегистрированная ошибка класса.
Затем я попытался скомпилировать тестовую библиотеку с .NET 2.0 вместо 4.0 в качестве целевой структуры, то же самое..NET framework 4.0 установлен на сервере, кстати.
Ошибка PHP — не удалось создать COM-объект, класс не зарегистрирован
В настоящее время я переношу веб-сайт PHP с сервера под управлением Windows Server 2003 и PHP 5.2 на сервер под управлением Windows Server 2012 R2 и PHP 5.6.35. Один сценарий выдает ошибку «Класс не зарегистрирован» при создании COM-объекта:
$obj = new COM('DllName.ClassName') or die ("Unable to create COM object");
Я проверил приведенные выше вопросы и могу подтвердить, что:
- COM-DLL регистрируется на сервере (как путем проверки реестра, так и с помощью PowerShell)
- Установка PHP 32-битная (PHP_INT_SIZE равно 4).
Думаю, следующее, на что мне стоит обратить внимание, — это диалоговое окно «Дополнительные настройки», упомянутое в ответе на первый вопрос выше, но где его найти? Фактически используемый сервер — это Apache, установленный как часть WAMP, но я думаю, что проблема на более низком уровне.
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете.
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции — это способ манипулировать массивами и играть с массивами данных. Благодаря.
PHP — это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать.
Laravel Scout — это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он.
Ответы 2
Это может быть связано с изменением функции, называемым изоляцией сеанса 0.
В результате именно в Windows Server 2003 COM можно было использовать в служебных целях. Его нельзя использовать с Windows Server 2008. А в Windows Vista, которая является частью рабочей станции, COM также нельзя использовать из программ, запущенных как служба.
In Windows XP, Windows Server 2003, and earlier versions of Windows, all services run in Session 0 along with applications. This situation poses a security risk. In Windows Vista, Windows Server 2008, and later versions of Windows, the operating system isolates services in Session 0 and runs applications in other sessions, so services are protected from attacks that originate in application code.
Пожалуйста, не используйте COM на стороне сервера, как показано в следующей офисной статье.
Это кажется довольно катастрофическим, но (насколько я знаю) PHP не работает как служба, и это нарушило бы все функции COM PHP — в Руководство по PHP об этом ничего не говорится. Я почти уверен, что это не такая уж серьезная проблема.
В таком случае Apache работает как служба? Была такая статья. служба apache php exec не работает Кроме того, не совпадает ли 32/64 битная конфигурация Apache / PHP и COM Object ?.
Класс не зарегистрированная ошибка из PHP
Мы создали сборку библиотеки классов C# и сделали ее видимой для COM, чтобы иметь возможность вызывать ее методы из PHP. Раньше это работало нормально, но теперь мы хотели установить его на сервер Windows Server 2008, и мы продолжаем сталкиваться с ошибкой «Класс не зарегистрирован».
Чтобы исключить любые проблемы с зависимостями, я сделал небольшую тестовую библиотеку классов на C#. Библиотека классов построена для любого процессора и является видимой для COM (также установите для COMVisible значение true в AssemblyInfo.cs). Библиотека тестовых классов содержит только один класс с одним методом. Класс называется TestLib, а пространство имен также называется TestLib. Метод называется Test и возвращает только строку.
Мы сделали следующее: — построили TestLib.dll — скопировали его на компьютер с Windows Server 2008 — зарегистрировали dll с помощью: regasm /codebase TestLib.dll — инструмент regasm возвращает сообщение об успехе — в PHP мы просто пытаемся создайте новый экземпляр COM:
try < $test = new COM("TestLib.TestLib"); >catch (Exception $e) < die($e->getMessage()); >
- когда мы вызываем этот тестовый скрипт из браузера или из командной строки (php -f test.php), мы получаем ошибку «Класс не зарегистрирован» в обоих случаях
Я также попытался добавить TestLib в GAC, используя gacutil -i, но безрезультатно; еще класс не зарегистрированная ошибка.
Затем я попытался скомпилировать тестовую библиотеку с.NET 2.0 вместо 4.0 в качестве целевой платформы, тот же результат. Кстати,.NET Framework 4.0 установлен на сервере.
2 ответа
Хорошо, после некоторого исследования я понял это. Процесс php.exe является 32-разрядным. Видимая сборка COM скомпилирована для любого процессора, поэтому она должна быть доступна как для 32-, так и для 64-битных приложений.
Проблема заключается в том, что в 64-битной ОС php.exe и любом 32-битном процессе поиск выполняется в HKEY_CLASSES_ROOT\Wow6432Node\CLSID вместо HKEY_CLASSES_ROOT\CLSID и в HKEY_LOCAL_MACHINE\Software\Classes\Wow6432Node\CLSID_HLK_K вместо HK \Classes\CLSID. Записи реестра в ключах Wow6432 не создаются программой regasm, которая поставляется с.NET Framework v4 на Windows Server 2008. В Windows 7 они создаются, не спрашивайте меня, почему.
Также оказалось, что если я создаю небольшую тестовую сборку для.NET v2.0 и регистрирую ее с помощью regasm, поставляемой с.NET Framework v2.0, то это создает записи Wow6432Node в Windows 2008. Странно.
Таким образом, мое решение состоит в том, чтобы создать основной файл реестра на сервере, используя:
regasm /regfile MyClassLib.dll
Это создает файл MyClassLib.reg только с «обычными» 64-битными записями. Затем я экспортировал ключи Wow6432Node с компьютера с Windows 7 и добавил его в этот файл.reg. Теперь, когда я импортирую этот reg файл в реестр в Windows 2008, все работает нормально.
Надеюсь, это сэкономит кому-то еще время и головные боли.