В основном проблема обновления платформы 1С стоит для клиентской части. Клиентских компьютеров может быть десятки и сотни, в то время как серверов на порядки меньше. У нас проблема обновления клиентских машин не стоит, клиенты запускаются на VDI, а там обновление сводится к установке на одной виртуальной машине и ее клонировании.
После победы над клиентами хочется разобраться с серверной частью. В интернете есть достаточное количество статей на тему, как обновить платформу 1С на клиентских машинах.
С серверной частью все ПОЧТИ тоже самое. Вот про это ПОЧТИ и хочу рассказать.
У нас для серверов 1С используется Windows, поэтому все, что написано далее относится только к установке 1С на Windows.
Обновление серверной части, состоит из нескольких действий:
Установка платформы 1С на сервере
Регистрация компонентов, таких как COM и консоль администрирования
Обновление пути к компоненте wsisapi.dll в конфигурационных файлах веб-сервера, в нашем случае IIS.
Отдельный вопрос - выбор среды для запуска языка и среды запуска скриптов. Нам хотелось как можно меньше использовать чего-то нового, поэтому выбор пал на то, что уже есть везде - PowerShell. У нас есть своя система для учета серверов и какие сервисы на них должны быть запущены. Из нее создаются индивидуальные скрипты для каждого сервера, которые запускаются из единого места.
$session = New-PSSession -ComputerName [Сервер];
Invoke-Command -Session $session -ScriptBlock {[Скрипт]} ;
Remove-PSSession $session
Побеждаем установку сервера
Суть всей установки сводится к запуску 1CEnterprise 8 (x86-64).msi с параметрами, которые есть в документации:
DESIGNERALLCLIENTS - все виды клиентов
THICKCLIENT – толстый клиент (в том числе позволяет запускать конфигуратор)
THINCLIENT – тонкий клиент для клиент-серверного варианта работы.
THINCLIENTFILE – тонкий клиент с возможностью работы с файловыми информационными базами
SERVER – серверная часть 1С
WEBSERVEREXT – компоненты расширения для веб-сервера
CONFREPOSSERVER – сервер хранилища конфигураций
SERVERCLIENT – компоненты для администрирования кластера серверов
CONVERTER77 – конвертер информационных баз из версии 1С:Предприятия 7.7
LANGUAGES – список языков интерфейса для установки через запятую
То есть, если хотим установить серверную часть 1С, то запуск установки будет выглядеть примерно так:
msiexec /i “C:\LastVersion\1CEnterprise 8 (x86-64).msi” /qn
TRANSFORMS=adminstallrestart.mst;1049.mst DESIGNERALLCLIENTS=1
THICKCLIENT=0 THINCLIENTFILE=0 THINCLIENT=0 WEBSERVEREXT=1 SERVER=1 CONFREPOSSERVER=0 CONVERTER77=0 SERVERCLIENT=1 LANGUAGES=RU
И вот здесь начинаются проблемы. При установке серверной части происходит регистрация сервиса и его запуск. При этом, такие параметры запуска, как каталог файлов сервера, пользователь под которым будет работать служба сервера указать невозможно. Это приводит к тому, что настроенные в реестре параметры запуска службы сервера будут перезаписаны на значения по умолчанию. Мы попробовали два подхода к устранению этой неприятности:
Подход 1: Не будем регистрировать и запускать сервис
Попробуем отключить регистрацию и запуск сервиса. Регистрацию и запуск сделаем отдельными скриптами. Стандартных параметров запуска недостаточно. Давайте поменяем саму программу установки. Качаем Windows SDK и устанавливаем Orca. Открываем нашего пациента 1CEnterprise 8 (x86-64).msi и, посмотрев на таблицу InstallExecuteSequence, видим, что многие действия, в том числе и запуск сервиса, зависят от параметра INSTALLSRVRASSRVC. Скорее всего его установка в «0» и поможет нам отказаться от регистрации и запуска сервиса. Поиском ищем, где же он устанавливается. Установка значения нашлась в таблице CustomAction в действии customSetSrvrAsService. Меняем Target на 0 и сохраняем наш файл трансформации DoNotRegister.mst.
Добавляем его в команду установки, и все выполняется без регистрации и запуска сервиса.
msiexec /i "C:\LastVersion\1CEnterprise 8 (x86-64).msi" /qr
TRANSFORMS=adminstallrelogon.mst;1049.mst;DoNotRegister.mst DESIGNERALLCLIENTS=1
THICKCLIENT=0 THINCLIENTFILE=0 THINCLIENT=0 WEBSERVEREXT=1 SERVER=1 CONFREPOSSERVER=0 CONVERTER77=0 SERVERCLIENT=1 LANGUAGES=RU
Далее необходимо только сменить путь к агенту сервера (C:\Program Files\1cv8\8.3.xx.xxxx\bin\ragent.exe) в реестре.
Подход 2: Пусть все будет стерто, настроим заново
Второй рассмотренный путь - пусть реестр будет перезаписан - отдельными скриптами настроим его заново. Мы в результате выбрали этот путь, так как хотели и новую установку на новый сервер тоже делать скриптами. Все наши настройки при установке сносятся, но мы их восстанавливаем.
$1cversion = "[ВерсияПлатформы]"
$PathToBin = 'C:\Program Files\1cv8\'+$1cversion+'\Bin'
$port = 1540
$regport = 1541
$range = "1560:1591"
$HomeCat = "[ПутьКsrvinfo]"
$PathToBin = "$PathToBin\ragent.exe"
$SrvcName = "1C:Enterprise 8.3 Server Agent (x86-64)"
$ImagePath = "`"$PathToBin`" -srvc -agent -regport $regport -port $port -range $range -debug -d `"$HomeCat`""
$Desctiption = "Агент сервера 1С:Предприятия 8.3"
$username = "[Пользователь]"
$password = "[Пароль]"
$secureStringPwd = $password | ConvertTo-SecureString -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPwd
$allServices1C = Get-WmiObject win32_service | ?{$_.Name -like '*'} |Select Name, DisplayName, State, PathName | Where-Object { $_.PathName -Like "*ragent.exe*" };
$m = $allServices1C | measure
$m.Count
if ($m.Count -gt 0) {
$allServices1C | % {
$services1C = $_;
$serviceExecPath = $services1C.PathName;
$serviceName = $services1C.name;
$serviceExecPathRagent = $services1C.PathName.split('"')[1];
$platformVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($serviceExecPathRagent).FileVersion
$NewPath = $services1C.PathName -replace $platformVersion,$1cversion
Write-Host "Найдена уже установленная служба агента 1с $serviceName"
try
{
if ($services1C.State -eq "Running"){Write-host "Останавливаем сервис $serviceName"; Stop-Service -Name $serviceName -Force}
Write-host "Меняем path службы на $NewPath"
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\$serviceName" -Name ImagePath -Value "$NewPath"
Write-Host "Запускаем сервис $serviceName "
Start-Service -Name $serviceName
sleep(10)
if ($services1C.State -eq "Running") { Write-host "Сервис запущен успешно"; write-host "ErrCode 0"}
else { Write-Host "Сервис $serviceName не запустился!" ;Write-Host "ErrCode 1"}
}catch
{
Write-Host "Ошибка при изменении службы $serviceName" -ForegroundColor Red
Write-Host "Подробно:" -ForegroundColor Red
Write-Host $Error[0] -ForegroundColor Red
Write-Host "ErrCode 1"
} }
}
else {
Write-Host "Устанавливаем службу 1С $SrvcName"
try{
New-Service -Name $SrvcName -BinaryPathName $ImagePath -Description $Desctiption -DisplayName $Desctiption -StartupType Automatic -Credential $creds
Start-Service -Name $serviceName;
Write-Host "Сервис $SrvcName зарегистрирован и запущен!" -ForegroundColor Green
Write-Host "ErrCode 0"
} catch {
Write-Host "Ошибка при регистрации компоненты!" -ForegroundColor Red
Write-Host "Подробно:" -ForegroundColor Red
Write-Host $Error[0] -ForegroundColor Red
Write-Host "ErrCode 1" -ForegroundColor Red
}
}
Регистрация COM и консоли администрирования
Это самые простые действия. Для регистрации COM Запускаем
regsvr32 /n /i:user "C:\Program Files\1cv8\8.3.xx.xxxx\bin\comcntr.dll" на PowerShell наш скрипт выглядит так:
$allServices1C = Get-WmiObject win32_service | ?{$_.Name -like '*'} |
Select Name, DisplayName, State, PathName |
Where-Object { $_.PathName -Like "*ragent.exe*" };
$allServices1C | % {
$services1C = $_;
$serviceExecPath = $services1C.PathName;
$serviceExecPathRagent = $services1C.PathName.split('"')[1];
$serviceDirectory = [System.IO.Path]::GetDirectoryName($serviceExecPathRagent);
$comcntrPath = "$serviceDirectory\comcntr.dll";
$regCommand = "regsvr32.exe /s ""$comcntrPath""";
$platformVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($serviceExecPathRagent).FileVersion
Write-Host "Начало регистрации COM-компоненты 1С:Предприятия";
Write-Host "Версия платформы: $platformVersion";
Write-Host "Путь к DLL: ""$comcntrPath""";
Write-Host "Команда регистрации компоненты: ""$regCommand""";
try
{
cmd /c "$regCommand"
Write-Host "Регистрация компоненты успешно выполнена!" -ForegroundColor Green
Write-Host "ErrCode 0"
} catch
{
Write-Host "Ошибка при регистрации компоненты!" -ForegroundColor Red
Write-Host "Подробно:" -ForegroundColor Red
Write-Host "ErrCode 1" -ForegroundColor Red
}
}
Для регистрации консоли
regsvr32 /n /i:user "C:\Program Files\1cv8\8.3.xx.xxxx\bin\radmin.dll" на PowerShell наш скрипт выглядит так:
$allServices1C = Get-WmiObject win32_service | ?{$_.Name -like '*'} |
Select Name, DisplayName, State, PathName |
Where-Object { $_.PathName -Like "*ragent.exe*" };
$allServices1C | % {
$services1C = $_;
$serviceExecPath = $services1C.PathName;
$serviceExecPathRagent = $services1C.PathName.split('"')[1];
$serviceDirectory = [System.IO.Path]::GetDirectoryName($serviceExecPathRagent);
$radminPath = "$serviceDirectory\radmin.dll";
$regCommand = "regsvr32.exe /s ""$radminPath""";
$platformVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($serviceExecPathRagent).FileVersion
Write-Host "Начало регистрации COM-компоненты 1С:Предприятия";
Write-Host "Версия платформы: $platformVersion";
Write-Host "Путь к DLL: ""$radminPath""";
Write-Host "Команда регистрации компоненты: ""$regCommand""";
try
{
cmd /c "$regCommand"
Write-Host "Регистрация компоненты успешно выполнена!" -ForegroundColor Green
Write-Host "ErrCode 0"
} catch
{
Write-Host "Ошибка при регистрации компоненты!" -ForegroundColor Red
Write-Host "Подробно:" -ForegroundColor Red
Write-Host "ErrCode 1" -ForegroundColor Red
}
}
Обновление пути к компоненте wsisapi.dll
Данное действие тоже достаточно простое, настройка веб публикации 1С систем сводится созданию в IIS приложения состоящего default.vrd и конфигурированием Handler mappings. С последним возникают тонкости. Настройки могут быть заданы как на уровне приложения, так и на уровне сайта или сервера в целом. Мы пошли по наиболее простому пути. В последних версиях платформы 1С утилита публикации (создания приложений) создает конфигурацию на уровне приложения. Так как публикации рождаются и изменяются регулярно в процессе развития систем, то чтобы не наступить на грабли, что в разных местах у нас разные настройки, решили остановиться на одном варианте. Конфигурационный файл web.config должен быть у каждого приложения. Мы проверили все наши публикации и там, где отсутствовал конфигурационный файл, создали его. Теперь в каждой директории приложения имелся файл web.config и задача свелась к замене версии платформы в строке:
scriptProcessor="C:\Program Files\1cv8\8.3.xx.xxxx\bin\wsisapi.dll"
Что мы делаем скриптом:
$result = Get-ChildItem -Path "[АдресПапкиСПубликациями]" -Recurse -ErrorAction SilentlyContinue -Include "web.config"
$1cUpdateV = "[ВерсияПлатформы]"
foreach($f in $result) {
$fullname = $f.fullname
$Text = Get-Content $f.FullName -raw
$pattern = "(?:C:\\Program Files\\1cv8\\)(?<version>\d+\.\d+\.\d+\.\d+)(?:\\bin\\wsisapi\.dll)"
$te = $Text -match $pattern
if ($Matches.Count -ne 0) {
$1cVersionold = $Matches["version"]
if ($1cVersionold -ne $Version1c) {
$replaceText = $Text -replace "$1cVersionold","$1cUpdateV"
Set-Content -Path $fullname -Value $replaceText
Write-Host "файл $fullname изменен версия платформы старая $1cVersionold новая $1cUpdateV"
} else { Write-Host "файл $fullname не изменен. Версии совпадают"}
}
}
Write-Host "ErrCode 0"
Надеюсь, этот материал оказался полезным для вас. А как вы решаете проблему обновления нескольких серверов 1С? Делитесь вашими know-how в комментариях.
Sergey-S-Kovalev
Я предпочитаю вместо обновления разворачивать новый сервер, так проще откатиться и обеспечить иммутабельность. Ну и быть на актуальной версии не только платформы 1С. Обновление может быть актуальным только, если программные ключи активированы на этом же сервере, но на практике это сильно ограничивает в возможностях по гибкой настройке сервера в зависимости от планируемых нагрузок.
Серверную часть можно ставить как приложение, без автоматического создания сервиса, а сервис доставлять и настраивать уже отдельно. Это избавляет от ковыряния в ORCA. На моей памяти серверная часть в принципе на ставилась автоматически и этой проблеме уже годы, возможно в последних версиях платформы это починили. Протестирую Ваш код завтра :)
Компоненты управления сервером 1С тоже ставить особо незачем. Оснасткой можно цепляться по сети. Базы можно прописывать через COM-соединения. Повисшие или не нужные соединения так же можно в любой момент прибить скриптом.
Статья немного сумбурная, но всеравно спасибо.
langoner
Удалось протестировать наш код?)
Sergey-S-Kovalev
Ну раз вопрос возник, то пришлось протестировать ту часть, которая у меня вызвала подозрения:
Ставит платформу, но служба "1C:Enterprise 8.3 Server Agent (x86-64)" не появляется. К счастью 1С не имеет привычки ставить службу под Локальной Системой, ей напрямую ключами нужно указывать имя пользователя и пароль. Как следствие кусок статьи про Orca не нужен.
Проверял на дистрибутиве 1С windows64full_8_3_20_1549 и под Windows Server 2019 Standard
Серверная часть как не ставилась автоматически (а мы говорим про дистрибутив содержащий "1CEnterprise 8 Server (x86-64).msi") так и продолжает этого не делать с классической ошибкой: Windows Installer installed the product. Product Name: 1C:Enterprise 8 Server (x86-64). Product Version: 8.3.20.1549. Product Language: 1033. Manufacturer: 1C-Soft. Installation success or error status: 1624.