Почему не работает КомандаСистемы при вызове msg.exe и как правильно запускать системные утилиты из 1С

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

При разработке на платформе 1С часто возникает необходимость взаимодействия с операционной системой: запуск внешних программ, отправка сообщений пользователям сети или выполнение скриптов. Одной из самых распространенных команд является КомандаСистемы(). Однако разработчики часто сталкиваются с ситуацией, когда команда, идеально работающая в консоли cmd, наотрез отказывается выполняться из кода 1С. Разберем по шагам, почему это происходит и как правильно настроить взаимодействие с ОС Windows, учитывая разрядность систем.

Причина 1: Мгновенное закрытие окна консоли

Первая и самая простая проблема, с которой мы сталкиваемся — это визуальное «мигание» черного окна. Когда мы вызываем КомандаСистемы("msg * Message"), 1С запускает командный интерпретатор, передает ему команду и, как только команда завершается, интерпретатор закрывает окно. Если в процессе возникла ошибка, мы ее просто не успеваем прочитать.

Для анализа ситуации проанализируем способ задержки окна. Чтобы окно не закрывалось сразу, можно использовать ключ /k (keep) или команду pause. Рассмотрим пример:


// Окно закроется сразу после выполнения
КомандаСистемы("msg * Тестовое сообщение");

// Окно останется открытым для анализа ошибок
КомандаСистемы("cmd /k msg * Тестовое сообщение");

Использование cmd /k — отличный способ отладки, который позволяет увидеть текст ошибки, возвращаемый операционной системой.

Причина 2: Механизм перенаправления файловой системы (File System Redirector)

Это наиболее глубокая и часто встречающаяся техническая причина. Если вы используете 32-битную версию 1С (что является стандартом для многих рабочих мест) на 64-битной Windows, вступает в силу механизм File System Redirector. Проанализируем, как это работает: когда 32-битное приложение обращается к папке C:\Windows\System32, Windows автоматически и прозрачно для приложения перенаправляет запрос в папку C:\Windows\SysWOW64.

Утилита msg.exe (отвечающая за отправку сообщений) в 64-битных редакциях Windows находится в «настоящей» System32, но её часто нет в SysWOW64. В результате 1С пытается запустить файл по пути, где его фактически не существует. Выясним, как обойти это ограничение.

Решение через виртуальный каталог Sysnative

Для решения проблемы доступа к 64-битным системным файлам из 32-битных приложений компания Microsoft предусмотрела специальный псевдоним — Sysnative. Это виртуальная папка, которая позволяет 32-битному процессу напрямую обратиться к реальной директории System32 без перенаправления. Перепишем нашу команду правильно:


// Вместо System32 используем Sysnative
ПутьККоманде = "C:\Windows\Sysnative\msg.exe * Сообщение из 1С";
КомандаСистемы(ПутьККоманде);

Важно: Псевдоним Sysnative виден только 32-битным приложениям. Если вы попытаетесь открыть этот путь через проводник или 64-битную командную строку, Windows выдаст ошибку, что путь не найден.

Альтернативный метод: Использование mshta

Если стандартная утилита msg.exe не подходит или требует специфических прав администратора (например, для настройки AllowRemoteRPC в реестре), можно воспользоваться встроенным движком выполнения HTML-приложений — mshta.exe. Этот способ хорош тем, что он не зависит от системных служб удаленных рабочих столов и позволяет выводить сообщения с форматированием. Рассмотрим пример кода:


ТекстСообщения = "Внимание!\n\nВыполнение операции завершено успешно.";
КомандаСистемы("mshta javascript:alert('" + ТекстСообщения + "');close();");

Этот метод создает полноценное диалоговое окно Windows, которое будет ждать реакции пользователя, прежде чем закрыться.

Использование объекта WScript.Shell (COM-объект)

Для более профессиональной работы с системными командами рекомендуется отказаться от КомандаСистемы() в пользу COM-объекта WScript.Shell. Разберем преимущества этого подхода: он позволяет скрыть черное окно консоли и дождаться завершения выполнения команды, получив код возврата.


Шелл = Новый COMОбъект("WScript.Shell");
// Параметр 0 скрывает окно консоли
// Параметр Истина заставляет 1С ждать завершения команды
Результат = Шелл.Run("C:\Windows\Sysnative\msg.exe * Сообщение", 0, Истина);

Если Результат <> 0 Тогда
    Сообщить("Команда завершилась с ошибкой: " + Результат);
КонецЕсли;

Нюансы контекста выполнения (Клиент vs Сервер)

Необходимо четко понимать, где выполняется код. Если вы вызываете КомандаСистемы() в модуле, помеченном &НаСервере, команда будет выполнена на сервере 1С под учетной записью службы (например, USR1CV8). В этом случае пользователь никогда не увидит никакого сообщения на своем экране, так как процесс запустится в изолированной сессии сервера.

Правило: Любые команды, взаимодействующие с интерфейсом пользователя или локальными утилитами рабочего стола, должны запускаться строго в клиентском контексте (&НаКлиенте).

Использование PowerShell как современная альтернатива

Если вам нужно вывести сложное уведомление или выполнить системное действие, современным стандартом является использование PowerShell. Он гораздо гибче работает с кодировками и путями. Посмотрим на пример вызова MessageBox через PowerShell из 1С:


КомандаPS = "powershell -Command ""[Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Текст сообщения')""";
ЗапуститьПриложение(КомандаPS);

Метод ЗапуститьПриложение() является более современным аналогом КомандаСистемы() и предпочтителен к использованию в управляемых формах.

Подводя итог, при работе с системными командами в 1С всегда учитывайте:

  1. Разрядность: Используйте Sysnative для доступа к системным утилитам из 32-битной 1С.
  2. Видимость: Используйте cmd /k для отладки и WScript.Shell для скрытого выполнения.
  3. Контекст: Выполняйте команды на клиенте, если требуется взаимодействие с пользователем.
  4. Права: Помните, что утилита msg.exe может требовать прав администратора или включенной службы RDS (Remote Desktop Services).
← На главную