Запуск EXE, PDF и других файлов из кода 1С

· 9 мин

Содержание

Чаще всего ломается одно: код пишут на сервере, а файл ищут на компьютере пользователя. Запустить внешний файл из 1С можно одной строкой, но только в клиентском контексте: программа стартует на той машине, где выполняется код. Вызвали из серверной процедуры, получили запуск на сервере, а пользователь ничего не увидел.

Запустить внешний файл или программу из 1С: Предприятие позволяют три инструмента. ЗапуститьПриложение работает синхронно, НачатьЗапускПриложения не блокирует интерфейс, КомандаСистемы отдаёт команду оболочке. Ниже разобрано, чем они отличаются, как передать параметры, открыть PDF или Excel по ассоциации, работать в клиент-серверной базе и веб-клиенте, а потом найти причину, если ничего не открылось.

Три способа запуска и когда какой брать

СпособЧто делаетОграничения
ЗапуститьПриложениеЗапускает программу, может дождаться завершения и вернуть код возвратаБлокирует сеанс, недоступен в веб-клиенте
НачатьЗапускПриложенияТо же, но асинхронно, результат приходит в оповещениеНужно описание оповещения, код сложнее
КомандаСистемыПередаёт строку командному процессору, окно консоли скрытоНет гарантии поведения в безопасном режиме и на всех клиентах

Для нового кода выбирайте асинхронный вариант: платформа развивается в сторону неблокирующих вызовов, а веб-клиент синхронные методы не поддерживает вовсе. Синхронный ЗапуститьПриложение остаётся рабочим на тонком и толстом клиенте и проще в отладке.

Все три метода выполняются на клиенте. В серверном модуле их нет смысла вызывать: пользователь программу не получит.

Метод ЗапуститьПриложение: синтаксис и примеры

Полная форма вызова:

ЗапуститьПриложение(СтрокаЗапуска, ТекущийКаталог, ОжидатьЗавершения, КодВозврата);
  • СтрокаЗапуска — путь к программе и её параметры одной строкой.
  • ТекущийКаталог — рабочая папка запускаемой программы. Необязательный.
  • ОжидатьЗавершения — если Истина, 1С стоит и ждёт, пока процесс закроется.
  • КодВозврата — сюда программа запишет код завершения. Нулевой код обычно означает успех.

Простейший пример, блокнот без ожидания:

ЗапуститьПриложение("notepad.exe");

А вот запуск с ожиданием и проверкой результата:

КодВозврата = 0;
ЗапуститьПриложение("""C:\Утилиты\конвертер.exe"" in.csv out.xml",
    "C:\Утилиты", Истина, КодВозврата);
Если КодВозврата <> 0 Тогда
    ВызватьИсключение "Конвертер завершился с кодом " + КодВозврата;
КонецЕсли;

Обратите внимание на тройные кавычки: в строке 1С двойные кавычки экранируются удвоением, поэтому путь в кавычках внутри строки пишется как """путь""". Это нужно, если в пути есть пробел, например C:\Program Files\.... Без кавычек Windows разберёт путь по первому пробелу и запустит не то.

Асинхронный вариант

Современный код выглядит так:

&НаКлиенте
Процедура ЗапуститьУтилиту()
    Оповещение = Новый ОписаниеОповещения("ПослеЗапуска", ЭтотОбъект);
    НачатьЗапускПриложения(Оповещение, "C:\Утилиты\конвертер.exe in.csv", , Истина);
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗапуска(КодВозврата, ДополнительныеПараметры) Экспорт
    Если КодВозврата <> 0 Тогда
        Сообщить("Программа вернула код " + КодВозврата);
    КонецЕсли;
КонецПроцедуры

Интерфейс при этом не замирает. Обработчик сработает, когда программа закроется (если вы просили ждать завершения).

Нужна гарантия, что результат готов, прежде чем идти дальше? Продолжение логики кладите в процедуру-оповещение, а не после вызова. Строка кода после НачатьЗапускПриложения выполнится сразу, не дожидаясь программы.

Клиент и сервер: откуда берётся файл

В файловой базе клиент и сервер живут на одной машине, и путь C:\Отчёты\акт.pdf работает везде. В клиент-серверной базе всё иначе: сервер 1С стоит отдельно, а программу нужно запустить у пользователя.

Типичная ловушка: файл сформирован на сервере и лежит в каталоге сервера. Путь \\srv\share\акт.pdf клиент увидит только если сетевая папка доступна пользователю по правам. Надёжный путь такой:

  1. На сервере поместите файл в временное хранилище (ПоместитьВоВременноеХранилище) вместе с двоичными данными.
  2. На клиенте получите адрес и скачайте файл в локальный каталог.
  3. Запустите приложение уже по локальному пути.

Схема на клиенте:

&НаКлиенте
Процедура ОткрытьФайл(АдресХранилища, ИмяФайла)
    ПолучитьФайл(АдресХранилища, ИмяФайла, Ложь);
    // дальше путь к сохранённому файлу передаётся в запуск
КонецПроцедуры

Временные файлы удобно складывать во временный каталог пользователя (КаталогВременныхФайлов()), а не в корень диска. Так не возникнет проблем с правами записи и мусор уберёт система.

Метод ПолучитьФайл с интерактивным режимом может показать диалог выбора каталога. Если нужна тишина, задайте имя файла явно и параметр интерактивности Ложь.

Если вы пишете обработку под терминальный сервер (RDP), помните: «клиент» там это сеанс на самом терминальном сервере, и запуск программы идёт внутри пользовательского сеанса, а не на рабочей станции за экраном.

Прямой запуск EXE с параметрами

Параметры идут через пробел после пути к исполняемому файлу. Если значение содержит пробелы, оно тоже берётся в кавычки:

Команда = """C:\Program Files\7-Zip\7z.exe"" a ""C:\Архив\отчёт.zip"" ""C:\Отчёты\акт 1.xlsx""";
ЗапуститьПриложение(Команда, , Истина, КодВозврата);

Здесь каждая кавычка экранирована удвоением, поэтому глазами строку читать неудобно. Соберите её по частям:

Программа = """" + ПутьКПрограмме + """";
Аргумент1 = """" + ИсходныйФайл + """";
Команда = Программа + " a " + Аргумент1;

Так проще искать ошибки, и в журнал можно вывести готовую команду целиком.

Что делать, если нужна оболочка

Встроенные команды Windows (dir, copy, del) не являются файлами. Для них нужен командный процессор:

КомандаСистемы("cmd /c copy C:\a.txt C:\b.txt");

Ключ /c выполняет команду и завершает процессор. У КомандаСистемы окно консоли не появляется, а вывод программы можно перенаправить в файл через > и прочитать после выполнения.

Bat-файлы и скрипты запускаются так же, через cmd /c. Для PowerShell обычно передают powershell -File "путь". Политики выполнения на машине пользователя могут запретить скрипт: это уже настройка Windows, а не 1С.

Безопасность

Не собирайте командную строку из данных, которые ввёл пользователь, без проверки. Строка вида программа.exe + введённое имя позволит подставить & del .... Проверяйте имя файла по списку допустимых символов, а путь к программе держите константой или настройкой, доступной только администратору.

Открытие документов через ассоциации Windows

Нужно открыть PDF, DOCX или XLSX в программе по умолчанию? Название программы знать не требуется: передайте путь к самому файлу.

ЗапуститьПриложение("""C:\Отчёты\акт.pdf""");

Windows подберёт приложение по расширению, так же, как при двойном щелчке в проводнике. Чтобы то же самое сделать асинхронно, используйте НачатьЗапускПриложения с путём к документу.

Нюансы:

  • ⚠️ Если для расширения нет назначенной программы, Windows покажет диалог выбора или ничего не откроет. 1С не получит ошибки.
  • 📄 Ожидание завершения для документов не гарантирует ничего. Многие программы (Word, браузер) передают файл уже запущенному экземпляру и закрывают процесс-посредник сразу.
  • 🔒 Открытый в Excel файл блокируется. Повторная запись под тем же именем даст ошибку доступа, поэтому для каждого открытия формируйте уникальное имя (например, с датой и временем).

Для файлов, лежащих в самой базе (присоединённые файлы), в типовых конфигурациях есть готовые подсистемы работы с файлами: они сами скачивают файл и открывают его. Если нужное решение уже есть в «Библиотеке стандартных подсистем», писать своё не нужно.

Простой вариант для печатных форм

Если нужно просто показать табличный документ пользователю, запускать внешнюю программу не обязательно. Вызовите метод Показать() у табличного документа, а для сохранения в PDF или XLSX используйте Записать() с нужным типом формата и откройте результат по ассоциации.

Браузер и ссылки

Для адреса в интернете внешнюю программу вызывать не нужно:

ПерейтиПоНавигационнойСсылке("https://example.com/page");

Метод откроет ссылку в браузере по умолчанию. Он работает в тонком клиенте и в веб-клиенте (в вебе откроется новая вкладка, если её не заблокировал браузер).

Если нужен конкретный браузер или режим окна, запускайте его как обычную программу:

ЗапуститьПриложение("""C:\Program Files\Google\Chrome\Application\chrome.exe"" --new-window https://example.com");

Ключ --new-window — параметр Chrome, он открывает ссылку в отдельном окне. Для других браузеров ключи свои, смотрите справку программы.

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

Хотите определить, где вы запущены, чтобы выбрать способ? Используйте директивы компиляции #Если ВебКлиент Тогда ... #Иначе ... #КонецЕсли.

Диагностика: почему файл не открылся

Метод ничего не вернул и не выдал ошибку? Сверяйтесь с таблицей.

Диагностика: выберите симптом

Как перехватить ошибку в коде

Оборачивайте вызов в Попытка ... Исключение, а текст ошибки пишите в журнал регистрации:

Попытка
    ЗапуститьПриложение(Команда, , Истина, КодВозврата);
Исключение
    ЗаписьЖурналаРегистрации("ЗапускПрограммы", УровеньЖурналаРегистрации.Ошибка, ,
        , ОписаниеОшибки());
    Сообщить("Не удалось запустить программу, подробности в журнале регистрации.");
КонецПопытки;

Так вы увидите причину, даже если пользователь просто скажет «не работает ». Саму команду тоже стоит записать в комментарий события: половина проблем решается, как только видно реальную строку с путём.

Частые ошибки и как их избежать

  • 📂 Путь с пробелами без кавычек. Всегда берите путь к программе в кавычки, даже если сегодня он без пробелов: завтра её поставят в Program Files.
  • 🖥️ Серверный код вместо клиентского. Если метод «ничего не делает», проверьте директиву &НаКлиенте у процедуры.
  • ⏳ Бесконечное ожидание. ОжидатьЗавершения = Истина с программой, которая не закрывается сама (блокнот, Word), подвесит сеанс. Для таких случаев ожидание не нужно.
  • 🔁 Жёсткие пути. Не прописывайте C:\Users\Иван\.... Берите каталог из КаталогВременныхФайлов() или из настроек.
  • 🧾 Забытая очистка. Скачанные во временный каталог файлы не удаляются сами при каждом запуске обработки: убирайте их после закрытия или периодически.

Не уверены, что всё предусмотрено? Пройдитесь по короткому списку перед выкладкой обработки пользователям:

Перед передачей обработки пользователям
Выполнено: 0 / 6

Частые вопросы

Можно ли запустить программу на сервере 1С из клиентского кода?
Прямо нет: клиентские методы запускают процесс на машине клиента. Для задач на сервере используют серверные механизмы платформы и службы самой операционной системы; решение зависит от задачи и политики безопасности.
Чем `НачатьЗапускПриложения` лучше `ЗапуститьПриложение`?
Он не блокирует интерфейс и подходит там, где синхронные вызовы запрещены. Платформа вызывает ваше оповещение, когда программа закрылась.
Как открыть папку в проводнике?
Передайте путь к папке в кавычках в ЗапуститьПриложение с программой explorer. Проводник откроет её в новом окне. Код возврата у проводника ненадёжный, не опирайтесь на него.
Работает ли запуск файла в мобильном клиенте?
Ограничения мобильной платформы отличаются от десктопных. Проверяйте нужный сценарий на своём устройстве: общего гарантированного поведения здесь нет.
Почему антивирус блокирует запуск из 1С?
Часть защитных программ запрещает запуск исполняемых файлов из «чужих» процессов и скриптовых интерпретаторов. Добавьте нужную программу в исключения по согласованию с администратором безопасности.