Как определить свободное место на диске через COM-соединение в 1С

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

В процессе администрирования и автоматизации систем на базе 1С часто возникает задача мониторинга ресурсов удаленных серверов. Одной из типичных задач является определение свободного дискового пространства. Если ваша архитектура предполагает работу через COM-соединение между базами, вы можете столкнуться с трудностями при попытке вызвать системные объекты Windows внутри этого соединения. В этой статье мы подробно разберем несколько эффективных способов решения этой задачи, проанализируем ошибки «зависания» команд и изучим наиболее современные подходы.

Способ 1. Создание объекта FileSystemObject внутри COM-соединения

Часто программисты пытаются создать объект Scripting.FileSystemObject привычным способом, но забывают, что внутри внешнего соединения контекст выполнения отличается. Разберем правильный синтаксис. Если вы просто напишете Новый COMОбъект внутри кода, он создастся локально. Чтобы создать его «там», на стороне подключенной базы, нужно использовать методы внешнего соединения.

Рассмотрим пример кода, в котором мы инициируем объект FSO непосредственно в контексте удаленной базы:


// Устанавливаем соединение с удаленной базой
Connector = Новый COMОбъект("V83.COMConnector");
Connection = Connector.Connect("Srvr=""ServerName"";Ref=""BaseName"";Usr=""Admin"";Pwd=""Password"";");

// Правильный способ создания системного объекта внутри соединения
// Используем метод NewObject, указывая тип "COMObject"
Попытка
    FSO = Connection.NewObject("COMObject", "Scripting.FileSystemObject");
    Диск = FSO.GetDrive("C:");
    СвободноБайт = Диск.FreeSpace;
    Сообщить("Свободно на диске C: " + СвободноБайт / 1024 / 1024 + " Мб");
Исключение
    Сообщить("Ошибка при создании FSO: " + ОписаниеОшибки());
КонецПопытки;

Важный нюанс: использование NewObject("COMObject", ...) позволяет пробросить создание объекта в контекст процесса удаленного сервера 1С. Это критично, если вам нужно проверить локальные диски именно того сервера, на котором запущена удаленная база.

Способ 2. Использование системных команд через CMD

Проанализируем ситуацию, когда необходимо получить данные без прямой поддержки COM-объектов (например, в условиях жестких ограничений безопасности). Можно воспользоваться стандартной командой dir, вывод которой перенаправляется в текстовый файл для последующего анализа.

Многие сталкиваются с проблемой: при использовании ЗапуститьПриложение процесс «зависает». Выясним причину: команда dir не является исполняемым файлом .exe, это внутренняя команда командного интерпретатора cmd.exe. Поэтому ее нужно вызывать через оболочку.

Разберем по шагам правильный алгоритм:

  1. Формируем команду с использованием cmd /c.
  2. Перенаправляем поток вывода в файл >.
  3. Читаем полученный файл средствами 1С.

Процедура ОпределитьСвободноеМестоЧерезФайл()
    ИмяФайлаРезультата = КаталогВременныхФайлов() + "freespace.txt";
    // Используем cmd /c для выполнения внутренней команды и автоматического закрытия окна
    Команда = "cmd /c dir \\serv\Archive > """ + ИмяФайлаРезультата + """";
    
    // Параметр "Истина" в конце означает ожидание завершения выполнения
    ЗапуститьПриложение(Команда, , Истина);
    
    Текст = Новый ЧтениеТекста(ИмяФайлаРезультата, КодировкаТекста.OEM);
    Строка = Текст.ПрочитатьСтроку();
    Пока Строка <> Неопределено Цикл
        // Ищем строку, содержащую информацию о свободном месте
        // Учтите, что слово "свободно" зависит от локализации ОС
        Если СтрНайти(НРег(Строка), "свободно") > 0 Или СтрНайти(НРег(Строка), "free") > 0 Тогда
            // Логика парсинга строки для выделения числа
            Сообщить("Найдена информация: " + СокрЛП(Строка));
        КонецЕсли;
        Строка = Текст.ПрочитатьСтроку();
    КонецЦикла;
    Текст.Закрыть();
КонецПроцедуры

Способ 3. Использование WMI (Windows Management Instrumentation)

Профессиональным и наиболее надежным способом получения информации о системе является использование WMI. Рассмотрим ситуацию: нам нужно получить данные о диске максимально быстро и точно, не занимаясь парсингом текстовых строк. Объект Win32_LogicalDisk предоставляет все необходимые данные в байтах.

Посмотрим на пример реализации через SWbemLocator:


// Подключаемся к локатору WMI
Локатор = Новый COMОбъект("WbemScripting.SWbemLocator");
// Можно подключиться к удаленному компьютеру, указав его имя, логин и пароль
СервисWMI = Локатор.ConnectServer(".", "root\cimv2");

// Выполняем запрос к логическим дискам
СписокДисков = СервисWMI.ExecQuery("Select * from Win32_LogicalDisk Where DeviceID = 'C:'");

Для Каждого Диск Из СписокДисков Цикл
    Размер = Диск.Size; // Общий размер
    Свободно = Диск.FreeSpace; // Свободное место
    Сообщить("Диск C: Свободно " + Цел(Свободно / 1024 / 1024 / 1024) + " Гб из " + Цел(Размер / 1024 / 1024 / 1024) + " Гб");
КонецЦикла;

Преимущества этого метода:

Почему код может не работать на сервере?

Если вы запускаете этот код в составе регламентного задания, следует помнить о нескольких критических моментах:

  1. Права службы 1С: По умолчанию служба сервера 1С (usr1cv8) работает под локальной учетной записью. Она не имеет доступа к сетевым путям вида \\server\share. Чтобы такие пути были доступны, службу необходимо запустить от имени доменного пользователя.
  2. Интерактивный режим: При использовании ЗапуститьПриложение на сервере, приложение запускается в «нулевой» сессии. Оно не может выводить диалоговые окна. Если команда потребует подтверждения (например, ввода пароля), процесс «зависнет» навсегда. Всегда используйте ключи тихой установки или подавления запросов (например, /y в некоторых командах).
  3. Разрядность: Если ваш сервер 1С 64-битный, убедитесь, что вызываемые COM-компоненты зарегистрированы в 64-битной версии. Для FileSystemObject и WMI это обычно не является проблемой, так как они системные и присутствуют в обеих разрядностях.

Итоги и рекомендации

Мы проанализировали три основных подхода к определению свободного места. Выбор метода зависит от ваших условий:

При реализации любого из этих методов в промышленной эксплуатации всегда оборачивайте вызовы в блоки Попытка...Исключение, так как работа с внешними системными ресурсами всегда сопряжена с рисками отказов прав доступа или сетевых сбоев.

← На главную