Instalar o .NET em funções de serviços de nuvem do Azure (clássico)

Importante

Os Serviços de Nuvem (clássicos) agora foram preteridos para novos clientes e serão desativados em 31 de agosto de 2024 para todos os clientes. As novas implantações devem usar o novo modelo de implantação baseado no Azure Resource Manager Serviços de Nuvem do Azure (suporte estendido) .

Este artigo descreve como instalar versões do .NET Framework que não são fornecidas com o SO convidado do Azure. Você pode usar o .NET no SO convidado para configurar as funções Web e de trabalho de seu serviço de nuvem.

Por exemplo, você pode instalar o .NET Framekwork 4.6.2 na família de SO Convidados 4, que não é fornecida com nenhuma versão do .NET Framework 4.6. (A família de sistemas operacionais convidados 5 vem com .NET Framework 4,6.) Para obter as informações mais recentes sobre as versões do sistema operacional convidado do Azure, consulte notícias de versão do SO convidado do Azure.

Importante

O SDK 2,9 do Azure contém uma restrição sobre a implantação de .NET Framework 4,6 na família de sistemas operacionais convidados 4 ou anterior. Uma correção para a restrição está disponível no repositório azure-cloud-services-filesGitHub.

Para instalar o .NET em suas funções web e de trabalho, inclua o instalador Web do .NET como parte de seu projeto de serviço de nuvem. Inicie o instalador como parte das tarefas de inicialização da função.

Adicione o instalador do .NET ao seu projeto

Para baixar o instalador da Web para o .NET Framework, escolha a versão que você deseja instalar:

Para adicionar o instalador para uma função web:

  1. No Gerenciador de Soluções, em Funções no projeto do serviço de nuvem, clique com o botão direito do mouse em sua função web e selecione Adicionar>Nova Pasta. Crie uma pasta chamada bin.
  2. Clique com o botão direito do mouse na pasta bin e selecione Adicionar>Item Existente. Selecione o instalador do .NET e adicione-o à pasta bin.

Para adicionar o instalador para uma função de trabalho:

  • Clique com o botão direito do mouse na função de trabalho e selecione Adicionar>Item Existente. Selecione o instalador do .NET e adicione-o à função.

Quando arquivos são adicionados dessa forma à pasta de conteúdo da função, eles são adicionados automaticamente ao seu pacote de serviço de nuvem. Em seguida, os arquivos são implantados em um local consistente na máquina virtual. Repita esse processo para cada função Web e de trabalho em seu serviço de nuvem para que todas as funções tenham uma cópia do instalador.

Observação

Você deve instalar .NET Framework 4.6.2 em sua função de serviço de nuvem mesmo que seu aplicativo tenha como destino .NET Framework 4.6. O SO convidado inclui a atualização 3098779 e a atualização 3097997 da Base de Dados de Conhecimento. Poderão ocorrer problemas quando você executar seus aplicativos .NET se o .NET Framework 4.6 estiver instalado sobre as atualizações da base de dados de conhecimento. Para evitar esses problemas, instale .NET Framework 4.6.2 em vez da versão 4.6. Para obter mais informações, consulte o Artigo 3118750 da Base de Dados de Conhecimento e 4340191.

Conteúdos de função com arquivos do instalador

Defina tarefas de inicialização para suas funções

Você pode usar as tarefas de inicialização para executar operações antes do início de uma função. Instalar o .NET Framework como parte da tarefa de inicialização garante que ele seja instalado antes que qualquer código de aplicativo seja executado. Para obter mais informações sobre as tarefas de inicialização, consulte Execução de tarefas de inicialização no Azure.

  1. Adicione o seguinte conteúdo ao arquivo ServiceDefinition.sdef sob o nó WebRole ou WorkerRole para todas as funções:

    <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>
    

    A configuração anterior executa o comando do console install.cmd com privilégios de administrador a fim de instalar o .NET Framework. A configuração também cria um elemento LocalStorage com o nome NETFXInstall. O script de inicialização define a pasta temporária para usar esse recurso de armazenamento local.

    Importante

    Para garantir a instalação correta do Framework, defina o tamanho desse recurso como, pelo menos, 1.024 MB.

    Para saber mais sobre as tarefas de inicialização, consulte Tarefas de inicialização comuns dos Serviço de Nuvem do Azure.

  2. Crie um arquivo chamado install.cmd e adicione o seguinte script de instalação a ele.

    O script verifica se a versão especificada do .NET Framework já está instalada no computador consultando o registro. Se a versão do .NET Framework não estiver instalada, o instalador da Web do .NET Framework será aberto. Para ajudar com a solução de problemas, o script registra todas as atividades no arquivo startuptasklog-(data e hora atual).txt colocado no armazenamento local InstallLogs.

    Importante

    Use um editor de texto básico, como o Bloco de Notas do Windows, para criar o arquivo install.cmd. Se você usar o Visual Studio para criar um arquivo de texto e alterar a extensão para .cmd, o arquivo ainda poderá conter uma marca de ordem de byte de UTF-8. Essa marca pode causar um erro quando a primeira linha do script for executada. Para evitar esse erro, faça com que a primeira linha do script seja uma instrução REM, que pode ser ignorada pelo processamento de ordem de byte.

    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. Adicione o arquivo install.cmd a cada função usando Adicionar>Item Existente no Gerenciador de Soluções, conforme descrito anteriormente neste tópico.

    Após a conclusão desta etapa, todas as funções devem ter o arquivo do instalador do .NET, assim como o arquivo install.cmd.

    Conteúdo da função com todos os arquivos

Configurar o Diagnóstico para transferir logs de inicialização para o Armazenamento de Blobs

Para simplificar a solução de problemas de instalação, você pode configurar o Diagnóstico do Azure para transferir os arquivos de log gerados pelo script de inicialização ou pelo instalador do .NET para o Armazenamento de Blobs do Azure. Usando essa abordagem, você pode exibir os logs baixando os arquivos de log do Armazenamento de Blobs em vez de usar a área de trabalho remota na função.

Para configurar o Diagnóstico, abra o arquivo diagnostics.wadcfgx e adicione o seguinte conteúdo abaixo do nó Diretórios:

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

Esse XML configura o Diagnóstico para transferir os arquivos no diretório do log no recurso NETFXInstall para a conta de armazenamento do Diagnóstico no contêiner de blobs netfx-install.

Implantar o serviço de nuvem

Quando você implanta o serviço de nuvem, as tarefas de inicialização instalam o .NET Framework se ele ainda não estiver instalado. As funções do serviço de nuvem ficam no estado ocupado enquanto o Framework está sendo instalado. Se a instalação do Framework exigir uma reinicialização, as funções do serviço também poderão ser reiniciadas.

Recursos adicionais