Как работать с файлами Compound File Binary (CFB) и MSG в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Формат Compound File Binary (CFB), также известный как OLE2 или Structured Storage, долгое время был стандартом для хранения документов Microsoft Office (старые форматы .doc, .xls, .ppt) и до сих пор является основным для файлов электронных писем Outlook (.msg). Работа с ним напрямую из 1С представляет определенную сложность, так как это не обычный текстовый файл, а целая «файловая система внутри файла». В данной статье мы разберем несколько эффективных подходов к извлечению данных из таких структур, начиная от простых внешних утилит и заканчивая низкоуровневой работой с бинарными данными.

Понимание структуры CFB и специфики файлов MSG

Прежде чем переходить к коду, давайте проанализируем, что представляет собой этот формат. Визуально CFB можно сравнить с архивом: внутри одного файла находятся «хранилища» (аналоги папок) и «потоки» (аналоги файлов). Если речь идет о формате .msg, то внутри него хранятся свойства письма (тема, тело, отправитель) в виде отдельных потоков с именами типа __substg1.0_0037001F. Каждое такое имя содержит шестнадцатеричный код (тег MAPI), который определяет тип данных.

Рассмотрим основные способы взаимодействия с этими данными из среды 1С.

Способ 1: Использование консольных утилит (7-Zip)

Один из самых простых и надежных способов «развернуть» файл CFB — использовать популярный архиватор 7-Zip. Мало кто знает, что его консольная версия прекрасно умеет работать с внутренними потоками Compound файлов. Проанализируем алгоритм реализации этого метода в 1С:

  1. Поместим 7z.exe в макет обработки или конфигурации как двоичные данные.
  2. При необходимости извлечем исполняемый файл во временный каталог.
  3. Запустим команду распаковки файла .msg как обычного архива.

Посмотрим на пример кода, реализующий этот подход:


// Извлекаем утилиту из макета
ПутьК7Zip = КаталогВременныхФайлов() + "7z.exe";
ДвоичныеДанныеУтилиты = УправлениеМакетами.ПолучитьМакет("Консоль7Zip");
ДвоичныеДанныеУтилиты.Записать(ПутьК7Zip);

// Команда для распаковки MSG файла во временную папку
ПутьКФайлуMSG = "C:\Temp\Email.msg";
ПутьВыгрузки = КаталогВременныхФайлов() + "ExtractedMSG\";
КомандаЗапуска = СтрШаблон("\"%1\" e \"%2\" -o\"%3\" -y", ПутьК7Zip, ПутьКФайлуMSG, ПутьВыгрузки);

ЗапуститьПриложение(КомандаЗапуска, , Истина); // Ждем завершения

После выполнения этой команды в каталоге ПутьВыгрузки появятся файлы, соответствующие внутренним потокам CFB. Теперь мы можем прочитать их обычными средствами 1С (например, ЧтениеТекста), ориентируясь на имена файлов (теги MAPI).

Способ 2: Работа через COM-объекты (Outlook и Redemption)

Если на компьютере установлен Microsoft Outlook, мы можем не разбирать бинарную структуру вручную, а воспользоваться объектной моделью приложения. Выясним, как это сделать программно:


OutlookПриложение = Новый COMОбъект("Outlook.Application");
Namespace = OutlookПриложение.GetNamespace("MAPI");
ОбъектПисьмо = OutlookПриложение.Session.OpenSharedItem("C:\Temp\mail.msg");

Сообщить("Тема письма: " + ОбъектПисьмо.Subject);
Сообщить("Текст: " + ОбъектПисьмо.Body);

// Работа с вложениями
Для Каждого Вложение Из ОбъектПисьмо.Attachments Цикл
    Вложение.SaveAsFile("C:\Temp\Attachments\" + Вложение.FileName);
КонецЦикла;

Важный нюанс: использование Outlook требует его наличия на сервере или клиенте, что не всегда возможно. В качестве альтернативы часто упоминается библиотека Redemption. Она позволяет работать с .msg файлами без установленного Outlook, предоставляя удобный COM-интерфейс, однако стоит учитывать, что это стороннее платное решение.

Способ 3: Интеграция с Python и библиотекой olefile

Проанализируем ситуацию, когда нам нужно кроссплатформенное и бесплатное решение. В сообществе разработчиков стандартом для работы с CFB является библиотека olefile на языке Python. Если на сервере установлен Python, мы можем написать скрипт-прослойку, который будет разбирать файл и возвращать JSON или XML в 1С.

Пример логики скрипта на Python:


import olefile

ole = olefile.OleFileIO('example.msg')
if ole.exists('__substg1.0_0037001F'): # Тег для темы сообщения
    subject = ole.openstream('__substg1.0_0037001F').read().decode('utf-16')
    print(subject)
ole.close()

Из 1С такой скрипт запускается через ЗапуститьПриложение, а результат считывается из текстового файла или потока вывода.

Способ 4: Использование объектов 1С "ЧтениеДанных" и "БуферДвоичныхДанных"

Начиная с версии платформы 8.3.10, в 1С появились мощные инструменты для работы с бинарными потоками. Хотя написание полного парсера CFB на языке 1С — задача крайне трудоемкая, мы можем использовать эти инструменты для поиска конкретных сигнатур или извлечения «сырых» данных. Рассмотрим, как прочитать заголовок файла для проверки, является ли он Compound файлом (сигнатура D0 CF 11 E0 A1 B1 1A E1):


Файл = Новый Файл("C:\Temp\Document.msg");
Поток = Файл.ОткрытьПотокЧтения();
Чтение = Новый ЧтениеДанных(Поток);

// Читаем первые 8 байт сигнатуры
Буфер = Чтение.ПрочитатьВБуферДвоичныхДанных(8);
СтрокаСигнатуры = НСтр(НРег(ПолучитьГексСтрокуИзБуфера(Буфер)));

Если Найти(СтрокаСигнатуры, "d0cf11e0a1b11ae1") > 0 Тогда
    Сообщить("Это валидный Compound File Binary");
КонецЕсли;

Поток.Закрыть();

Этот метод подходит, если вам нужно реализовать быструю проверку или если структура файла вам заранее известна и вы планируете искать данные по смещениям (офсетам).

Способ 5: PowerShell как связующее звено

В среде Windows мы можем воспользоваться PowerShell для доступа к .NET-классам. Это позволяет избежать регистрации COM-объектов. Выясним, как это помогает в работе с CFB. Через PowerShell можно обратиться к системным функциям ole32.dll (Structured Storage API). Скрипт PowerShell может быть вызван из 1С, выполнить распаковку потоков и завершить работу, вернув управление платформе.

Резюме и рекомендации

Выбор метода зависит от ваших условий эксплуатации:

Разбор Compound File Binary — задача непростая, но наличие разнообразных инструментов позволяет подобрать оптимальный путь для любого проекта на базе 1С:Предприятие.

← На главную