Установка .NET для (классических) ролей облачных служб Azure

Важно!

Облачные службы (классическая версия) объявлены устаревшими для новых клиентов. Их поддержка будет полностью прекращена 31 августа 2024 года. Для новых развертываний следует использовать Облачные службы Azure с расширенной поддержкой . Это новая модель развертывания на основе Azure Resource Manager.

В этой статье описывается установка версий платформы .NET Framework, которые не входят в состав гостевой ОС Azure. .NET в гостевой ОС можно использовать для настройки веб-ролей и рабочих ролей облачной службы.

Например, можно установить .NET Framework 4.6.2 в семействе версии 4 гостевых ОС, которые не входят в состав какого-либо из выпусков .NET Framework 4.6. (Платформа .NET Framework 4.6 входит в состав семейства версии 5 гостевых ОС.) Актуальные сведения о выпусках гостевой ОС Azure см. в статье Таблица совместимости выпусков гостевых ОС Azure и пакетов SDK.

Важно!

Пакет SDK 2.9 для Azure содержит ограничение на развертывание .NET Framework 4.6 в семействе версий 4 гостевых ОС. Исправление ограничения доступно в azure-cloud-services-filesрепозитории GitHub.

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

Добавление установщика .NET в проект

Чтобы скачать веб-установщик для платформы .NET Framework, выберите версию, которую требуется установить:

Чтобы добавить установщик для веб-роли:

  1. В обозревателе решений в разделе Роли проекта облачной службы щелкните правой кнопкой мыши веб-роль и выберите Добавить>Новая папка. Создайте папку с именем bin.
  2. Щелкните правой кнопкой мыши папку bin и выберите Добавить>Существующий элемент. Выберите установщик .NET и добавьте его в папку bin.

Чтобы добавить установщик для рабочей роли:

  • Щелкните правой кнопкой мыши рабочую роль и выберите Добавить>Существующий элемент. Выберите установщик .NET и добавьте его в роль.

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

Примечание

Установите .NET Framework 4.6.2 в роль облачной службы, даже если для приложения требуется .NET Framework 4.6. Гостевая ОС включает обновление 3098779 и обновление 3097997 базы знаний. Проблемы могут возникнуть при запуске приложений .NET, если платформа .NET Framework 4.6 установлена поверх обновлений базы знаний Майкрософт. Чтобы избежать этих проблем, установите .NET Framework 4.6.2 вместо версии 4.6. Дополнительные сведения см. в статьях базы знаний 3118750 и 4340191.

Роль с файлами установщика

Определение начальных задач для ролей

С помощью задач запуска вы можете выполнять различные операции перед запуском роли. Установка платформы .NET Framework как части начальной задачи позволяет установить платформу до того, как будет запущено выполнение программного кода. Дополнительные сведения о начальных задачах см. в статье Как настроить и выполнить задачи запуска для облачной службы.

  1. В файл ServiceDefinition.csdef в узле WebRole или WorkerRole добавьте для всех ролей следующее содержимое:

    <LocalResources>
      <LocalStorage name="NETFXInstall" sizeInMB="1024" cleanOnRoleRecycle="false" />
    </LocalResources>    
    <Startup>
      <Task commandLine="install.cmd" executionContext="elevated" taskType="simple">
        <Environment>
          <Variable name="PathToNETFXInstall">
            <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='NETFXInstall']/@path" />
          </Variable>
          <Variable name="ComputeEmulatorRunning">
            <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
          </Variable>
        </Environment>
      </Task>
    </Startup>
    

    Предыдущая конфигурация выполняет консольную команду install.cmd с правами администратора и устанавливает платформу .NET Framework. Конфигурация также создает элемент LocalStorage с именем NETFXInstall. Сценарий запуска задает временную папку для использования этого локального ресурса хранилища.

    Важно!

    Для обеспечения правильной установки платформы размер этого ресурса должен быть не менее 1024 МБ.

    Дополнительные сведения о задачах запуска см. в статье Стандартные задачи запуска в облачной службе.

  2. Создайте файл с именем install.cmd и добавьте в него следующий скрипт установки.

    Скрипт путем поиска по реестру проверяет, установлена ли на компьютере выбранная версия .NET Framework. Если требуемая версия .NET Framework не установлена, открывается веб-установщик .NET Framework. Для помощи в устранении возникших проблем скрипт регистрирует все действия в файл startuptasklog-(текущая дата и время).txt, который хранится в локальном хранилище InstallLogs.

    Важно!

    Для создания файла install.cmd используйте простой текстовый редактор, например Блокнот. Если для создания текстового файла и изменения расширения на .cmd используется Visual Studio, файл по-прежнему может содержать метку порядка байтов UTF-8. Эта метка может вызвать ошибку при выполнении первой строки скрипта. Чтобы избежать этой ошибки, сделайте первую строку скрипта оператором REM, который может быть пропущен при обработке порядка байтов.

    REM Set the value of netfx to install appropriate .NET Framework. 
    REM ***** To install .NET 4.5.2 set the variable netfx to "NDP452" ***** https://go.microsoft.com/fwlink/?LinkId=397707
    REM ***** To install .NET 4.6 set the variable netfx to "NDP46" ***** https://go.microsoft.com/fwlink/?LinkId=528222
    REM ***** To install .NET 4.6.1 set the variable netfx to "NDP461" ***** https://go.microsoft.com/fwlink/?LinkId=671729
    REM ***** To install .NET 4.6.2 set the variable netfx to "NDP462" ***** https://go.microsoft.com/fwlink/?linkid=780596
    REM ***** To install .NET 4.7 set the variable netfx to "NDP47" ***** https://go.microsoft.com/fwlink/?LinkId=825298
    REM ***** To install .NET 4.7.1 set the variable netfx to "NDP471" ***** https://go.microsoft.com/fwlink/?LinkId=852095
    REM ***** To install .NET 4.7.2 set the variable netfx to "NDP472" ***** https://go.microsoft.com/fwlink/?LinkId=863262
    REM ***** To install .NET 4.8 set the variable netfx to "NDP48" ***** https://dotnet.microsoft.com/download/thank-you/net48
    REM ***** To install .NET 4.8.1 set the variable netfx to "NDP481" ***** https://go.microsoft.com/fwlink/?linkid=2215256 
    set netfx="NDP481"
    
    REM ***** Set script start timestamp ****
    set timehour=%time:~0,2%
    set timestamp=%date:~-4,4%%date:~-10,2%%date:~-7,2%-%timehour: =0%%time:~3,2%
    set "log=install.cmd started %timestamp%."
    
    REM ***** Exit script if running in Emulator *****
    if "%ComputeEmulatorRunning%"=="true" goto exit
    
    REM ***** Needed to correctly install .NET 4.6.1, otherwise you may see an out of disk space error *****
    set TMP=%PathToNETFXInstall%
    set TEMP=%PathToNETFXInstall%
    
    REM ***** Setup .NET filenames and registry keys *****
    if %netfx%=="NDP481" goto NDP481
    if %netfx%=="NDP48" goto NDP48
    if %netfx%=="NDP472" goto NDP472
    if %netfx%=="NDP471" goto NDP471
    if %netfx%=="NDP47" goto NDP47
    if %netfx%=="NDP462" goto NDP462
    if %netfx%=="NDP461" goto NDP461
    if %netfx%=="NDP46" goto NDP46
    
    set "netfxinstallfile=NDP452-KB2901954-Web.exe"
    set netfxregkey="0x5cbf5"
    set netfxUrl="https://go.microsoft.com/fwlink/?LinkId=397707"
    goto logtimestamp
    
    :NDP46
    set "netfxinstallfile=NDP46-KB3045560-Web.exe"
    set netfxregkey="0x6004f"
    set netfxUrl="https://go.microsoft.com/fwlink/?LinkId=528222"
    goto logtimestamp
    
    :NDP461
    set "netfxinstallfile=NDP461-KB3102438-Web.exe"
    set netfxregkey="0x6040e"
    set netfxUrl="https://go.microsoft.com/fwlink/?LinkId=671729"
    goto logtimestamp
    
    :NDP462
    set "netfxinstallfile=NDP462-KB3151802-Web.exe"
    set netfxregkey="0x60632"
    set netfxUrl="https://go.microsoft.com/fwlink/?linkid=780596"
    goto logtimestamp
    
    :NDP47
    set "netfxinstallfile=NDP47-KB3186500-Web.exe"
    set netfxregkey="0x707FE"
    set netfxUrl="https://go.microsoft.com/fwlink/?LinkId=825298"
    goto logtimestamp
    
    :NDP471
    set "netfxinstallfile=NDP471-KB4033344-Web.exe"
    set netfxregkey="0x709fc"
    set netfxUrl="https://go.microsoft.com/fwlink/?LinkId=852095"
    goto logtimestamp
    
    :NDP472
    set "netfxinstallfile=NDP472-KB4054531-Web.exe"
    set netfxregkey="0x70BF0"
    set netfxUrl="https://go.microsoft.com/fwlink/?LinkId=863262"
    goto logtimestamp
    
    :NDP48
    set "netfxinstallfile=NDP48-Web.exe"
    set netfxregkey="0x80EA8"
    set netfxUrl="https://dotnet.microsoft.com/download/thank-you/net48"
    goto logtimestamp
    
    :NDP481
    set "netfxinstallfile=NDP481-Web.exe"
    set netfxregkey="0x82348"
    set netfxUrl="https://go.microsoft.com/fwlink/?linkid=2215256"
    goto logtimestamp
    
    :logtimestamp
    REM ***** Setup LogFile with timestamp *****
    md "%PathToNETFXInstall%\log"
    set startuptasklog="%PathToNETFXInstall%log\startuptasklog-%timestamp%.txt"
    set netfxinstallerlog="%PathToNETFXInstall%log\NetFXInstallerLog-%timestamp%"
    echo %log% >> %startuptasklog%
    echo Logfile generated at: %startuptasklog% >> %startuptasklog%
    echo TMP set to: %TMP% >> %startuptasklog%
    echo TEMP set to: %TEMP% >> %startuptasklog%
    
    REM ***** Check if .NET is installed *****
    echo Checking if .NET (%netfx%) is installed >> %startuptasklog%
    set /A netfxregkeydecimal=%netfxregkey%
    set foundkey=0
    FOR /F "usebackq skip=2 tokens=1,2*" %%A in (`reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" /v Release 2^>nul`) do @set /A foundkey=%%C
    echo Minimum required key: %netfxregkeydecimal% -- found key: %foundkey% >> %startuptasklog%
    if %foundkey% GEQ %netfxregkeydecimal% goto installed
    
    REM ***** Downloading .NET Framework Setup *****
    set retryCount=0
    set maxRetry=3
    set delayInSeconds=60
    echo Downloading .NET Framework %netfx% setup with commandline: powershell -Command "Invoke-WebRequest %netfxUrl% -OutFile %~dp0%netfxinstallfile%" >> %startuptasklog%
    goto loop
    
    :loop
    if %retryCount% NEQ 0 echo %date% %time% : Waiting %delayInSeconds% seconds to retry >> %startuptasklog%
    if %retryCount% NEQ 0 (powershell -Command "Start-Sleep -Seconds %delayInSeconds%")
    set /a retryCount=%retryCount%+1
    echo %date% %time% : Try downloading... [%retryCount% of %maxRetry%] >> %startuptasklog%
    powershell -Command "Invoke-WebRequest %netfxUrl% -OutFile %~dp0%netfxinstallfile%"
    if %ERRORLEVEL% NEQ 0 if %retryCount% NEQ %maxRetry% goto loop
    if %ERRORLEVEL% NEQ 0 if %retryCount%== %maxRetry% echo Taking existing file to install since error occurred while downloading .NET framework %netfx% setup from  %netfxUrl%. >> %startuptasklog%
    if %ERRORLEVEL%== 0 echo %date% %time% : Successfully downloaded .NET framework %netfx% setup file. >> %startuptasklog%
    goto install
    
    :install
    REM ***** Installing .NET *****
    echo Installing .NET with commandline: start /wait %~dp0%netfxinstallfile% /q /serialdownload /log %netfxinstallerlog%  /chainingpackage "CloudService Startup Task" >> %startuptasklog%
    start /wait %~dp0%netfxinstallfile% /q /serialdownload /log %netfxinstallerlog% /chainingpackage "CloudService Startup Task" >> %startuptasklog% 2>>&1
    if %ERRORLEVEL%== 0 goto installed
        echo .NET installer exited with code %ERRORLEVEL% >> %startuptasklog%    
        if %ERRORLEVEL%== 3010 goto restart
        if %ERRORLEVEL%== 1641 goto restart
        echo .NET (%netfx%) install failed with Error Code %ERRORLEVEL%. Further logs can be found in %netfxinstallerlog% >> %startuptasklog%
        goto exit
    
    :restart
    echo Restarting to complete .NET (%netfx%) installation >> %startuptasklog%
    shutdown.exe /r /t 5 /c "Installed .NET framework" /f /d p:2:4
    
    :installed
    echo .NET (%netfx%) is installed >> %startuptasklog%
    
    :end
    echo install.cmd completed: %date:~-4,4%%date:~-10,2%%date:~-7,2%-%timehour: =0%%time:~3,2% >> %startuptasklog%
    
    :exit
    EXIT /B 0
    
  3. Добавьте файл install.cmd для каждой роли, используя команды Добавить>Существующий элемент в обозревателе решений, как описано ранее в этой статье.

    После завершения этого шага все роли должны иметь файл установщика .NET и файл install.cmd.

    Роль со всеми файлами

Настройка диагностики для передачи журналов задач запуска в хранилище BLOB-объектов

Чтобы упростить устранение неполадок при установке, можно настроить в Диагностике Azure передачу всех файлов журналов, созданных скриптом запуска или установщиком .NET, в хранилище BLOB-объектов Azure. Это позволит просматривать журналы, скачивая их из хранилища BLOB-объектов, а не на удаленном рабочем столе, где хранится роль.

Чтобы настроить систему диагностики, откройте файл diagnostics.wadcfgx и добавьте в узел Directories следующее содержимое:

<DataSources>
 <DirectoryConfiguration containerName="netfx-install">
  <LocalResource name="NETFXInstall" relativePath="log"/>
 </DirectoryConfiguration>
</DataSources>

Этот XML-код позволяет системе диагностики передавать файлы из каталога log в ресурсе NETFXInstall в учетную запись хранения диагностических данных в контейнере больших двоичных объектов netfx-install.

Развертывание облачной службы

При развертывании облачной службы задачи запуска устанавливают платформу .NET Framework, если она еще не установлена. Роли облачной службы находятся в состоянии занятости при установке платформы. Если при установке платформы необходима перезагрузка, роли службы также могут перезапуститься.

Дополнительные ресурсы