在 Azure 云服务角色上安装 .NETInstall .NET on Azure Cloud Services roles

本文介绍如何安装不随 Azure 来宾 OS 一起提供的 .NET Framework 版本。This article describes how to install versions of .NET Framework that don't come with the Azure Guest OS. 可使用来宾 OS 上的 .NET 配置云服务 web 角色和辅助角色。You can use .NET on the Guest OS to configure your cloud service web and worker roles.

例如,可在来宾 OS 系列 4(它不随 .NET Framework 4.6 的任何版本一起提供)上安装 .NET Framework 4.6.2。For example, you can install .NET Framework 4.6.2 on the Guest OS family 4, which doesn't come with any release of .NET Framework 4.6. (来宾 OS 系列 5 随 .NET Framework 4.6 一起提供。)有关最新的 Azure 来宾 OS 版本信息,请参阅 Azure 来宾 OS 发行动态(The Guest OS family 5 does come with .NET Framework 4.6.) For the latest information on the Azure Guest OS releases, see the Azure Guest OS release news.

重要

Azure SDK 2.9 包含对在来宾 OS 系列 4 或更早版本上部署 .NET Framework 4.6 的限制。The Azure SDK 2.9 contains a restriction on deploying .NET Framework 4.6 on the Guest OS family 4 or earlier. 有关此限制的修复方法可在 Microsoft 文档站点上找到。A fix for the restriction is available on the Microsoft Docs site.

要在 web 角色和辅助角色上安装 .NET,可将 .NET web 安装程序包括为云服务项目的一部分。To install .NET on your web and worker roles, include the .NET web installer as part of your cloud service project. 将安装程序作为角色启动任务的一部分启动。Start the installer as part of the role's startup tasks.

将 .NET 安装程序添加到项目Add the .NET installer to your project

若要下载 .NET Framework 的 Web 安装程序,请选择想要安装的版本:To download the web installer for the .NET Framework, choose the version that you want to install:

添加 web 角色的安装程序:To add the installer for a web role:

  1. 在“解决方案资源管理器” 中云服务项目中的“角色” 下,右键单击 web 角色,然后选择“添加” > “新文件夹” 。In Solution Explorer, under Roles in your cloud service project, right-click your web role and select Add > New Folder. 创建一个名为 bin 的文件夹。Create a folder named bin.
  2. 右键单击 bin 文件夹,并选择“添加” > >“现有项” 。Right-click the bin folder and select Add > Existing Item. 选择 .NET 安装程序,并将它添加到 bin 文件夹。Select the .NET installer and add it to the bin folder.

添加辅助 角色的安装程序:To add the installer for a worker role:

  • 右键单击辅助 角色,然后选择“添加” > “现有项” 。Right-click your worker role and select Add > Existing Item. 选择 .NET 安装程序,并将它添加到角色。Select the .NET installer and add it to the role.

当以此方式将文件添加到角色内容文件夹时,会自动将其添加到云服务包。When files are added in this way to the role content folder, they're automatically added to your cloud service package. 然后会将文件部署到虚拟机上的一致位置。The files are then deployed to a consistent location on the virtual machine. 对云服务中的每个 Web 和辅助角色重复此过程,以便所有角色都有安装程序的副本。Repeat this process for each web and worker role in your cloud service so that all roles have a copy of the installer.

备注

即使应用程序面向 .NET Framework 4.6,也应该在云服务角色上安装 .NET Framework 4.6.2。You should install .NET Framework 4.6.2 on your cloud service role even if your application targets .NET Framework 4.6. 来宾 OS 包括知识库更新 3098779更新 3097997The Guest OS includes the Knowledge Base update 3098779 and update 3097997. 如果在知识库更新的基础上安装了 .NET Framework 4.6,则运行 .NET 应用程序时可能会出现问题。Issues can occur when you run your .NET applications if .NET Framework 4.6 is installed on top of the Knowledge Base updates. 若要避免这些问题,请安装 .NET Framework 4.6.2,而不是版本 4.6。To avoid these issues, install .NET Framework 4.6.2 rather than version 4.6. 有关详细信息,请参阅知识库文章 31187504340191For more information, see the Knowledge Base article 3118750 and 4340191.

包含安装程序文件的角色内容

为角色定义启动任务Define startup tasks for your roles

角色启动之前,可以使用启动任务执行操作。You can use startup tasks to perform operations before a role starts. 安装 .NET Framework 作为启动任务的一部分,可确保在运行任何应用程序代码之前已安装好 Framework。Installing the .NET Framework as part of the startup task ensures that the framework is installed before any application code is run. 有关启动任务的详细信息,请参阅在 Azure 中运行启动任务For more information on startup tasks, see Run startup tasks in Azure.

  1. 将以下内容添加到所有角色的“WebRole” 或“WorkerRole” 节点下的 ServiceDefinition.csdef 文件中:Add the following content to the ServiceDefinition.csdef file under the WebRole or WorkerRole node for all roles:

    <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。The preceding configuration runs the console command install.cmd with administrator privileges to install the .NET Framework. 该配置还创建了一个名为“NETFXInstall” 的“LocalStorage” 元素。The configuration also creates a LocalStorage element named NETFXInstall. 启动脚本将临时文件夹设置为使用此本地存储资源。The startup script sets the temp folder to use this local storage resource.

    重要

    为确保能够正确安装框架,请将此资源的大小设置为至少 1,024 MB。To ensure correct installation of the framework, set the size of this resource to at least 1,024 MB.

    有关启动任务的详细信息,请参阅常见的 Azure 云服务启动任务For more information about startup tasks, see Common Azure Cloud Services startup tasks.

  2. 创建名为“install.cmd” 的文件并将以下安装脚本添加到该文件。Create a file named install.cmd and add the following install script to the file.

    脚本将通过查询注册表来检查指定的 .NET Framework 版本是否已安装在计算机上。The script checks whether the specified version of the .NET Framework is already installed on the machine by querying the registry. 如果未安装该 .NET Framework 版本,则将打开 .NET Framework Web 安装程序。If the .NET Framework version is not installed, then the .NET Framework web installer is opened. 为帮助排查任何问题,该脚本会将所有活动记录到文件 startuptasklog-(current date and time).txt(存储在“InstallLogs” 本地存储中)。To help troubleshoot any issues, the script logs all activity to the file startuptasklog-(current date and time).txt that is stored in InstallLogs local storage.

    重要

    使用 Windows 记事本等基本文本编辑器创建 install.cmd 文件。Use a basic text editor like Windows Notepad to create the install.cmd file. 如果使用 Visual Studio 创建文本文件并将扩展名更改为 .cmd,则文件可能仍包含 UTF-8 字节顺序标记。If you use Visual Studio to create a text file and change the extension to .cmd, the file might still contain a UTF-8 byte order mark. 运行该脚本的第一行时,此标记可能会导致错误。This mark can cause an error when the first line of the script is run. 为避免此错误,可将脚本第一行设为可被字节顺序处理过程跳过的 REM 语句。To avoid this error, make the first line of the script a REM statement that can be skipped by the byte order processing.

    REM Set the value of netfx to install appropriate .NET Framework. 
    REM ***** To install .NET 4.5.2 set the variable netfx to "NDP452" *****
    REM ***** To install .NET 4.6 set the variable netfx to "NDP46" *****
    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://www.microsoft.com/download/details.aspx?id=53345
    REM ***** To install .NET 4.7 set the variable netfx to "NDP47" ***** 
    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
    set netfx="NDP472"
    REM ***** To install .NET 4.8 set the variable netfx to "NDP48" ***** https://dotnet.microsoft.com/download/thank-you/net48
    
    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%=="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"
    goto logtimestamp
    
    :NDP46
    set "netfxinstallfile=NDP46-KB3045560-Web.exe"
    set netfxregkey="0x6004f"
    goto logtimestamp
    
    :NDP461
    set "netfxinstallfile=NDP461-KB3102438-Web.exe"
    set netfxregkey="0x6040e"
    goto logtimestamp
    
    :NDP462
    set "netfxinstallfile=NDP462-KB3151802-Web.exe"
    set netfxregkey="0x60632"
    goto logtimestamp
    
    :NDP47
    set "netfxinstallfile=NDP47-KB3186500-Web.exe"
    set netfxregkey="0x707FE"
    goto logtimestamp
    
    :NDP471
    set "netfxinstallfile=NDP471-KB4033344-Web.exe"
    set netfxregkey="0x709fc"
    goto logtimestamp
    
    :NDP472
    set "netfxinstallfile=NDP472-KB4054531-Web.exe"
    set netfxregkey="0x70BF6"
    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 ***** 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 文件添加到每个角色。Add the install.cmd file to each role by using Add > Existing Item in Solution Explorer as described earlier in this topic.

    完成此步骤后,所有角色应该都有 .NET 安装程序文件和 install.cmd 文件。After this step is complete, all roles should have the .NET installer file and the install.cmd file.

    包含所有文件的角色内容

配置诊断以将启动日志传输到 Blob 存储Configure Diagnostics to transfer startup logs to Blob storage

为了方便排查安装问题,可以配置 Azure 诊断,将启动脚本或 .NET 安装程序生成的任何日志文件传输到 Azure Blob 存储。To simplify troubleshooting installation issues, you can configure Azure Diagnostics to transfer any log files generated by the startup script or the .NET installer to Azure Blob storage. 使用这种方法,可通过从 blob 存储直接下载日志文件(而无需通过远程桌面访问角色)查看日志。By using this approach, you can view the logs by downloading the log files from Blob storage rather than having to remote desktop into the role.

若要配置诊断,请打开 diagnostics.wadcfgx 文件,并在“Directories” 节点下添加以下内容:To configure Diagnostics, open the diagnostics.wadcfgx file and add the following content under the Directories node:

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

此 XML 将诊断配置为将“NETFXInstall” 资源中日志目录中的文件传输到“netfx-install” blob 容器中的诊断存储帐户上。This XML configures Diagnostics to transfer the files in the log directory in the NETFXInstall resource to the Diagnostics storage account in the netfx-install blob container.

部署云服务Deploy your cloud service

部署云服务时,启动任务会安装 .NET Framework(如果尚未安装)。When you deploy your cloud service, the startup tasks install the .NET Framework if it's not already installed. 框架安装过程中,云服务角色处于“忙碌” 状态。Your cloud service roles are in the busy state while the framework is being installed. 如果框架安装需要重启,可能同时会重启服务角色。If the framework installation requires a restart, the service roles might also restart.

其他资源Additional resources