Запуск EXE, PDF и других файлов из кода 1С
Содержание
Чаще всего ломается одно: код пишут на сервере, а файл ищут на компьютере пользователя. Запустить внешний файл из 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 клиент увидит только если сетевая папка доступна пользователю по правам. Надёжный путь такой:
- На сервере поместите файл в временное хранилище (
ПоместитьВоВременноеХранилище) вместе с двоичными данными. - На клиенте получите адрес и скачайте файл в локальный каталог.
- Запустите приложение уже по локальному пути.
Схема на клиенте:
&НаКлиенте
Процедура ОткрытьФайл(АдресХранилища, ИмяФайла)
ПолучитьФайл(АдресХранилища, ИмяФайла, Ложь);
// дальше путь к сохранённому файлу передаётся в запуск
КонецПроцедуры
Временные файлы удобно складывать во временный каталог пользователя (КаталогВременныхФайлов()), а не в корень диска. Так не возникнет проблем с правами записи и мусор уберёт система.
Метод ПолучитьФайл с интерактивным режимом может показать диалог выбора каталога. Если нужна тишина, задайте имя файла явно и параметр интерактивности Ложь.
Если вы пишете обработку под терминальный сервер (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\Иван\.... Берите каталог изКаталогВременныхФайлов()или из настроек. - 🧾 Забытая очистка. Скачанные во временный каталог файлы не удаляются сами при каждом запуске обработки: убирайте их после закрытия или периодически.
Не уверены, что всё предусмотрено? Пройдитесь по короткому списку перед выкладкой обработки пользователям:
Частые вопросы
Можно ли запустить программу на сервере 1С из клиентского кода?
Чем `НачатьЗапускПриложения` лучше `ЗапуститьПриложение`?
Как открыть папку в проводнике?
ЗапуститьПриложение с программой explorer. Проводник откроет её в новом окне. Код возврата у проводника ненадёжный, не опирайтесь на него.