在 Azure 云服务角色上安装 .NET

本文介绍如何安装不随 Azure 来宾 OS 一起提供的 .NET Framework 版本。 可使用来宾 OS 上的 .NET 配置云服务 web 角色和辅助角色。

例如,可在来宾 OS 系列 4 上安装 .NET 4.6.2(它不随 .NET 4.6 的任何版本一起提供)。 (来宾 OS 系列 5 随 .NET 4.6 一起提供。)有关最新的 Azure 来宾 OS 版本信息,请参阅 Azure 来宾 OS 发行动态

Important

Azure SDK 2.9 包含一个限制,限制将 .NET 4.6 部署到来宾 OS 系列 4 或更早版本。 有关此限制的修复方法可在 Microsoft 文档站点上找到。

要在 web 角色和辅助角色上安装 .NET,可将 .NET web 安装程序包括为云服务项目的一部分。 将安装程序作为角色启动任务的一部分启动。

将 .NET 安装程序添加到项目

若要下载 .NET Framework 的 Web 安装程序,请选择想要安装的版本:

添加 web 角色的安装程序:

  1. 在“解决方案资源管理器”中云服务项目中的“角色”下,右键单击 web 角色,然后选择“添加” > “新文件夹”。 创建一个名为 bin 的文件夹。
  2. 右键单击 bin 文件夹,并选择“添加” > >“现有项”。 选择 .NET 安装程序,并将它添加到 bin 文件夹。

添加辅助角色的安装程序:

  • 右键单击辅助角色,然后选择“添加” > “现有项”。 选择 .NET 安装程序,并将它添加到角色。

当以此方式将文件添加到角色内容文件夹时,会自动将其添加到云服务包。 然后会将文件部署到虚拟机上的一致位置。 对云服务中的每个 Web 和辅助角色重复此过程,以便所有角色都有安装程序的副本。

Note

即使应用程序面向 .NET 4.6,也应该在云服务角色上安装 .NET 4.6.2。 来宾 OS 包括知识库更新 3098779更新 3097997。 如果在知识库更新上安装 .NET 4.6,运行 .NET 应用程序时可能会出现问题。 若要避免这些问题,请安装 .NET 4.6.2,而不是版本 4.6。 有关详细信息,请参阅知识库文章 3118750

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

为角色定义启动任务

角色启动之前,可以使用启动任务执行操作。 安装 .NET Framework 作为启动任务的一部分,可确保在运行任何应用程序代码之前已安装好 Framework。 有关启动任务的详细信息,请参阅在 Azure 中运行启动任务

  1. 将以下内容添加到所有角色的“WebRole”或“WorkerRole”节点下的 ServiceDefinition.csdef 文件中:

    <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。 该配置还创建了一个名为“NETFXInstall”的“LocalStorage”元素。 启动脚本将临时文件夹设置为使用此本地存储资源。

    Important

    为确保能够正确安装框架,请将此资源的大小设置为至少 1,024 MB。

    有关启动任务的详细信息,请参阅常见的 Azure 云服务启动任务

  2. 创建名为“install.cmd”的文件并将以下安装脚本添加到该文件。

    脚本将通过查询注册表来检查指定的 .NET Framework 版本是否已安装在计算机上。 如果未安装该 .NET 版本,则将打开 .Net Web 安装程序。 为帮助排查任何问题,该脚本会将所有活动记录到文件 startuptasklog-(current date and time).txt(存储在“InstallLogs”本地存储中)。

    Important

    使用 Windows 记事本等基本文本编辑器创建 install.cmd 文件。 如果使用 Visual Studio 创建文本文件并将扩展名更改为 .cmd,则文件可能仍包含 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" *****
    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" ***** http://go.microsoft.com/fwlink/?LinkId=671729
    REM ***** To install .NET 4.6.2 set the variable netfx to "NDP462" *****
    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" ***** http://go.microsoft.com/fwlink/?LinkId=852095
    REM ***** To install .NET 4.7.2 set the variable netfx to "NDP472" ***** http://go.microsoft.com/fwlink/?LinkId=863262
    set netfx="NDP472"
    
    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%
    
    :restart
    echo Restarting to complete .NET (%netfx%) installation >> %startuptasklog%
    EXIT /B %ERRORLEVEL%
    
    :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 安装程序生成的任何日志文件传输到 Azure Blob 存储。 使用这种方法,可从 blob 存储直接下载日志文件,而无需通过远程桌面访问角色,即可查看日志。

若要配置诊断,请打开 diagnostics.wadcfgx 文件,并在“Directories”节点下添加以下内容:

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

此 XML 将诊断配置为将“NETFXInstall”资源中日志目录中的文件传输到“netfx-install” blob 容器中的诊断存储帐户上。

部署云服务

部署云服务时,启动任务会安装 .NET Framework(如果尚未安装)。 框架安装过程中,云服务角色处于“忙碌”状态。 如果框架安装需要重启,可能同时会重启服务角色。

其他资源