КоллекцияСтраницPDF

Типы · PDFPagesCollection

Предоставляет методы для работы со страницами PDF-документа.

Полное описание, параметры и ограничения

КоллекцияСтраницPDF (PDFPagesCollection)

КоллекцияСтраницPDF (PDFPagesCollection)

Доступен, начиная с версии 8.3.26.

Элементы коллекции:
СтраницаPDF
Для объекта доступен обход коллекции посредством оператора Для каждого … Из … Цикл. При обходе выбираются страницы документа PDF.
Возможно обращение к странице документа PDF посредством оператора [...]. В качестве аргумента передается .

Методы:
Индекс (IndexOf)
Количество (Count)
Получить (Get)

Описание:

Предоставляет методы для работы со страницами PDF-документа.

Доступность:

Тонкий клиент, веб-клиент, сервер, толстый клиент.

Использование в версии:

Доступен, начиная с версии 8.3.26.

Методическая информация

Практические примеры

Создать настоящий учебный PDF и разобрать страницу

Экспортируем таблицу Книга / 3 / 250 / 750 и читаем PDF обратно. Индекс коллекции начинается с нуля, номер страницы — с единицы.

Где и как запускать

Полный серверный общий модуль УчебныйPDF собственной учебной конфигурации; только собственные PDF-байты в памяти.

Подготовка

  1. Отдельная собственная учебная база 8.5.1.1343: серверный общий модуль УчебныйPDF. Вставьте полный модуль одного урока и вызовите ВыполнитьПример() своей серверной командой.

  2. Имя конфигурации должно быть УчебнаяКонфигурацияСинтаксиса. Все данные создаются кодом: строка Книга / 3 / 250 / 750 и собственные текстовые вложения.

  3. Исходный PDF получается настоящим экспортом собственного ТабличныйДокумент в ПотокВПамяти. Никакого файла с неизвестным происхождением или рабочего печатного макета не требуется.

  4. Чтение и повторная запись выполняются в памяти. Примеры не печатают, не обращаются к интернету и не меняют документы базы.

  5. Проверки размеров, страниц и вложений не доказывают вид штампа или оттенки серого. Для визуального контроля используйте отдельный урок просмотра собственного PDF; этот серверный модуль окна не открывает.

Функция СоздатьСобственныеБайтыPDF()
    Таблица = Новый ТабличныйДокумент;
    Таблица.КодЯзыка = "ru";
    Таблица.Область(1, 1).Текст = "СОБСТВЕННЫЙ УЧЕБНЫЙ ОБРАЗЕЦ";
    Таблица.Область(2, 1).Текст = "Книга";
    Таблица.Область(2, 2).Текст = "3";
    Таблица.Область(2, 3).Текст = "250";
    Таблица.Область(2, 4).Текст = "750";
    Таблица.Область(1, 1, 2, 4).ЦветФона = Новый Цвет(255, 255, 210);
    Таблица.Область(, 1, , 1).ШиринаКолонки = 45;
    Поток = Новый ПотокВПамяти;
    Попытка
        Таблица.Записать(Поток, ТипФайлаТабличногоДокумента.PDF);
        Данные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
    Исключение
        Поток.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Возврат Данные;
КонецФункции

Функция ПрочитатьСобственныйДокумент(Данные)
    Поток = Данные.ОткрытьПотокДляЧтения();
    Попытка
        Документ = Новый ДокументPDF;
        Документ.Прочитать(Поток);
        Поток.Закрыть();
    Исключение
        Поток.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Возврат Документ;
КонецФункции

Процедура ВыполнитьПример() Экспорт
    Данные = СоздатьСобственныеБайтыPDF();
    Документ = ПрочитатьСобственныйДокумент(Данные);
    Страницы = Документ.Страницы;
    Сообщить(Данные.Размер() > 0);
    Сообщить(Страницы.Количество() = Документ.КоличествоСтраниц());
    Если Страницы.Количество() = 0 Тогда
        ВызватьИсключение "В собственном PDF нет страниц";
    КонецЕсли;
    Первая = Страницы.Получить(0);
    Сообщить(Первая.Номер = 1);
    Сообщить(Страницы.Индекс(Первая) = 0);
    Сообщить(Первая.Ширина > 0 И Первая.Высота > 0);
    Сообщить(ТипЗнч(Первая.Ориентация) = Тип("Число"));
    Сообщить(Первая.ПолеСверху >= 0 И Первая.ПолеСнизу >= 0);
    Сообщить(Первая.ПолеСлева >= 0 И Первая.ПолеСправа >= 0);
    Сообщить("Размер страницы, мм: " + Строка(Первая.Ширина) + " × " + Строка(Первая.Высота));
    Сообщить("Угол, градусы: " + Строка(Первая.Ориентация));
    Сообщить("Формат PDF: " + Строка(Документ.ТипФайла));
    Сообщить(Документ.Вложения.Количество() = 0);
КонецПроцедуры

Разбор по шагам

  1. Создать табличный документ и экспортировать в поток. Получить ДвоичныеДанные вместе с закрытием исходного потока.

  2. Открыть отдельный поток чтения, прочитать ДокументPDF и закрыть поток. Сам документ продолжает хранить прочитанные данные.

  3. Сверить количество страниц двумя настоящими API. Проверить наличие хотя бы одной страницы перед Получить(0).

  4. Прочитать номер, размеры, угол и четыре поля. Все свойства страницы только для чтения; мм и градусы — разные единицы.

Как проверить результат

  1. Девять булевых проверок должны дать Истина. Получить(0).Номер = 1 и Индекс(Первая) = 0.

  2. Выводятся реальные размеры и угол собственной страницы, а не зашитое предположение A4. Вложений исходного документа нет.

Ожидаемый результат

Полный путь от собственной таблицы к настоящему PDF и читаемому паспорту страницы.

На что обратить внимание

  1. Количество страниц зависит от вывода таблицы, размеров и настроек; не переносите ожидание одной страницы на произвольный отчёт.

  2. Ориентация страницы PDF — числовой угол, а не перечисление Портрет/Альбом и не Булево.

  3. СтраницаPDF не имеет конструктора и изменяемых размеров. Коллекция страниц не имеет Добавить, Удалить или Очистить.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Асинхронно подписать свой PDF и получить реальные результаты проверки в тонком клиенте

Полный модуль собственной формы получает свои PDF-байты с сервера, использует явно подготовленный CurrentUser-ключ, ждёт подпись/запись/чтение и проверяет реальные Array/Certificate-результаты Promise. Ни Promise, ни выходные параметры синхронных overloads не подменяют готовый результат.

Где и как запускать

Полный модуль управляемой формы собственного тонкого Windows-клиента: PDF-операции с Ждать, отдельный полный supporting-серверный модуль для генерации своих байтов. В1С не запускался.

Подготовка

  1. НОВАЯ пустая файловая учебная база УчебнаяАсинхроннаяПодписьPDF85 на8.5.1.1343, совместимость Не использовать. Только свои модуль и форма; без рабочих объектов, расширений, подписок/заданий. Запускать под ОТДЕЛЬНЫМ собственным Windows-пользователем или в отдельном учебном Windows-стенде без рабочих сертификатов. Не серверный кластер под служебной учётной записью.

  2. Для будущей ручной подготовки отключите сеть учебного стенда. Все операции подписи локальны, TSA-массив в коде явно пуст. Команды создания ключа ниже НЕ выполнялись при подготовке справочника; они создают собственный сертификат и закрытый ключ в Личном текущего учебного Windows-пользователя.

  3. Откройте Windows PowerShell в своём отдельном учебном профиле, не от администратора рабочего сервера. В одной и той же консоли вручную выполните последовательно только следующие четыре команды; не закрывайте её между командами. Провайдер Microsoft Enhanced RSA and AES Cryptographic Provider должен существовать и иметь Type24. CNG-провайдер по умолчанию не подставлять вместо него.

  4. Ручная команда 1: $pdfTrainingId = [guid]::NewGuid().ToString("D")

  5. Ручная команда 2: $pdfTrainingCert = New-SelfSignedCertificate -Type Custom -Subject ("CN=Syntax Guide PDF Own85 " + $pdfTrainingId) -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -KeySpec Signature -KeyAlgorithm RSA -KeyLength 2048 -KeyUsage DigitalSignature -HashAlgorithm SHA256 -KeyExportPolicy NonExportable -CertStoreLocation "Cert:\CurrentUser\My" -NotAfter (Get-Date).AddMonths(1)

  6. Ручная команда 3: if (-not $pdfTrainingCert.HasPrivateKey) { throw "Own training private key was not created" }

  7. Ручная команда 4: [pscustomobject]@{TrainingId=$pdfTrainingId;ThumbprintHex=$pdfTrainingCert.Thumbprint;OwnPrivateKey=$pdfTrainingCert.HasPrivateKey;Subject=$pdfTrainingCert.Subject}

  8. Сохраните показанные TrainingId и ThumbprintHex для этой попытки. OwnPrivateKey должен быть True, Subject должен содержать только Syntax Guide PDF Own85 и ваш новый TrainingId. Ключ не экспортируется в PFX и не печатается. Сертификат самоподписанный и не добавляется в доверенные корневые.

  9. Команды и различие legacy CSP/KeySpec=Signature сверены с официальной документацией Microsoft New-SelfSignedCertificate: https://learn.microsoft.com/en-us/powershell/module/pki/new-selfsignedcertificate?view=windowsserver2025-ps. Это документирование будущего учебного опыта, не выполненное создание ключа.

  10. Учебный сертификат и ключ остаются в собственном Windows-профиле после закрытия1С; урок их автоматически не удаляет. Администратор отдельного стенда отвечает за его очистку после обучения. Не переносите опыт в рабочий профиль и не выдавайте закрытие формы за удаление ключа.

  11. Ни PowerShell-команды, ни CryptoAPI/1С, ни AddSignature, ни GUI/сервер/ключи/подпись здесь не запускались. runtimeVerifiedScenarios=0.

  12. Используйте именно тонкий Windows-клиент собственной файловой базы8.5.1.1343. В конфигурации разрешите синхронные вызовы расширений платформы/внешних компонент: сведения, инициализация CryptoAPI и поиск своего сертификата здесь синхронные. Асинхронны PDF-операции; это не обещание полностью неблокирующего криптографического стека.

  13. Основной код теперь вставляется В МОДУЛЬ ФОРМЫ, не в серверный общий модуль. Своя управляемая форма: реквизиты МеткаСертификата85 Строка100, ОтпечатокHex85 Строка40, ПодтверждаюСвойСтенд Булево начально Ложь, Занято Булево начально Ложь, Отчёт Строка0. Поля с теми же путями; Занято не редактировать, Отчёт многострочный ТолькоПросмотр=Да. Команда/кнопка Выполнить, действие Выполнить. Вставьте весь основной модуль, сохранить/F7, открыть свою форму и скопировать фактические TrainingId/ThumbprintHex.

  14. В общий серверный модуль УчебнаяАсинхроннаяПодписьPDF85 вставьте ТОЛЬКО supporting-модуль ниже. Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Он проверяет свою пустую конфигурацию и экспортирует только собственную таблицу в байты. Подписание/ключевой контейнер работают у своего текущего Windows-клиента, не у учётной записи рабочего сервера.

  15. Во время Ждать не закрывайте форму и не меняйте поля источника ключа. Метка/отпечаток копируются в локальные переменные до ожидания, Занято запрещает повторный старт; флаг очищается и при успехе, и при ошибке. Веб-/мобильный клиент и установка расширений не входят в этот опыт.

&НаКлиенте
Функция ПодготовитьСвойМенеджер()
    Информация = СредстваКриптографии.ПолучитьИнформациюМодуляКриптографии("Microsoft Enhanced RSA and AES Cryptographic Provider", "", 24);
    Если Информация = Неопределено Или ТипЗнч(Информация) <> Тип("ИнформацияМодуляКриптографии") Тогда
        ВызватьИсключение "На своём Windows-стенде не найден требуемый провайдер";
    КонецЕсли;
    Если Информация.ТипМодуляКриптографии <> 24 Тогда
        ВызватьИсключение "Нужен фактический CryptoAPI-провайдер типа24";
    КонецЕсли;
    АлгоритмSHA256 = "";
    Для Каждого Алгоритм Из Информация.АлгоритмыХеширования Цикл
        Если НРег(Алгоритм) = "sha256" Или НРег(Алгоритм) = "sha-256" Или Алгоритм = "2.16.840.1.101.3.4.2.1" Тогда
            АлгоритмSHA256 = Алгоритм;
        КонецЕсли;
    КонецЦикла;
    Если АлгоритмSHA256 = "" Тогда
        ВызватьИсключение "Свой провайдер не подтвердил SHA256; другое имя не подставлять наугад";
    КонецЕсли;
    Менеджер = Новый МенеджерКриптографии("Microsoft Enhanced RSA and AES Cryptographic Provider", "", 24, ИспользованиеИнтерактивногоРежимаКриптографии.НеИспользовать);
    Менеджер.АлгоритмХеширования = АлгоритмSHA256;
    Менеджер.ВключениеСертификатовВПодпись = РежимВключенияСертификатовКриптографии.ВключатьСертификатСубъекта;
    Менеджер.АдресаСерверовМетокВремени = Новый Массив;
    Если Менеджер.АдресаСерверовМетокВремени.Количество() <> 0 Тогда
        ВызватьИсключение "Урок не должен обращаться к внешнему серверу меток времени";
    КонецЕсли;
    Возврат Менеджер;
КонецФункции

&НаКлиенте
Функция НайтиСвойСертификат(Менеджер, Метка, ОтпечатокHex)
    Если СтрДлина(ОтпечатокHex) <> 40 Тогда
        ВызватьИсключение "Скопируйте весь SHA1-отпечаток из собственного PowerShell-опыта без пробелов";
    КонецЕсли;
    Отпечаток = ПолучитьДвоичныеДанныеИзHexСтроки(ОтпечатокHex);
    Если Отпечаток.Размер() <> 20 Тогда
        ВызватьИсключение "SHA1-отпечаток должен содержать20байт";
    КонецЕсли;
    Хранилище = Менеджер.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты,
        РасположениеХранилищаСертификатовКриптографии.ДанныеПользователяОС);
    Сертификат = Хранилище.НайтиПоОтпечатку(Отпечаток);
    Если Сертификат = Неопределено Или ТипЗнч(Сертификат) <> Тип("СертификатКриптографии") Тогда
        ВызватьИсключение "В собственном текущем Windows-профиле не найден именно созданный учебный сертификат";
    КонецЕсли;
    Если Base64Строка(Сертификат.Отпечаток) <> Base64Строка(Отпечаток) Тогда
        ВызватьИсключение "Найден не свой точный отпечаток";
    КонецЕсли;
    CN = Неопределено;
    Если Не Сертификат.Субъект.Свойство("CN", CN) Тогда
        ВызватьИсключение "Нет собственного CN учебного сертификата";
    КонецЕсли;
    Если CN <> "Syntax Guide PDF Own85 " + Метка Тогда
        ВызватьИсключение "CN должен совпасть с собственной уникальной меткой подготовки ключа";
    КонецЕсли;
    Возврат Сертификат;
КонецФункции

&НаКлиенте
Функция ПодготовитьСвоюПодпись(Документ, Сертификат, Метка)
    Если Документ.КоличествоСтраниц() = 0 Тогда
        ВызватьИсключение "Нужен собственный PDF с реальной первой страницей";
    КонецЕсли;
    Страница = Документ.Страницы.Получить(0);
    Если Страница.Ориентация <> 0 Или Страница.Ширина - Страница.ПолеСлева - Страница.ПолеСправа < 80
        Или Страница.Высота - Страница.ПолеСверху - Страница.ПолеСнизу < 60 Тогда
        ВызватьИсключение "Собственная неповёрнутая страница должна вместить штамп10/45/70/15мм";
    КонецЕсли;
    Описание = Новый ОписаниеПодписиPDF;
    Описание.Имя = "СвояПодпись85_" + Метка;
    Описание.Сертификат = Сертификат;
    Описание.ТипПодписи = ТипПодписиPDF.Утверждающая;
    Описание.БлокировкаДокумента = Ложь;
    Описание.НомерСтраницы = 1;
    Описание.Лево = 10;
    Описание.Верх = 45;
    Описание.Ширина = 70;
    Описание.Высота = 15;
    Возврат Описание;
КонецФункции

&НаКлиенте
Асинх Функция ПрочитатьСвоиБайтыАсинх(Данные)
    Поток = Данные.ОткрытьПотокДляЧтения();
    Попытка
        Документ = Новый ДокументPDF;
        Ждать Документ.ПрочитатьАсинх(Поток, "");
    Исключение
        ОшибкаОперации = ОписаниеОшибки();
        Попытка
            Поток.Закрыть();
        Исключение
            ОшибкаОперации = ОшибкаОперации + " Закрытие своего входного потока: " + ОписаниеОшибки();
        КонецПопытки;
        ВызватьИсключение ОшибкаОперации;
    КонецПопытки;
    Поток.Закрыть();
    Возврат Документ;
КонецФункции

&НаКлиенте
Асинх Функция ЗаписатьСвоиБайтыАсинх(Документ)
    Поток = Новый ПотокВПамяти;
    Попытка
        Ждать Документ.ЗаписатьАсинх(Поток, "", ТипФайлаДокументаPDF.PDF);
        Данные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
    Исключение
        ОшибкаОперации = ОписаниеОшибки();
        Попытка
            Поток.Закрыть();
        Исключение
            ОшибкаОперации = ОшибкаОперации + " Закрытие своего выходного потока: " + ОписаниеОшибки();
        КонецПопытки;
        ВызватьИсключение ОшибкаОперации;
    КонецПопытки;
    Возврат Данные;
КонецФункции

&НаКлиенте
Процедура ПроверитьСвойОтветСертификата(Результат, Сертификат)
    Если ТипЗнч(Результат) <> Тип("СертификатКриптографии")
        Или Base64Строка(Результат.Отпечаток) <> Base64Строка(Сертификат.Отпечаток) Тогда
        ВызватьИсключение "Await должен вернуть включённый сертификат собственного субъекта";
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьСвоиБайтыНаСервере()
    Возврат УчебнаяАсинхроннаяПодписьPDF85.ПолучитьСвоиБайтыPDF();
КонецФункции

&НаКлиенте
Асинх Процедура Выполнить(Команда)
    Если Занято Тогда
        ВызватьИсключение "Дождитесь завершения своей текущей операции";
    КонецЕсли;
    Система = Новый СистемнаяИнформация;
    Если (Система.ТипПлатформы <> ТипПлатформы.Windows_x86 И Система.ТипПлатформы <> ТипПлатформы.Windows_x86_64) Тогда
        ВызватьИсключение "Нужен собственный тонкий Windows-клиент8.5.1.1343";
    КонецЕсли;
    Если Не ПодтверждаюСвойСтенд Тогда
        ВызватьИсключение "Подтвердите только использование своего отдельного ключевого стенда";
    КонецЕсли;
    Метка = МеткаСертификата85;
    ОтпечатокHex = ОтпечатокHex85;
    UUID = Новый УникальныйИдентификатор(Метка);
    Если Строка(UUID) <> Метка Тогда
        ВызватьИсключение "Скопируйте фактическую метку собственного учебного сертификата";
    КонецЕсли;
    Занято = Истина;
    Отчёт = "Собственная операция ещё не завершена";
    Попытка
        ДанныеPDF = ПолучитьСвоиБайтыНаСервере();
        Документ = Ждать ПрочитатьСвоиБайтыАсинх(ДанныеPDF);
        Менеджер = ПодготовитьСвойМенеджер();
        Сертификат = НайтиСвойСертификат(Менеджер, Метка, ОтпечатокHex);
        ДоПодписания = Ждать Документ.ПолучитьОписанияПодписейАсинх(Менеджер);
        Если ТипЗнч(ДоПодписания) <> Тип("Массив") Или ДоПодписания.Количество() <> 0 Тогда
            ВызватьИсключение "Собственный исходный PDF не должен содержать прежних подписей";
        КонецЕсли;
        Описание = ПодготовитьСвоюПодпись(Документ, Сертификат, Метка);
        Штамп = Новый ТабличныйДокумент;
        Штамп.Область(1, 1).Текст = "УЧЕБНЫЙ АСИНХРОННЫЙ САМОПОДПИСАННЫЙ ОБРАЗЕЦ";
        Ждать Документ.ДобавитьПодписьАсинх(Менеджер, Описание, Штамп, Истина);
        ПодписанныеБайты = Ждать ЗаписатьСвоиБайтыАсинх(Документ);
        Если ПодписанныеБайты.Размер() = 0 Тогда
            ВызватьИсключение "Не получены собственные подписанные PDF-байты";
        КонецЕсли;
        Копия = Ждать ПрочитатьСвоиБайтыАсинх(ПодписанныеБайты);
        Описания = Ждать Копия.ПолучитьОписанияПодписейАсинх(Менеджер);
        Если ТипЗнч(Описания) <> Тип("Массив") Или Описания.Количество() <> 1 Тогда
            ВызватьИсключение "Из новых PDF-байтов должно вернуться одно описание собственной подписи";
        КонецЕсли;
        Подпись = Описания[0];
        Если ТипЗнч(Подпись) <> Тип("ОписаниеПодписиPDF") Или Подпись.Имя <> Описание.Имя Тогда
            ВызватьИсключение "Await описаний не вернул именно собственную добавленную подпись";
        КонецЕсли;
        ПроверитьСвойОтветСертификата(Подпись.Сертификат, Сертификат);
        ДатаПодписи = Подпись.Дата;
        Если ТипЗнч(ДатаПодписи) <> Тип("Дата") Или ДатаПодписи = Дата(1, 1, 1) Тогда
            ВызватьИсключение "В своём описании нет заполненной native-даты; подстановка текущей даты запрещена";
        КонецЕсли;
        ПроверенныйСертификат = Ждать Копия.ПроверитьПодписьАсинх(Описание.Имя, Менеджер);
        ПроверитьСвойОтветСертификата(ПроверенныйСертификат, Сертификат);
        ВсеСертификаты = Ждать Копия.ПроверитьПодписиАсинх(Менеджер);
        Если ТипЗнч(ВсеСертификаты) <> Тип("Массив") Или ВсеСертификаты.Количество() <> 1 Тогда
            ВызватьИсключение "Await всех подписей должен вернуть один включённый собственный сертификат";
        КонецЕсли;
        ПроверитьСвойОтветСертификата(ВсеСертификаты[0], Сертификат);
        Отчёт = "Все await завершены: собственная подпись и сертификаты проверены. Native-дата: " + Строка(ДатаПодписи)
            + ". Это не доверенная TSA-дата и не правовая оценка";
    Исключение
        Занято = Ложь;
        Отчёт = "Свой асинхронный опыт не завершён: " + ОписаниеОшибки();
        ВызватьИсключение Отчёт;
    КонецПопытки;
    Занято = Ложь;
КонецПроцедуры
УчебнаяАсинхроннаяПодписьPDF85

Конфигуратор → Общие модули → УчебнаяАсинхроннаяПодписьPDF85 → Модуль

Полный серверный общий модуль: защита своего пустого стенда и создание только своих unsigned PDF-байтов в памяти. Не выполнялся.

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Функция СоздатьСобственныеБайтыPDF()
    Таблица = Новый ТабличныйДокумент;
    Таблица.КодЯзыка = "ru";
    Таблица.Область(1, 1).Текст = "СОБСТВЕННЫЙ УЧЕБНЫЙ ОБРАЗЕЦ";
    Таблица.Область(2, 1).Текст = "Книга";
    Таблица.Область(2, 2).Текст = "3";
    Таблица.Область(2, 3).Текст = "250";
    Таблица.Область(2, 4).Текст = "750";
    Таблица.Область(1, 1, 2, 4).ЦветФона = Новый Цвет(255, 255, 210);
    Таблица.Область(, 1, , 1).ШиринаКолонки = 45;
    Поток = Новый ПотокВПамяти;
    Попытка
        Таблица.Записать(Поток, ТипФайлаТабличногоДокумента.PDF);
        Данные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
    Исключение
        Поток.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Возврат Данные;
КонецФункции

Функция ПолучитьСвоиБайтыPDF() Экспорт
    ПроверитьСвойПустойСтенд();
    Возврат СоздатьСобственныеБайтыPDF();
КонецФункции

Разбор по шагам

  1. Клиент проверяет точное имя своей конфигурации, версию/Windows и подтверждение учебного стенда. Supporting-серверный модуль отдельно проверяет отсутствие рабочих объектов/расширений ДО экспорта собственных байтов. Серверная защита не скопирована в контекст тонкого клиента.

  2. Свои байты получают полный реальный источник: собственная таблица Книга/3/250/750 → PDF в ПотокВПамяти на сервере → ДвоичныеДанные в свою форму. Клиент открывает собственный поток чтения и ждёт ПрочитатьАсинх до его закрытия.

  3. Полные клиентские функции проверяют настоящий CryptoAPI Type24/SHA256 и собственный CurrentUser-сертификат по20байтам отпечатка и CN с UUID. ВключатьСертификатСубъекта задан явно, TSA-массив пуст. Файл/ключ с неизвестным источником не принимается.

  4. До подписи Ждать ПолучитьОписанияПодписейАсинх возвращает настоящий Массив: требуется0. Promise без Ждать не имеет готового количества; нельзя сравнить сам Promise с пустым массивом.

  5. Собственное описание проверяет реальную первую страницу и поля, получает свой сертификат/имя и прямоугольник. Ждать ДобавитьПодписьАсинх ждёт завершения создания подписи; никакого нового готового ДокументPDF этот результат не обещает.

  6. Новый выходной ПотокВПамяти передаётся ЗаписатьАсинх с ЯВНЫМ ПУСТЫМ паролем и PDF-форматом. Native-контракт запрещает запись подписанного PDF с непустым паролем. Только после Ждать поток закрывается с получением новых байтов.

  7. Подписанные байты читаются новым независимым ДокументPDF через второй awaited ПрочитатьАсинх. ПолучитьОписанияПодписейАсинх у Копия должен вернуть1 ДО индекса0; сверяются реальный тип, имя, свой отпечаток и readonly native-дата.

  8. Ждать ПроверитьПодписьАсинх(Имя, Менеджер) возвращает СертификатКриптографии. В отличие от синхронного overload, третьего выходного параметра нет. Полученный сертификат проверяется по типу/своему отпечатку, не по непустому представлению.

  9. Ждать ПроверитьПодписиАсинх(Менеджер) возвращает Массив сертификатов. В отличие от синхронного overload, второго выходного параметра нет. Проверяем Array/количество1 ДО индекса0 и тот же фактический отпечаток.

  10. Потоки чтения закрываются после завершившегося await; при исключении ошибка закрытия добавляется к исходной ошибке, не превращает её в успех. Выходной поток закрывается с байтами при успехе и отдельно на ошибке. Флаг Занято восстанавливается независимо от итогового статуса.

  11. Строка успеха появляется только ПОСЛЕ всех awaited операций и сравнений. Ошибка любого этапа формирует отчёт об ошибке и повторно выбрасывается. CA/отзыв/правовая сила и доверенная TSA-дата не обещаются.

Как проверить результат

  1. Будущий результат на полностью подготовленном своём тонком клиенте: исходных подписей0, из новых байтов возвращается1; фактическое имя/сертификат/дата совпадают с собственным источником, оба awaited метода проверки возвращают ожидаемые реальные типы. Занято в конце Ложь.

  2. Будущий отрицательный контроль: у ПроверитьПодписьАсинх временно передайте Описание.Имя + "_отсутствует". Promise должен завершиться ошибкой, отчёт успеха не появиться, Занято вернуться в Ложь. Не заменяйте имя другой подписью автоматически.

  3. Будущий контроль результатов: после Ждать проверки всех подписей временно замените ВсеСертификаты на Новый Массив. Проверка количества должна отказать ДО индекса0, несмотря на ранее завершённые операции.

  4. Будущий контроль источника: перед чтением Копия подайте ДанныеPDF вместо ПодписанныеБайты. Массив описаний будет0 и должен быть отвергнут. Верните новые подписанные байты после опыта.

  5. Будущий контроль повторного старта: вызовите собственную кнопку повторно, пока Занято=Истина. Второй запуск должен отказать до открытия потока/использования ключа. Не закрывайте форму для имитации отмены.

  6. runtimeVerifiedScenarios=0: BSL, тонкий клиент, ключи, подпись, PDF-потоки и GUI здесь не запускались. Успех статических проверок не удостоверяет завершение Promise на конкретном провайдере.

Ожидаемый результат

Все awaited PDF-операции завершены, из новых своих подписанных байтов получены и проверены реальные описание, дата и сертификаты; флаг занятости очищен, доверие/правовая сила не заявлены

На что обратить внимание

  1. Это отдельный урок со своим закрытым ключом, не продолжение опыта с публичным DER Syntax Guide Training Only. Публичный DER из предыдущего урока не может заменить этот ключ.

  2. Создание учебного ключа — осознанное будущее изменение ТОЛЬКО своего изолированного профиля. Оно не выполнялось инструментами этого чата. NonExportable не означает, что ключ исчезнет после опыта или что он доверенный.

  3. Чтение описания/даты — не эквивалент ПроверитьПодпись, проверки CA/отзыва или доверенной TSA-метки. Никакого правового вывода по self-signed образцу не делается.

  4. Текст штампа — визуальное представление, не сама криптографическая подпись. Не обещается, что все PDF-просмотрщики доверяют self-signed сертификату или одинаково показывают штамп.

  5. Ключ принадлежит текущему учебному Windows-клиенту. Сервер создаёт только свои PDF-байты и ключ не использует; ошибка источника не разрешает переключиться на чужой профиль или область ДанныеКомпьютера.

  6. Новый ОписаниеПодписиPDF — настройки до подписи, не источник фактической readonly-даты. Её читаем только из awaited описаний новых подписанных PDF-байтов.

  7. Четыре PDF Async-метода доступны клиенту, не серверу. Синхронные методы подписания/чтения/проверки не вставлены вместо Async в основном модуле формы.

  8. Promise надо дождаться внутри Асинх Процедура/Функция. ПолучитьОписанияПодписейАсинх возвращает Array после ожидания, ПроверитьПодписьАсинх — Certificate, ПроверитьПодписиАсинх — Array; это разные контракты.

  9. Асинхронное ожидание — не фоновая серверная работа и не гарантия, что синхронная инициализация криптографии не блокирует интерфейс. Разрешённый синхронный режим указан явно; браузерные расширения не устанавливаются.

  10. Пустой пароль записи обязателен для этого подписанного образца. Непустой пароль должен вызвать native-ошибку; её нельзя скрыть и вернуть старые байты как новый результат.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.