Поделиться через


Стандартные задачи запуска в Облачных службах (классических)

Это важно

Облачные службы (классическая версия) теперь не поддерживается для всех пользователей с 1 сентября 2024 года. Все существующие запущенные развертывания будут остановлены и завершены корпорацией Майкрософт, и данные будут окончательно потеряны начиная с октября 2024 года. Для новых развертываний следует использовать Облачные службы Azure с расширенной поддержкой. Это новая модель развертывания на основе Azure Resource Manager.

В этой статье приведены некоторые примеры стандартных задач запуска, которые можно выполнить в облачной службе. С помощью задач запуска вы можете выполнять различные операции перед запуском роли. Операции, которые могут потребоваться выполнить, включают установку компонента, регистрацию компонентов объектной модели (COM), настройку разделов реестра или запуск длительного процесса.

Эта статья поможет понять, как работают задачи запуска, и, в частности, как создавать записи, которые определяют задачу запуска.

Примечание.

Задачи запуска неприменимы к виртуальным машинам, они подходят только для веб-ролей и рабочих ролей облачной службы.

Определение переменных среды до запуска роли

Если требуется определить переменные среды для конкретной задачи, можно использовать элемент Environment внутри элемента Task

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
    <WorkerRole name="WorkerRole1">
        ...
        <Startup>
            <Task commandLine="Startup.cmd" executionContext="limited" taskType="simple">
                <Environment>
                    <Variable name="MyEnvironmentVariable" value="MyVariableValue" />
                </Environment>
            </Task>
        </Startup>
    </WorkerRole>
</ServiceDefinition>

В переменных также может использоваться допустимое значение XPath Azure для ссылки на что-либо, относящееся к развертыванию. Вместо использования атрибута value определите дочерний элемент RoleInstanceValue .

<Variable name="PathToStartupStorage">
    <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='StartupLocalStorage']/@path" />
</Variable>

Настройка запуска IIS с помощью AppCmd.exe

Средство командной строки AppCmd.exe можно использовать для управления параметрами службы IIS при запуске в Azure. AppCmd.exe предоставляет удобный доступ из командной строки к параметрам конфигурации, используемым в задачах запуска в Azure. При использовании AppCmd.exe параметры веб-сайта можно добавлять, изменять или удалять для приложений и сайтов.

Однако следует знать о некоторых особенностях использования AppCmd.exe в качестве задачи запуска:

  • Задачи запуска могут несколько раз выполняться между перезагрузками. Например, при перезапуске роли.
  • Если действие AppCmd.exe выполняется несколько раз, может произойти ошибка. Например, попытка дважды добавить раздел в Web.config приведет к ошибке.
  • Задачи запуска завершаются сбоем, если они возвращают ненулевой код выхода или errorlevel. Например, если AppCmd.exe выдает ошибку.

Рекомендуется проверять уровень ошибки после вызова AppCmd.exe, что легко сделать, если обернуть вызов AppCmd.exe в файл .cmd. При обнаружении известного значения errorlevel его можно игнорировать или передать обратно.

Значения ошибок, возвращаемые AppCmd.exe, перечислены в файле winerror.h, а также можно увидеть в сети разработчиков Майкрософт (MSDN).

Пример управления уровнем ошибок

Этот пример добавляет раздел сжатия и запись сжатия для JSON в файл Web.config с обработкой ошибок и ведением журнала.

Здесь показаны соответствующие разделы файла ServiceDefinition.csdef, которые включают в себя присвоение атрибуту executionContext значения elevated. Так AppCmd.exe предоставляются достаточные разрешения для изменения параметров в файле Web.config:

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
    <WorkerRole name="WorkerRole1">
        ...
        <Startup>
            <Task commandLine="Startup.cmd" executionContext="elevated" taskType="simple" />
        </Startup>
    </WorkerRole>
</ServiceDefinition>

Пакетный файл Startup.cmd использует AppCmd.exe для добавления раздела сжатия и записи сжатия для JSON в файл Web.config. Ожидаемое значение errorlevel 183 сбрасывается на ноль с помощью программы командной строки VERIFY.EXE. Неожиданные уровни ошибок заносятся в файл StartupErrorLog.txt.

REM   *** Add a compression section to the Web.config file. ***
%windir%\system32\inetsrv\appcmd set config /section:urlCompression /doDynamicCompression:True /commit:apphost >> "%TEMP%\StartupLog.txt" 2>&1

REM   ERRORLEVEL 183 occurs when trying to add a section that already exists. This error is expected if this
REM   batch file were executed twice. This can occur and must be accounted for in an Azure startup
REM   task. To handle this situation, set the ERRORLEVEL to zero by using the Verify command. The Verify
REM   command will safely set the ERRORLEVEL to zero.
IF %ERRORLEVEL% EQU 183 VERIFY > NUL

REM   If the ERRORLEVEL is not zero at this point, some other error occurred.
IF %ERRORLEVEL% NEQ 0 (
    ECHO Error adding a compression section to the Web.config file. >> "%TEMP%\StartupLog.txt" 2>&1
    GOTO ErrorExit
)

REM   *** Add compression for json. ***
%windir%\system32\inetsrv\appcmd set config  -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost >> "%TEMP%\StartupLog.txt" 2>&1
IF %ERRORLEVEL% EQU 183 VERIFY > NUL
IF %ERRORLEVEL% NEQ 0 (
    ECHO Error adding the JSON compression type to the Web.config file. >> "%TEMP%\StartupLog.txt" 2>&1
    GOTO ErrorExit
)

REM   *** Exit batch file. ***
EXIT /b 0

REM   *** Log error and exit ***
:ErrorExit
REM   Report the date, time, and ERRORLEVEL of the error.
DATE /T >> "%TEMP%\StartupLog.txt" 2>&1
TIME /T >> "%TEMP%\StartupLog.txt" 2>&1
ECHO An error occurred during startup. ERRORLEVEL = %ERRORLEVEL% >> "%TEMP%\StartupLog.txt" 2>&1
EXIT %ERRORLEVEL%

Добавление правил брандмауэра

Фактически в Azure есть два брандмауэра. Первый брандмауэр управляет подключениями между виртуальной машиной и внешним миром. Элемент EndPoints в файле ServiceDefinition.csdef управляет этим брандмауэром.

Второй брандмауэр управляет подключениями между виртуальной машиной и процессами в этой виртуальной машине. Этот брандмауэр можно контролировать с помощью средства командной netsh advfirewall firewall строки.

Azure создает правила брандмауэра для процессов, запущенных в ваших ролях. Например, при запуске службы или программы Azure автоматически создает необходимые правила брандмауэра, чтобы служба могла взаимодействовать с Интернетом. Однако если вы создаете службу, запущенную процессом вне роли (например, службой COM+ или запланированной задачей Windows), необходимо вручную создать правило брандмауэра, чтобы разрешить доступ к этой службе. Эти правила брандмауэра можно создавать с помощью задачи запуска.

Задача запуска, которая создает правило брандмауэра, должна иметь executionContext со значением elevated. Добавьте следующую задачу запуска в файл ServiceDefinition.csdef .

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
    <WorkerRole name="WorkerRole1">
        ...
        <Startup>
            <Task commandLine="AddFirewallRules.cmd" executionContext="elevated" taskType="simple" />
        </Startup>
    </WorkerRole>
</ServiceDefinition>

Чтобы добавить правило брандмауэра, необходимо использовать в пакетном файле запуска соответствующие команды netsh advfirewall firewall . В этом примере задача запуска требует безопасности и шифрования для tcp-порта 80.

REM   Add a firewall rule in a startup task.

REM   Add an inbound rule requiring security and encryption for TCP port 80 traffic.
netsh advfirewall firewall add rule name="Require Encryption for Inbound TCP/80" protocol=TCP dir=in localport=80 security=authdynenc action=allow >> "%TEMP%\StartupLog.txt" 2>&1

REM   If an error occurred, return the errorlevel.
EXIT /B %errorlevel%

Блокирование определенного IP-адреса

Доступ к веб-роли Azure можно ограничить набором указанных IP-адресов, изменив файл IIS web.config. Также необходимо использовать файл команды, который разблокирует раздел ipSecurity файла ApplicationHost.config.

Чтобы разблокировать раздел ipSecurity файла ApplicationHost.config, создайте командный файл, который запускается при запуске роли. Создайте папку startup на корневом уровне веб-роли, а в этой папке создайте пакетный файл startup.cmd. Добавьте этот файл в проект Visual Studio и задайте свойства Always Copy, чтобы убедиться, что он включен в пакет.

Добавьте следующую задачу запуска в файл ServiceDefinition.csdef .

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
    <WebRole name="WebRole1">
        ...
        <Startup>
            <Task commandLine="startup.cmd" executionContext="elevated" />
        </Startup>
    </WebRole>
</ServiceDefinition>

Добавьте эту команду в файл startup.cmd :

@echo off
@echo Installing "IPv4 Address and Domain Restrictions" feature 
powershell -ExecutionPolicy Unrestricted -command "Install-WindowsFeature Web-IP-Security"
@echo Unlocking configuration for "IPv4 Address and Domain Restrictions" feature 
%windir%\system32\inetsrv\AppCmd.exe unlock config -section:system.webServer/security/ipSecurity

В результате пакетный файл startup.cmd будет запускаться каждый раз при инициализации веб-роли, что разблокирует необходимый раздел ipSecurity.

Наконец, измените раздел system.webServer в файле web.config веб-роли, чтобы добавить список IP-адресов, к которым предоставлен доступ, как показано в следующем примере:

В этом примере конфигурации доступ к серверу разрешен всем IP-адресам, за исключением двух определенных.

<system.webServer>
    <security>
    <!--Unlisted IP addresses are granted access-->
    <ipSecurity>
        <!--The following IP addresses are denied access-->
        <add allowed="false" ipAddress="192.168.100.1" subnetMask="255.255.0.0" />
        <add allowed="false" ipAddress="192.168.100.2" subnetMask="255.255.0.0" />
    </ipSecurity>
    </security>
</system.webServer>

В этом примере конфигурации доступ к серверу запрещен всем IP-адресам, за исключением двух определенных.

<system.webServer>
    <security>
    <!--Unlisted IP addresses are denied access-->
    <ipSecurity allowUnlisted="false">
        <!--The following IP addresses are granted access-->
        <add allowed="true" ipAddress="192.168.100.1" subnetMask="255.255.0.0" />
        <add allowed="true" ipAddress="192.168.100.2" subnetMask="255.255.0.0" />
    </ipSecurity>
    </security>
</system.webServer>

Создание задачи запуска PowerShell.

Скрипты Windows PowerShell не могут вызываться непосредственно из файла ServiceDefinition.csdef , но их можно вызывать в пакетном файле запуска.

PowerShell (по умолчанию) не выполняет неподписанные скрипты. Если сценарии не подписаны, необходимо настроить PowerShell для запуска неподписанных сценариев. Для запуска неподписанных сценариев параметру ExecutionPolicy необходимо присвоить значение Unrestricted. Используемый параметр ExecutionPolicy зависит от версии Windows PowerShell.

REM   Run an unsigned PowerShell script and log the output
PowerShell -ExecutionPolicy Unrestricted .\startup.ps1 >> "%TEMP%\StartupLog.txt" 2>&1

REM   If an error occurred, return the errorlevel.
EXIT /B %errorlevel%

Если вы используете гостевую ОС, на которой выполняется PowerShell 2.0 или 1.0, можно принудительно выполнить версию 2, и если она недоступна, использовать версию 1.

REM   Attempt to set the execution policy by using PowerShell version 2.0 syntax.
PowerShell -Version 2.0 -ExecutionPolicy Unrestricted .\startup.ps1 >> "%TEMP%\StartupLog.txt" 2>&1

REM   If PowerShell version 2.0 isn't available. Set the execution policy by using the PowerShell
IF %ERRORLEVEL% EQU -393216 (
   PowerShell -Command "Set-ExecutionPolicy Unrestricted" >> "%TEMP%\StartupLog.txt" 2>&1
   PowerShell .\startup.ps1 >> "%TEMP%\StartupLog.txt" 2>&1
)

REM   If an error occurred, return the errorlevel.
EXIT /B %errorlevel%

Создание файлов в локальном хранилище из задачи запуска

Вы можете использовать локальный ресурс хранилища для хранения файлов, созданных задачей запуска, к которым позже обращается ваше приложение.

Для создания локального ресурса хранилища добавьте раздел LocalResources в файл ServiceDefinition.csdef, затем добавьте дочерний элемент LocalStorage. Присвойте локальному ресурсу хранилища уникальное имя и задайте соответствующий размер для задачи запуска.

Чтобы использовать локальный ресурс хранилища в задаче запуска, необходимо создать переменную среды для ссылки на расположение локального ресурса хранилища. Затем задача запуска и приложение смогут выполнять чтение и запись файлов в локальный ресурс хранилища.

Соответствующие разделы файла ServiceDefinition.csdef показаны ниже:

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WorkerRole name="WorkerRole1">
    ...

    <LocalResources>
      <LocalStorage name="StartupLocalStorage" sizeInMB="5"/>
    </LocalResources>

    <Startup>
      <Task commandLine="Startup.cmd" executionContext="limited" taskType="simple">
        <Environment>
          <Variable name="PathToStartupStorage">
            <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='StartupLocalStorage']/@path" />
          </Variable>
        </Environment>
      </Task>
    </Startup>
  </WorkerRole>
</ServiceDefinition>

Например, этот пакетный файл Startup.cmd использует переменную среды PathToStartupStorage, чтобы создать файл MyTest.txt в локальном хранилище.

REM   Create a simple text file.

ECHO This text will go into the MyTest.txt file which will be in the    >  "%PathToStartupStorage%\MyTest.txt"
ECHO path pointed to by the PathToStartupStorage environment variable.  >> "%PathToStartupStorage%\MyTest.txt"
ECHO The contents of the PathToStartupStorage environment variable is   >> "%PathToStartupStorage%\MyTest.txt"
ECHO "%PathToStartupStorage%".                                          >> "%PathToStartupStorage%\MyTest.txt"

REM   Exit the batch file with ERRORLEVEL 0.

EXIT /b 0

Обратиться к папке локального хранилища можно из пакета SDK для Azure с помощью метода GetLocalResource.

string localStoragePath = Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetLocalResource("StartupLocalStorage").RootPath;

string fileContent = System.IO.File.ReadAllText(System.IO.Path.Combine(localStoragePath, "MyTestFile.txt"));

Запуск в эмуляторе или облаке

Вы можете настроить выполнение различных шагов вашей задачи при запуске, в зависимости от того, работает ли она в облаке или в эмуляторе вычислений. Например, вам может понадобиться использовать обновлённую версию ваших данных SQL только при работе в эмуляторе. Кроме того, может понадобиться каким-либо образом оптимизировать производительность для облака, что не требуется при выполнении в эмуляторе.

Эту возможность выполнять различные действия в эмуляторе вычислений и облаке можно получить, создав переменную среды в файле ServiceDefinition.csdef. Затем вы проверяете эту переменную среды на наличие определённого значения в вашей задаче запуска.

Чтобы создать переменную среды, добавьте элемент Variable/RoleInstanceValue и создайте значение XPath /RoleEnvironment/Deployment/@emulated. При выполнении в эмуляторе вычислений переменная среды %ComputeEmulatorRunning% приобретает значение true, а при выполнении в облаке — false.

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WorkerRole name="WorkerRole1">

    ...

    <Startup>
      <Task commandLine="Startup.cmd" executionContext="limited" taskType="simple">
        <Environment>
          <Variable name="ComputeEmulatorRunning">
            <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
          </Variable>
        </Environment>
      </Task>
    </Startup>

  </WorkerRole>
</ServiceDefinition>

Теперь задача может проверить переменную среды %ComputeEmulatorRunning% для выполнения разных действий в зависимости от того, где выполняется роль —в облаке или эмуляторе. Ниже приведен скрипт оболочки .cmd, который проверяет наличие этой переменной среды.

REM   Check if this task is running on the compute emulator.

IF "%ComputeEmulatorRunning%" == "true" (
    REM   This task is running on the compute emulator. Perform tasks that must be run only in the compute emulator.
) ELSE (
    REM   This task is running on the cloud. Perform tasks that must be run only in the cloud.
)

Определите, что ваша задача уже выполнена

Роль может обновляться без перезагрузки, вызывая повторный запуск ваших начальных задач. Нет флага, указывающего, что задача уже запущена на виртуальной машине узла. Возможно, для некоторых задач не важно, сколько раз они выполняются. Однако возможны ситуации, когда нужно предотвратить выполнение задачи несколько раз.

Самый простой способ определить, что задача уже была запущена, —создавать файл в папке %TEMP% , если задача выполнена успешно, и искать его при запуске задачи. Вот пример скрипта оболочки cmd, который делает это для вас.

REM   If Task1_Success.txt exists, then Application 1 is already installed.
IF EXIST "%PathToApp1Install%\Task1_Success.txt" (
  ECHO Application 1 is already installed. Exiting. >> "%TEMP%\StartupLog.txt" 2>&1
  GOTO Finish
)

REM   Run your real exe task
ECHO Running XYZ >> "%TEMP%\StartupLog.txt" 2>&1
"%PathToApp1Install%\setup.exe" >> "%TEMP%\StartupLog.txt" 2>&1

IF %ERRORLEVEL% EQU 0 (
  REM   The application installed without error. Create a file to indicate that the task
  REM   does not need to be run again.

  ECHO This line will create a file to indicate that Application 1 installed correctly. > "%PathToApp1Install%\Task1_Success.txt"

) ELSE (
  REM   An error occurred. Log the error and exit with the error code.

  DATE /T >> "%TEMP%\StartupLog.txt" 2>&1
  TIME /T >> "%TEMP%\StartupLog.txt" 2>&1
  ECHO  An error occurred running task 1. Errorlevel = %ERRORLEVEL%. >> "%TEMP%\StartupLog.txt" 2>&1

  EXIT %ERRORLEVEL%
)

:Finish

REM   Exit normally.
EXIT /B 0

Рекомендации по лучшим практикам выполнения задач

Ниже приведены некоторые рекомендации, которые необходимо выполнять при настройке задачи для рабочей роли или веб-роли.

Всегда ведите журнал операций запуска

Visual Studio не предоставляет отладчик для пошагового выполнения пакетных файлов, поэтому хорошо получать столько данных о работе пакетных файлов, сколько это возможно. Ведение журнала выходных данных пакетных файлов, stdout и stderr, может предоставить вам важную информацию при попытке отладить и исправить пакетные файлы. Чтобы записывать stdout и stderr в файл StartupLog.txt в каталоге, указанном переменной среды %TEMP%, добавьте текст >> "%TEMP%\\StartupLog.txt" 2>&1 в конец конкретных строк, которые вы хотите записывать в журнал. Например, так можно выполнить setup.exe в каталоге %PathToApp1Install%: "%PathToApp1Install%\setup.exe" >> "%TEMP%\StartupLog.txt" 2>&1

Чтобы упростить XML, можно создать файл-оболочку CMD, который вызывает все задачи запуска, ведет журналы и гарантирует, что все дочерние задачи используют одинаковые переменные среды

Иногда может быть неудобно использовать >> "%TEMP%\StartupLog.txt" 2>&1 в конце каждой задачи запуска. Чтобы настроить принудительную регистрацию задач, можно создать оболочку, которая выполняет ведение журнала автоматически. Эта оболочка вызывает действительный пакетный файл, который нужно запустить. Все выходные данные целевого пакетного файла перенаправляются в файл Startuplog.txt .

В примере ниже показано, как перенаправить все выходные данные из пакетного файла запуска. В этом примере файл ServerDefinition.csdef создает задачу запуска, которая называется logwrap.cmd. logwrap.cmd вызывает Startup2.cmd, перенаправляя все выходные данные в %TEMP%\StartupLog.txt.

ServiceDefinition.cmd:

<Startup>
    <Task commandLine="logwrap.cmd startup2.cmd" executionContext="limited" taskType="simple" />
</Startup>

logwrap.cmd:

@ECHO OFF

REM   logwrap.cmd calls passed in batch file, redirecting all output to the StartupLog.txt log file.

ECHO [%date% %time%] == START logwrap.cmd ============================================== >> "%TEMP%\StartupLog.txt" 2>&1
ECHO [%date% %time%] Running %1 >> "%TEMP%\StartupLog.txt" 2>&1

REM   Call the child command batch file, redirecting all output to the StartupLog.txt log file.
START /B /WAIT %1 >> "%TEMP%\StartupLog.txt" 2>&1

REM   Log the completion of child command.
ECHO [%date% %time%] Done >> "%TEMP%\StartupLog.txt" 2>&1

IF %ERRORLEVEL% EQU 0 (

   REM   No errors occurred. Exit logwrap.cmd normally.
   ECHO [%date% %time%] == END logwrap.cmd ================================================ >> "%TEMP%\StartupLog.txt" 2>&1
   ECHO.  >> "%TEMP%\StartupLog.txt" 2>&1
   EXIT /B 0

) ELSE (

   REM   Log the error.
   ECHO [%date% %time%] An error occurred. The ERRORLEVEL = %ERRORLEVEL%.  >> "%TEMP%\StartupLog.txt" 2>&1
   ECHO [%date% %time%] == END logwrap.cmd ================================================ >> "%TEMP%\StartupLog.txt" 2>&1
   ECHO.  >> "%TEMP%\StartupLog.txt" 2>&1
   EXIT /B %ERRORLEVEL%

)

Startup2.cmd:

@ECHO OFF

REM   This is the batch file where the startup steps should be performed. Because of the
REM   way Startup2.cmd was called, all commands and their outputs will be stored in the
REM   StartupLog.txt file in the directory pointed to by the TEMP environment variable.

REM   If an error occurs, the following command will pass the ERRORLEVEL back to the
REM   calling batch file.

ECHO [%date% %time%] Some log information about this task
ECHO [%date% %time%] Some more log information about this task

EXIT %ERRORLEVEL%

Пример выходных данных в файле StartupLog.txt:

[Mon 10/17/2016 20:24:46.75] == START logwrap.cmd ============================================== 
[Mon 10/17/2016 20:24:46.75] Running command1.cmd 
[Mon 10/17/2016 20:24:46.77] Some log information about this task
[Mon 10/17/2016 20:24:46.77] Some more log information about this task
[Mon 10/17/2016 20:24:46.77] Done 
[Mon 10/17/2016 20:24:46.77] == END logwrap.cmd ================================================ 

Подсказка

Файл StartupLog.txt находится в папке C:\Resources\temp\{role identifier}\RoleTemp.

Правильная настройка executionContext для задач запуска

Задайте соответствующие привилегии для задачи запуска. Иногда задачи запуска должны выполняться с повышенными привилегиями, даже несмотря на то, что роль запускается с обычными привилегиями.

Атрибут executionContext задает уровень привилегий задачи запуска. Использование executionContext="limited" означает, что задаче запуска назначен тот же уровень привилегий, что и роли. Использование executionContext="elevated" означает, что задаче запуска назначены привилегии администратора, разрешающие задаче запуска выполнять операции администрирования без предоставления привилегий администратора вашей роли.

Примером задачи запуска, которой требуются повышенные привилегии, может послужить задача запуска, которая использует AppCmd.exe для настройки IIS. AppCmd.exe требуется executionContext="elevated".

Использование соответствующего taskType

Атрибут taskType определяет способ выполнения стартовой задачи. Он имеет три значения: simple, background и foreground. Фоновые и задачи переднего плана запускаются асинхронно, а затем синхронно одна за другой выполняются простые задачи.

С помощью простых задач запуска можно задать порядок выполнения задач, упорядочив их список в файле ServiceDefinition.csdef. Если простая задача заканчивается ненулевым кодом выхода, процедура запуска останавливается и роль не запускается.

Разница между фоновыми задачами запуска и задачами запуска переднего плана состоит в том, что задачи переднего плана поддерживают выполнение роли до тех пор, пока задача переднего плана не завершится. Эта структура означает, что если задача переднего плана зависает или падает, роль остается не освобожденной до принудительного закрытия задачи переднего плана. По этой причине рекомендуется использовать фоновые задачи для асинхронных задач запуска, если только не требуется использовать возможности задачи переднего плана.

Завершайте пакетные файлы командой EXIT /B 0

Роль начинается только в том случае, если уровень ошибки от каждой из ваших простых задач запуска равен нулю. Не все программы корректно задают errorlevel (код завершения), поэтому пакетный файл должен заканчиваться EXIT /B 0, если все выполнено правильно.

Отсутствие элемента EXIT /B 0 в конце пакетного файла запуска является распространенной причиной, по которой роли не запускаются.

Примечание.

Выяснилось, что при использовании параметра /B вложенные пакетные файлы иногда перестают отвечать. Возможно, стоит убедиться, что эта проблема не возникает, если другой пакетный файл вызывает ваш текущий пакетный файл, например, при использовании оболочки журнала. В этом случае можно опустить параметр /B.

Ожидайте многократного выполнения задач запуска

Не все переработки ролей включают перезагрузку, но все они предусматривают выполнение всех стартовых задач. Это означает, что задачи запуска должны выполняться несколько раз между перезагрузками без каких-либо проблем, которые рассматриваются в предыдущем разделе.

Используйте локальное хранилище для хранения файлов, которые должны использоваться в роли

Если вы хотите во время выполнения задачи запуска скопировать или создать файл, который затем будет доступен вашей роли, этот файл необходимо поместить в локальное хранилище. См. предыдущий раздел.

Дальнейшие действия

Ознакомьтесь с моделью и пакетом облачной службы

Узнайте, как работают задачи .

Создайте и разверните свой пакет облачной службы.