При переносе базы данных или обработок 1С со старых операционных систем (Windows 7, Windows Server 2008) на более современные ОС, такие как Windows Server 2012 R2, разработчики часто сталкиваются с аппаратными и системными сбоями при обращении к внешним компонентам. Одна из распространенных проблем — ошибка инициализации объекта System.Text.UTF8Encoding.
Рассмотрим стандартный вызов кода, который вызывает ошибку:
Текст = Новый COMОбъект("System.Text.UTF8Encoding");
На Windows Server 2012 R2 выполнение этого кода завершается сбоем: Ошибка при вызове конструктора (COMОбъект): Unknown error 0x80131700. Разберем подробно, почему возникает данное исключение и как его корректно устранить несколькими способами.
Проанализируем техническую суть сбоя. Код ошибки 0x80131700 (в спецификации Microsoft — COR_E_CANNOT_LOAD_NET_ERR) генерируется библиотекой mscoree.dll, которая отвечает за загрузку среды выполнения .NET Framework (CLR).
COM-объекты из базовой библиотеки mscorlib (включая класс System.Text.UTF8Encoding) зарегистрированы в реестре Windows с привязкой к старой версии среды выполнения .NET Framework 2.0/3.5 (CLR v2.0). В Windows Server 2012 R2 по умолчанию активирована новая среда .NET Framework 4.5 (CLR v4.0), а компонент .NET 3.5 отключен. При попытке инициализации COMОбъект Windows находит записи в реестре, но загрузчик не может запустить среду CLR v2.0, из-за чего возникает сбой.
Самый простой и надежный способ вернуть работоспособность коду — включить необходимую версию платформы .NET в операционной системе.
Нюанс установки при отсутствии доступа к интернету: Если сервер изолирован от сети Интернет или службы Windows Update, установка через интерфейс завершится ошибкой. В этом случае установим компонент через утилиту DISM, указав путь к установочному диску операционной системы (папка sources\sxs):
dism /online /enable-feature /featurename:NetFx3 /All /Source:D:\sources\sxs /LimitAccess
Если на сервере запрещено устанавливать устаревшие версии .NET Framework, мы можем указать среде выполнения .NET 4.x необходимость исполнять вызовы, предназначенные для устаревших версий CLR.
Для этого в каталоге с исполняемым файлом 1С необходимо создать или отредактировать файл конфигурации приложения:
1cv8.exe.config рядом с 1cv8.exe.rphost.exe.config рядом с rphost.exe.Добавим в структуру файла следующий XML-код:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
</startup>
</configuration>
Флаг useLegacyV2RuntimeActivationPolicy="true" заставляет загрузчик .NET 4.0 обрабатывать вызовы старых COM-компонентов без использования среды CLR v2.0.
Использование COM-объектов платформы .NET создает лишние системные зависимости. Проанализируем, как решить задачу кодирования текстов в UTF-8 средствами самой платформы 1С:Предприятие (начиная с версии 8.3.9).
Для перевода строки в массив двоичных данных в кодировке UTF-8 и обратно воспользуемся встроенными функциями платформы:
// Преобразование строки в двоичные данные UTF-8
ИсходнаяСтрока = "Тестовый текст для кодирования";
ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(ИсходнаяСтрока, КодировкаТекста.UTF8, Ложь);
// Обратное преобразование из двоичных данных в строку
РезультатСтрока = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные, КодировкаТекста.UTF8);
Если требуется записать файл на диск в кодировке UTF-8, задействуем объект ЗаписьТекста:
Запись = Новый ЗаписьТекста("C:\temp\file.txt", КодировкаТекста.UTF8);
Запись.ЗаписатьСтроку("Текст в кодировке UTF-8");
Запись.Закрыть();
Если решение обязательно должно использовать COM-технологию, но при этом необходимо исключить зависимость от .NET Framework, заменим System.Text.UTF8Encoding на стандартный системный объект ADODB.Stream, доступный в любой редакции Windows по умолчанию:
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 2; // Текстовый режим
Поток.Charset = "utf-8";
Поток.Open();
Поток.WriteText("Данные в UTF-8");
Поток.Position = 0;
// Дальнейшие манипуляции с потоком
Поток.Close();
При вызове COM-объектов всегда необходимо обращать внимание на контекст выполнения кода:
1cv8.exe), Windows производит поиск объекта в 32-разрядной ветке реестра (SysWOW64).rphost.exe), поиск происходит в 64-битной ветке реестра.Установка компонента .NET Framework 3.5 регистрирует необходимые библиотеки одновременно для 32-битных и 64-битных процессов, что полностью решает проблему совместимости независимо от разрядности сервера 1С.