【问题标题】:Cloud Service (Classic) web/worker role startup script does not runCloud Service (Classic) web/worker 角色启动脚本不运行
【发布时间】:2019-09-20 23:55:32
【问题描述】:

我有一个 web/worker 角色,它有自定义启动脚本在角色启动时执行,以确保安装所需的 .NET 版本。

ServiceDefinition.csdef云服务文件:

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="MyServices" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
  <WebRole name="WebApiRole" vmsize="Standard_D1">
    <Sites>
      <Site name="Web" physicalDirectory="..\..\..\WebApiRole\">
        <Bindings>
          <Binding name="HttpIn" endpointName="HttpIn" />
          <Binding name="Endpoint1" endpointName="HttpsIn" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
      <InputEndpoint name="HttpsIn" protocol="https" port="443" certificate="myservices.com" />
    </Endpoints>
    <Certificates>
      <Certificate name="myservices.com" storeLocation="LocalMachine" storeName="CA" />
    </Certificates>
    <LocalResources>
      <LocalStorage name="InstallLogs" sizeInMB="5" cleanOnRoleRecycle="false" />
    </LocalResources>
    <Startup>
      <Task commandLine="install.cmd" executionContext="elevated" taskType="simple">
        <Environment>
          <Variable name="PathToInstallLogs">
            <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='InstallLogs']/@path" />
          </Variable>
        </Environment>
      </Task>
    </Startup>
    <Imports>
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
  </WebRole>
  <WorkerRole name="WorkerRole" vmsize="Standard_D1">
    <LocalResources>
      <LocalStorage name="CustomTempLocalStore" sizeInMB="2048" cleanOnRoleRecycle="true" />
      <LocalStorage name="InstallLogs" sizeInMB="5" cleanOnRoleRecycle="false" />
    </LocalResources>
    <Startup>
      <Task commandLine="install.cmd" executionContext="elevated" taskType="simple">
        <Environment>
          <Variable name="PathToInstallLogs">
            <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='InstallLogs']/@path" />
          </Variable>
        </Environment>
      </Task>
    </Startup>
    <Imports>
      <Import moduleName="RemoteAccess" />
    </Imports>
  </WorkerRole>
</ServiceDefinition>

据我所知,运行install.cmd的启动任务是根据microsoft docs

我可以确认在部署时 install.cmd 已部署在根文件夹 - AppRoot\Bin

如果我在云服务 VM 上手动执行 install.cmd,它会按预期运行。 但是,它不会在部署时运行,因此 web/worker 角色会不断回收(由于缺少代码所依赖的 .NET 版本)。

这是install.cmd的内容供参考

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" *****
set netfx="NDP48"

REM ***** Setup .NET filenames and registry keys *****
if %netfx%=="NDP48" goto NDP48
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="0x60051"
goto logtimestamp

:NDP48
set netfxinstallfile="ndp48-web.exe"
set netfxregkey="0x80eb1"
goto logtimestamp

:logtimestamp
REM ***** Setup LogFile with timestamp *****
set timehour=%time:~0,2%
set timestamp=%date:~-4,4%%date:~-10,2%%date:~-7,2%-%timehour: =0%%time:~3,2%
set startuptasklog=%PathToInstallLogs%startuptasklog-%timestamp%.txt
set netfxinstallerlog=%PathToInstallLogs%NetFXInstallerLog-%timestamp%
echo Logfile generated at: %startuptasklog% >> %startuptasklog%

REM ***** Check if .NET is installed *****
echo Checking if .NET (%netfx%) is installed >> %startuptasklog%
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" /v Release | Find %netfxregkey%
if %ERRORLEVEL%== 0 goto end

REM ***** Installing .NET *****
echo Installing .NET. Logfile: %netfxinstallerlog% >> %startuptasklog%
start /wait %~dp0%netfxinstallfile% /q /serialdownload /log %netfxinstallerlog% >> %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

:end
echo install.cmd completed: %date:~-4,4%%date:~-10,2%%date:~-7,2%-%timehour: =0%%time:~3,2% >> %startuptasklog%

:exit
EXIT /B 0

我可以确认ndp48-web.exe 可执行文件可以与install.cmd 一起在根文件夹下找到。 正如我所说,脚本在启动时不会执行(我在事件查看器中找不到任何日志,也没有任何条目)。

你知道这有什么问题吗?

【问题讨论】:

    标签: azure azure-cloud-services


    【解决方案1】:

    错误在install.cmd 脚本中。

    我在使用文档中的脚本 here 时遇到了同样的问题,这与您的类似。

    如果您仔细观察,日志文件的名称末尾有一个%timestamp%。这会使文件名的格式错误。它有/。因此,脚本第一次尝试写入日志文件时,会收到错误:The system cannot find the path specified.

    这成功结束了脚本,但没有做任何事情。它不创建任何日志,也不安装 .NET Framework。

    我的解决方案是更改时间戳格式,将%timestamp% 变量替换为我使用以下脚本计算的%dtStamp%

    @ECHO OFF
    SET HOUR=%time:~0,2%
    SET dtStamp9=%date:~-4%%date:~4,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 
    SET dtStamp24=%date:~-4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%
    if "%HOUR:~0,1%" == " " (SET dtStamp=%dtStamp9%) else (SET dtStamp=%dtStamp24%)
    @ECHO ON
    
    echo timestamp: %dtStamp%
    

    【讨论】:

    • 感谢您发布此信息。你会考虑在 Github 中为文档页面打开一个问题吗?我无法确认这是否是我案例的根本问题,但我切换回原来的脚本,该脚本缺少 .NET 4.8 安装部分,之后它开始工作,所以看起来这可能是问题所在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    • 2018-10-18
    • 1970-01-01
    相关资源
    最近更新 更多