在 Azure 云服务(经典)角色上安装 .NET
重要
从 2024 年 9 月 1 日开始,已弃用所有客户的云服务(经典版)。 从 2024 年 10 月开始,Microsoft 将停止并关闭任何正在运行的现有部署,数据将永久性丢失。 新部署应使用基于 Azure 资源管理器的新型部署模型 Azure 云服务(外延支持)。
本文介绍如何安装不随 Azure 来宾 OS 一起提供的 .NET Framework 版本。 可使用来宾 OS 上的 .NET 配置云服务 web 角色和辅助角色。
例如,可在来宾 OS 系列 4(它不随 .NET Framework 4.6 的任何版本一起提供)上安装 .NET Framework 4.6.2。 (来宾 OS 系列 5 随 .NET Framework 4.6 一起提供。)有关最新的 Azure 来宾 OS 版本信息,请参阅 Azure 来宾 OS 发行动态。
重要
Azure SDK 2.9 包含对在来宾 OS 系列 4 或更早版本上部署 .NET Framework 4.6 的限制。 azure-cloud-services-files
GitHub 存储库提供了限制的修补程序。
要在 web 角色和辅助角色上安装 .NET,可将 .NET web 安装程序包括为云服务项目的一部分。 将安装程序作为角色启动任务的一部分启动。
将 .NET 安装程序添加到项目
若要下载 .NET Framework 的 Web 安装程序,请选择想要安装的版本:
- .NET Framework 4.8.1 Web 安装程序
- .NET Framework 4.8 Web 安装程序
- .NET Framework 4.7.2 Web 安装程序
- .NET Framework 4.6.2 Web 安装程序
添加 web 角色的安装程序:
- 在“解决方案资源管理器” 中云服务项目中的“角色” 下,右键单击 web 角色,然后选择“添加” >“新文件夹” 。 创建一个名为 bin 的文件夹。
- 右键单击 bin 文件夹,并选择“添加” >>“现有项” 。 选择 .NET 安装程序,并将它添加到 bin 文件夹。
添加辅助 角色的安装程序:
- 右键单击辅助 角色,然后选择“添加” >“现有项” 。 选择 .NET 安装程序,并将它添加到角色。
当以此方式将文件添加到角色内容文件夹时,文件会自动添加到云服务包。 然后会将文件部署到虚拟机上的一致位置。 对云服务中的每个 Web 和辅助角色重复此过程,以便所有角色都有安装程序的副本。
注意
即使应用程序面向 .NET Framework 4.6,也应该在云服务角色上安装 .NET Framework 4.6.2。 来宾 OS 包括知识库更新 3098779和更新 3097997。 如果在知识库更新的基础上安装了 .NET Framework 4.6,则运行 .NET 应用程序时可能会出现问题。 若要避免这些问题,请安装 .NET Framework 4.6.2,而不是版本 4.6。 有关详细信息,请参阅知识库文章 3118750 和 4340191。
为角色定义启动任务
角色启动之前,可以使用启动任务执行操作。 安装 .NET Framework 作为启动任务的一部分,可确保在运行任何应用程序代码之前已安装好 Framework。 有关启动任务的详细信息,请参阅在 Azure 中运行启动任务。
将以下内容添加到所有角色的“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” 元素。 启动脚本将临时文件夹设置为使用此本地存储资源。重要
为确保能够正确安装框架,请将此资源的大小设置为至少 1,024 MB。
有关启动任务的详细信息,请参阅常见的 Azure 云服务启动任务。
创建名为“install.cmd” 的文件并将以下安装脚本添加到该文件。
脚本会通过查询注册表来检查指定的 .NET Framework 版本是否已存在于计算机上。 如果未安装该 .NET Framework 版本,则会打开 .NET Framework Web 安装程序。 为帮助排查任何问题,该脚本会将所有活动记录到文件 startuptasklog-(current date and time).txt(存储在“InstallLogs” 本地存储中)。
重要
使用 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" ***** 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
通过使用“解决方案资源管理器”中的“添加”>“现有项”,将 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(如果有必要)。 框架安装过程中,云服务角色处于“忙碌” 状态。 如果框架安装需要重启,可能同时会重启服务角色。