Как обновить расширение конфигурации из его хранилища в пакетном режиме с помощью командной строки 1С?

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

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

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


"C:\Program Files\1cv8\8.3.22.1709\bin\1cv8.exe" designer 
/OUT "c:\temp\StorageUpdate.log" 
/F "c:\temp\testDB" 
/N "Admin" 
/P "123" 
/ConfigurationRepositoryF "c:\temp\storage_ext_test" 
/ConfigurationRepositoryN "Admin" 
/ConfigurationRepositoryP "123" 
/ConfigurationRepositoryUpdateCfg -force 
-Extension "Тест_Расширение"

В ответ на эту команду система выдает ошибку: "Конфигурация связана с другим хранилищем", а затем предлагает в интерактивном режиме выбрать расположение хранилища и ввести пароль. Причина этой ошибки кроется в специфике работы командной строки 1С:Предприятия с хранилищами.

1. Анализ проблемы и причины возникновения ошибки

Для начала, давайте проанализируем ситуацию, описанную автором. Информационная база, к которой мы обращаемся (`c:\temp\testDB`), связана с основным хранилищем конфигурации (например, `c:\temp\storage_test`). Расширение (`Тест_Расширение`) при этом имеет собственное, отдельное хранилище (`c:\temp\storage_ext_test`).

Ключи командной строки /ConfigurationRepositoryF, /ConfigurationRepositoryN и /ConfigurationRepositoryP в 1С:Предприятии предназначены исключительно для работы с основным хранилищем конфигурации информационной базы. Когда мы в командной строке указываем эти ключи, но направляем их на путь к хранилищу расширения (`c:\temp\storage_ext_test`), платформа 1С корректно определяет несоответствие.

Система понимает, что:

  1. Основная конфигурация базы данных `c:\temp\testDB` связана с одним хранилищем (пусть будет `c:\temp\storage_test`).
  2. В командной строке через параметры для основного хранилища (`/ConfigurationRepositoryF`) мы пытаемся указать путь к *другому* хранилищу (`c:\temp\storage_ext_test`).

Из-за этого несоответствия и возникает ошибка "Конфигурация связана с другим хранилищем". Платформа ожидает, что указанное хранилище будет тем, с которым связана *основная* конфигурация, а не хранилищем какого-либо расширения.

2. Документация и подтверждение ограничений платформы

Тщательное изучение официальной документации 1С:Предприятия (например, для версии 8.3.22, как упомянуто в сообщении) подтверждает, что на данный момент в стандартной командной строке платформы отсутствуют отдельные, явно документированные ключи, предназначенные специально для подключения к хранилищу *расширения* конфигурации. Нет аналогов вроде /ExtensionRepositoryF, /ExtensionRepositoryN или /ExtensionRepositoryP, которые позволили бы напрямую указать параметры хранилища для конкретного расширения.

Это означает, что прямой путь для обновления расширения из его собственного хранилища в пакетном режиме с помощью единственной команды 1cv8.exe designer, аналогичной обновлению основной конфигурации, к сожалению, не предусмотрен.

3. Частичное решение для обхода интерактивных диалогов: ключ /DisableStartupDialogs

Хотя этот ключ не решает корневую проблему подключения к хранилищу расширения, он может быть полезен при автоматизации других операций, которые могут вызывать интерактивные диалоги. В одном из сообщений было предложено использовать ключ /DisableStartupDialogs для подавления стартовых диалогов, включая запросы пароля, которые могут возникать, если система не смогла автоматически авторизоваться или определить необходимые параметры.

Применение этого ключа может выглядеть так:


"C:\Program Files\1cv8\8.3.22.1709\bin\1cv8.exe" designer 
/OUT "c:\temp\StorageUpdate.log" 
/F "c:\temp\testDB" 
/N "Admin" 
/P "123" 
/ConfigurationRepositoryF "c:\temp\storage_ext_test" 
/ConfigurationRepositoryN "Admin" 
/ConfigurationRepositoryP "123" 
/ConfigurationRepositoryUpdateCfg -force 
-Extension "Тест_Расширение" 
/DisableStartupDialogs

Однако важно понимать, что /DisableStartupDialogs лишь подавляет появление окон. Если базовая причина ошибки (несоответствие хранилища основной конфигурации и хранилища, указанного в параметрах) не устранена, то выполнение команды все равно завершится неудачей, но без показа диалогов.

4. Обходные пути и альтернативные подходы к обновлению расширения из хранилища

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

Подход 1: Программное взаимодействие через COM-соединение

Одним из наиболее гибких и мощных способов автоматизации работы с 1С:Предприятием является использование COM-соединения. Этот подход позволяет нам программно управлять платформой 1С из внешнего скрипта (например, на PowerShell, VBScript, Python или C#). Мы можем создать объект конфигуратора, подключиться к информационной базе, а затем выполнить необходимые операции с расширением.

Разберем шаги, которые мы можем предпринять:

  1. Создание COM-объекта: Мы начинаем с создания экземпляра COM-соединителя 1С.
  2. Подключение к информационной базе: Через созданный COM-объект мы подключаемся к нужной информационной базе в режиме конфигуратора. Для этого нам потребуются параметры подключения к базе (путь к базе, имя пользователя, пароль).
  3. Получение объекта расширения: После успешного подключения мы получаем доступ к коллекции расширений конфигурации и находим нужное нам расширение по имени.
  4. Подключение к хранилищу расширения: Для найденного расширения мы вызываем методы, которые позволяют подключиться к его хранилищу. В отличие от командной строки, где ключи общие, через COM мы можем оперировать непосредственно объектом расширения и его специфическими методами для работы с хранилищем.
  5. Обновление расширения из хранилища: После подключения к хранилищу расширения мы вызываем соответствующий метод для выполнения обновления.

Рассмотрим пример концептуального кода на PowerShell, демонстрирующего общий подход:


# Шаг 1: Параметры подключения к информационной базе
$dbPath    = "File=""c:\temp\testDB"";"
$dbUser    = "Admin"
$dbPass    = "123"

# Шаг 2: Параметры хранилища расширения
$repoExtPath = "c:\temp\storage_ext_test"
$repoExtUser = "Admin"
$repoExtPass = "123"
$extName   = "Тест_Расширение"

# Шаг 3: Создаем COM-объект конфигуратора
Try {
    $v8 = New-Object -ComObject "V83.COMConnector"
    $configurator = $v8.Connect("$dbPath User=""$dbUser""; Pwd=""$dbPass"";")
    Write-Host "Успешно подключились к информационной базе."
}
Catch {
    Write-Error "Ошибка подключения к информационной базе: $($_.Exception.Message)"
    Exit
}

Try {
    # Шаг 4: Получаем объект Конфигурация
    $configuration = $configurator.Конфигурация

    # Шаг 5: Находим нужное расширение по имени
    $extension = $null
    ForEach ($ext In $configuration.Расширения) {
        If ($ext.Имя = -eq $extName) {
            $extension = $ext
            Break
        }
    }

    If ($extension -ne $null) {
        Write-Host "Расширение '$extName' найдено."

        # Шаг 6: Подключаемся к хранилищу расширения
        # Метод ПодключитьсяКХранилищу() вызывается для объекта расширения
        # Это псевдокод, реальные параметры и возвращаемое значение могут отличаться
        $connectResult = $extension.ПодключитьсяКХранилищу($repoExtPath, $repoExtUser, $repoExtPass) 
        
        If ($connectResult.Успех) { # Предполагаем, что метод возвращает объект с полем Успех
            Write-Host "Успешно подключились к хранилищу расширения '$extName'."

            # Шаг 7: Обновляем расширение из хранилища
            # Метод ОбновитьКонфигурациюИзХранилища() для объекта расширения
            # Это псевдокод, реальные параметры и возвращаемое значение могут отличаться
            $updateResult = $extension.ОбновитьИзХранилища() 

            If ($updateResult.Успех) { # Предполагаем, что метод возвращает объект с полем Успех
                Write-Host "Расширение '$extName' успешно обновлено из хранилища."
                # Возможно, потребуется сохранить конфигурацию базы данных после обновления
                $configurator.ЗаписатьКонфигурациюБазыДанных()
                Write-Host "Конфигурация базы данных записана."
            } Else {
                Write-Error "Ошибка обновления расширения '$extName' из хранилища: $($updateResult.ОписаниеОшибки)"
            }
        } Else {
            Write-Error "Ошибка подключения к хранилищу расширения '$extName': $($connectResult.ОписаниеОшибки)"
        }
    } Else {
        Write-Error "Расширение '$extName' не найдено в информационной базе."
    }
}
Catch {
    Write-Error "Произошла ошибка при работе с расширением: $($_.Exception.Message)"
}
Finally {
    # Обязательно закрываем конфигуратор и освобождаем COM-объект
    If ($configurator -ne $null) {
        $configurator.Закрыть()
        [System.Runtime.InteropServices.Marshal]::ReleaseComObject($configurator) | Out-Null
    }
    If ($v8 -ne $null) {
        [System.Runtime.InteropServices.Marshal]::ReleaseComObject($v8) | Out-Null
    }
    Write-Host "Работа завершена. Освобождены COM-объекты."
}

Важное примечание: Приведенный выше код является концептуальным псевдокодом. Конкретные имена методов для работы с хранилищами расширений через COM могут отличаться в зависимости от версии платформы 1С. Вам потребуется обратиться к справке по объектам COM-соединителя вашей версии платформы для точных названий методов, таких как ПодключитьсяКХранилищу и ОбновитьИзХранилища для объекта РасширениеКонфигурации.

Подход 2: Выгрузка расширения из хранилища в файл и обновление из файла

Другой обходной путь заключается в поэтапном выполнении операции:

  1. Выгрузка расширения из хранилища в файл: Сначала нам необходимо каким-либо способом (возможно, через другой экземпляр конфигуратора, подключенный к хранилищу расширения, или используя тот же COM-подход, но с целью выгрузки) получить актуальную версию расширения из его хранилища и сохранить ее в файл формата `.cfe`.
  2. Обновление расширения в информационной базе из файла: После получения файла расширения (`.cfe`), мы можем использовать его для обновления расширения в целевой информационной базе. Это также может быть сделано программно через COM-соединение, используя методы для загрузки расширения из файла.

Сценарий использования:

  1. Запускаем 1cv8.exe designer с параметрами подключения к хранилищу расширения (`c:\temp\storage_ext_test`), но с целью не обновления базы, а просто запуска конфигуратора с этим хранилищем. Затем программно (например, через COM) или скриптом, имитирующим действия пользователя, выгружаем расширение из этого хранилища в файл `.cfe`.
  2. Запускаем 1cv8.exe designer с параметрами подключения к *основной* информационной базе (`c:\temp\testDB`).
  3. Программно (через COM-соединение) или, если возможно, через специализированные ключи (которых пока нет для расширений) загружаем расширение из полученного `.cfe` файла в информационную базу.

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

Пример концептуального кода для загрузки расширения из файла через COM:


# Шаг 1: Параметры подключения к информационной базе
$dbPath    = "File=""c:\temp\testDB"";"
$dbUser    = "Admin"
$dbPass    = "123"

# Шаг 2: Путь к файлу расширения
$extensionFilePath = "c:\temp\Тест_Расширение.cfe"

# Шаг 3: Создаем COM-объект конфигуратора
Try {
    $v8 = New-Object -ComObject "V83.COMConnector"
    $configurator = $v8.Connect("$dbPath User=""$dbUser""; Pwd=""$dbPass"";")
    Write-Host "Успешно подключились к информационной базе."
}
Catch {
    Write-Error "Ошибка подключения к информационной базе: $($_.Exception.Message)"
    Exit
}

Try {
    # Шаг 4: Получаем объект Конфигурация
    $configuration = $configurator.Конфигурация

    # Шаг 5: Загружаем расширение из файла
    # Метод ЗагрузитьРасширениеКонфигурации() вызывается для объекта Конфигурация
    # Это псевдокод, реальные параметры и возвращаемое значение могут отличаться
    $loadResult = $configuration.Расширения.ЗагрузитьИзФайла($extensionFilePath) # Или похожий метод
    
    If ($loadResult.Успех) { # Предполагаем, что метод возвращает объект с полем Успех
        Write-Host "Расширение успешно загружено из файла '$extensionFilePath'."
        # Возможно, потребуется сохранить конфигурацию базы данных после загрузки
        $configurator.ЗаписатьКонфигурациюБазыДанных()
        Write-Host "Конфигурация базы данных записана."
    } Else {
        Write-Error "Ошибка загрузки расширения из файла: $($loadResult.ОписаниеОшибки)"
    }
}
Catch {
    Write-Error "Произошла ошибка при работе с расширением: $($_.Exception.Message)"
}
Finally {
    # Обязательно закрываем конфигуратор и освобождаем COM-объект
    If ($configurator -ne $null) {
        $configurator.Закрыть()
        [System.Runtime.InteropServices.Marshal]::ReleaseComObject($configurator) | Out-Null
    }
    If ($v8 -ne $null) {
        [System.Runtime.InteropServices.Marshal]::ReleaseComObject($v8) | Out-Null
    }
    Write-Host "Работа завершена. Освобождены COM-объекты."
}

Подход 3: Включение расширения в основное хранилище (если применимо)

В некоторых случаях, если архитектура разработки позволяет, можно рассмотреть вариант включения расширения в то же хранилище, что и основная конфигурация. Это может упростить процесс обновления, так как и конфигурация, и расширение будут обновляться из одного и того же хранилища с использованием стандартных команд.

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

  1. Расширение разрабатывается отдельной командой или сторонним разработчиком.
  2. Различные версии расширения применяются к разным базам, использующим одну и ту же основную конфигурацию.
  3. Необходимо строгое разделение версионирования и публикации основной конфигурации и расширения.

Подход 4: Автоматизация через имитацию действий пользователя в конфигураторе

Это наименее рекомендуемый, но иногда возможный вариант. Он заключается в использовании скриптов или специализированных инструментов для имитации нажатий клавиш и движений мыши, чтобы автоматически выполнять шаги, которые обычно делаются вручную в режиме конфигуратора (например, "Конфигурация" -> "Расширения конфигурации" -> "Обновить конфигурацию из хранилища"). Для роботизации подобных действий в интерфейсе используется платформа для создания программных роботов с визуальным конструктором сценариев.

Мы не будем рассматривать подробные примеры этого подхода, поскольку он является крайне хрупким, зависимым от расположения элементов интерфейса, и при любом обновлении платформы или изменении внешнего вида окон конфигуратора такие скрипты перестают работать. Кроме того, этот метод не является "пакетным" в прямом смысле и обходит заложенные в платформе механизмы автоматизации.

Заключение

Исходя из анализа темы и возможностей платформы, мы можем сделать вывод, что прямое обновление расширения из его собственного хранилища с помощью одной команды 1cv8.exe designer и специализированных ключей командной строки на данный момент не поддерживается. Существующие ключи /ConfigurationRepositoryF, /ConfigurationRepositoryN, /ConfigurationRepositoryP предназначены исключительно для работы с хранилищем основной конфигурации.

Для решения задачи автоматизированного обновления расширения из его хранилища мы рекомендуем использовать программное взаимодействие через COM-соединение. Этот метод предоставляет максимальную гибкость и контроль над процессом, позволяя реализовать сложную логику, недоступную через простые команды командной строки. В качестве альтернативы можно рассмотреть выгрузку расширения в файл и последующую загрузку из файла, также программным путем.

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

← На главную