Tarefas de inicialização comuns do Serviço de NuvemCommon Cloud Service startup tasks

Este artigo oferece alguns exemplos de tarefas de inicialização comuns que talvez você queira executar no serviço de nuvem.This article provides some examples of common startup tasks you may want to perform in your cloud service. Você pode usar as tarefas de inicialização para executar operações antes do início de uma função.You can use startup tasks to perform operations before a role starts. As operações que talvez você queira executar incluem a instalação de um componente, o registro de componentes COM, a configuração de chaves do registro ou o início de um processo de longa duração.Operations that you might want to perform include installing a component, registering COM components, setting registry keys, or starting a long running process.

Confira este artigo para entender o funcionamento das tarefas de inicialização e, especificamente, como criar as entradas que definem uma tarefa de inicialização.See this article to understand how startup tasks work, and specifically how to create the entries that define a startup task.

Observação

As tarefas de inicialização não são aplicáveis às Máquinas Virtuais, apenas às funções Web e de Trabalho do Serviço de Nuvem.Startup tasks are not applicable to Virtual Machines, only to Cloud Service Web and Worker roles.

Definir variáveis de ambiente antes de iniciar uma funçãoDefine environment variables before a role starts

Se você precisar de variáveis de ambiente definidas para uma tarefa específica, use o elemento Ambiente dentro do elemento Tarefa.If you need environment variables defined for a specific task, use the Environment element inside the Task element.

<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>

As variáveis também podem usar um valor válido do Azure XPath para fazer referência a algo sobre a implantação.Variables can also use a valid Azure XPath value to reference something about the deployment. Em vez de usar o atributo value , defina um elemento filho RoleInstanceValue .Instead of using the value attribute, define a RoleInstanceValue child element.

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

Configurar a inicialização do IIS com AppCmd.exeConfigure IIS startup with AppCmd.exe

A ferramenta de linha de comando AppCmd.exe pode ser usada para gerenciar as configurações do IIS na inicialização no Azure.The AppCmd.exe command-line tool can be used to manage IIS settings at startup on Azure. AppCmd.exe oferece acesso de linha de comando conveniente às definições de configuração para uso nas tarefas de inicialização no Azure.AppCmd.exe provides convenient, command-line access to configuration settings for use in startup tasks on Azure. Com AppCmd.exe, as configurações do site podem ser adicionadas, modificadas ou removidas para aplicativos e sites.Using AppCmd.exe, Website settings can be added, modified, or removed for applications and sites.

No entanto, há algumas coisas que merecem atenção no uso de AppCmd.exe como uma tarefa de inicialização:However, there are a few things to watch out for in the use of AppCmd.exe as a startup task:

  • As tarefas de inicialização podem ser executadas mais de uma vez entre as reinicializações.Startup tasks can be run more than once between reboots. Por exemplo, quando uma função é reciclada.For instance, when a role recycles.
  • Se uma ação AppCmd.exe for executada mais de uma vez, poderá gerar um erro.If a AppCmd.exe action is performed more than once, it may generate an error. Por exemplo, a tentativa de adicionar uma seção a Web.config duas vezes pode gerar um erro.For example, attempting to add a section to Web.config twice could generate an error.
  • As tarefas de inicialização falharão caso retornem um código de saída diferente de zero ou errorlevel.Startup tasks fail if they return a non-zero exit code or errorlevel. Por exemplo, quando AppCmd.exe gera um erro.For example, when AppCmd.exe generates an error.

É uma prática recomendada verificar errorlevel depois de chamar AppCmd.exe, o que é fácil se você encapsula a chamada a AppCmd.exe com um arquivo .cmd.It is a good practice to check the errorlevel after calling AppCmd.exe, which is easy to do if you wrap the call to AppCmd.exe with a .cmd file. Se você detectar uma resposta errorlevel conhecida, poderá ignorá-la ou passá-la novamente.If you detect a known errorlevel response, you can ignore it, or pass it back.

O errorlevel retornado por AppCmd.exe é listado no arquivo winerror.h e também pode ser visto no MSDN.The errorlevel returned by AppCmd.exe are listed in the winerror.h file, and can also be seen on MSDN.

Exemplo de gerenciamento de nível de erroExample of managing the error level

Este exemplo adiciona uma seção e uma entrada de compactação para JSON para o arquivo Web.config , com tratamento de erros e registro em log.This example adds a compression section and a compression entry for JSON to the Web.config file, with error handling and logging.

As seções relevantes do arquivo ServiceDefinition.csdef são mostradas aqui, o que inclui a definição do atributo executionContext como elevated para dar a AppCmd.exe permissões suficientes para alterar as configurações no arquivo Web.config:The relevant sections of the ServiceDefinition.csdef file are shown here, which include setting the executionContext attribute to elevated to give AppCmd.exe sufficient permissions to change the settings in the Web.config file:

<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>

O arquivo em lotes Startup.cmd usa AppCmd.exe para adicionar uma seção e uma entrada de compactação para JSON ao arquivo Web.config.The Startup.cmd batch file uses AppCmd.exe to add a compression section and a compression entry for JSON to the Web.config file. O errorlevel esperado de 183 é definido como zero usando o programa de linha de comando VERIFY.EXE.The expected errorlevel of 183 is set to zero using the VERIFY.EXE command-line program. Os errorlevels inesperados são registrados em StartupErrorLog.txt.Unexpected errorlevels are logged to 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 a 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 DO 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%

Adicionar regras de firewallAdd firewall rules

No Azure, há efetivamente dois firewalls.In Azure, there are effectively two firewalls. O primeiro firewall controla conexões entre a máquina virtual e o mundo externo.The first firewall controls connections between the virtual machine and the outside world. Esse firewall é controlado pelo elemento EndPoints no arquivo ServiceDefinition.csdef.This firewall is controlled by the EndPoints element in the ServiceDefinition.csdef file.

O segundo firewall controla conexões entre a máquina virtual e os processos dessa máquina virtual.The second firewall controls connections between the virtual machine and the processes within that virtual machine. Esse firewall pode ser controlada pela ferramenta de linha de comando netsh advfirewall firewall.This firewall can be controlled by the netsh advfirewall firewall command-line tool.

O Azure cria regras de firewall para processos iniciados em suas funções.Azure creates firewall rules for the processes started within your roles. Por exemplo, quando você inicia um serviço ou um programa, o Azure cria automaticamente as regras de firewall necessárias para permitir que o serviço ser comunique com a Internet.For example, when you start a service or program, Azure automatically creates the necessary firewall rules to allow that service to communicate with the Internet. No entanto, se você criar um serviço que é iniciado por um processo fora de sua função (como um serviço COM+ ou uma tarefa agendada do Windows), precisará criar manualmente uma regra de firewall para permitir o acesso a esse serviço.However, if you create a service that is started by a process outside your role (like a COM+ service or a Windows Scheduled Task), you need to manually create a firewall rule to allow access to that service. Essas regras de firewall podem ser criadas usando uma tarefa de inicialização.These firewall rules can be created by using a startup task.

Uma tarefa de inicialização que cria uma regra de firewall deve ter um executionContext elevado.A startup task that creates a firewall rule must have an executionContext of elevated. Adicione a seguinte tarefa de inicialização ao arquivo ServiceDefinition.csdef .Add the following startup task to the ServiceDefinition.csdef file.

<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>

Para adicionar a regra de firewall, você deverá usar os comandos netsh advfirewall firewall adequados no arquivo em lotes de inicialização.To add the firewall rule, you must use the appropriate netsh advfirewall firewall commands in your startup batch file. Neste exemplo, a tarefa de inicialização exige segurança e criptografia para a porta TCP 80.In this example, the startup task requires security and encryption for TCP port 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%

Bloquear um endereço IP específicoBlock a specific IP address

Você pode restringir um acesso de função Web do Azure para um conjunto de endereços IP especificados, modificando o IIS arquivo Web.config.You can restrict an Azure web role access to a set of specified IP addresses by modifying your IIS web.config file. Você também precisa usar um arquivo de comando que desbloqueie a seção ipSecurity do arquivo applicationHost.config.You also need to use a command file which unlocks the ipSecurity section of the ApplicationHost.config file.

Para desbloquear a seção ipSecurity do arquivo applicationHost. config, crie um arquivo de comando que é executado no início da função.To do unlock the ipSecurity section of the ApplicationHost.config file, create a command file that runs at role start. Crie uma pasta no nível raiz da sua função Web chamada startup e, nessa pasta, crie um arquivo em lotes chamado startup.cmd.Create a folder at the root level of your web role called startup and, within this folder, create a batch file called startup.cmd. Adicione esse arquivo ao projeto do Visual Studio e defina as propriedades como Copiar Sempre para garantir que ele seja incluído no pacote.Add this file to your Visual Studio project and set the properties to Copy Always to ensure that it is included in your package.

Adicione a seguinte tarefa de inicialização ao arquivo ServiceDefinition.csdef .Add the following startup task to the ServiceDefinition.csdef file.

<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>

Adicione este comando ao arquivo startup.cmd :Add this command to the startup.cmd file:

@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

Essa tarefa faz com que o arquivo em lotes startup.cmd seja executado sempre que a função Web for inicializada, garantindo que a seção ipSecurity necessária seja desbloqueada.This task causes the startup.cmd batch file to be run every time the web role is initialized, ensuring that the required ipSecurity section is unlocked.

Por fim, modifique a seção system.webServer do arquivo web.config da sua função Web para adicionar uma lista de endereços IP com acesso concedido, como mostrado neste exemplo:Finally, modify the system.webServer section your web role’s web.config file to add a list of IP addresses that are granted access, as shown in the following example:

Esta configuração de exemplo permite que todos os IPs acessem o servidor, exceto os dois definidosThis sample config allows all IPs to access the server except the two defined

<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>

Esta configuração de exemplo nega que todos os IPs acessem o servidor, exceto os dois definidos.This sample config denies all IPs from accessing the server except for the two defined.

<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>

Criar uma tarefa de inicialização do PowerShellCreate a PowerShell startup task

Os scripts do Windows PowerShell não podem ser chamados diretamente do arquivo ServiceDefinition.csdef , mas podem ser chamados de um arquivo em lotes de inicialização.Windows PowerShell scripts cannot be called directly from the ServiceDefinition.csdef file, but they can be invoked from within a startup batch file.

O PowerShell (por padrão) não executa scripts não assinados.PowerShell (by default) does not run unsigned scripts. A menos que você assine seu script, precisará configurar o PowerShell para executar scripts não assinados.Unless you sign your script, you need to configure PowerShell to run unsigned scripts. Para executar scripts não assinados, ExecutionPolicy deve ser definido como Irrestrito.To run unsigned scripts, the ExecutionPolicy must be set to Unrestricted. A configuração ExecutionPolicy que você usa baseia-se na versão do Windows PowerShell.The ExecutionPolicy setting that you use is based on the version of 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%

Se você estiver usando um SO Convidado que esteja executando o PowerShell 2.0 ou 1.0, poderá impor a execução da versão 2. Se ela não estiver disponível, use a versão 1.If you're using a Guest OS that is runs PowerShell 2.0 or 1.0 you can force version 2 to run, and if unavailable, use version 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%

Criar arquivos no armazenamento local de uma tarefa de inicializaçãoCreate files in local storage from a startup task

Você pode usar um recurso de armazenamento local para armazenar os arquivos criados pela tarefa de inicialização que será acessada posteriormente por seu aplicativo.You can use a local storage resource to store files created by your startup task that is accessed later by your application.

Para criar o recurso de armazenamento local, adicione uma seção LocalResources ao arquivo ServiceDefinition.csdef e adicione o elemento filho LocalStorage.To create the local storage resource, add a LocalResources section to the ServiceDefinition.csdef file and then add the LocalStorage child element. Dê ao recurso de armazenamento local um nome exclusivo e um tamanho adequado para sua tarefa de inicialização.Give the local storage resource a unique name and an appropriate size for your startup task.

Para usar um recurso de armazenamento local em sua tarefa de inicialização, será necessário criar uma variável de ambiente para fazer referência ao local do recurso de armazenamento local.To use a local storage resource in your startup task, you need to create an environment variable to reference the local storage resource location. Em seguida, a tarefa de Inicialização e o aplicativo podem ler e gravar arquivos no recurso de armazenamento local.Then the startup task and the application are able to read and write files to the local storage resource.

As seções relevantes do arquivo ServiceDefinition.csdef são mostradas aqui:The relevant sections of the ServiceDefinition.csdef file are shown here:

<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>

Como um exemplo, esse arquivo em lotes Startup.cmd usa a variável de ambiente PathToStartupStorage para criar o arquivo MyTest.txt no armazenamento local.As an example, this Startup.cmd batch file uses the PathToStartupStorage environment variable to create the file MyTest.txt on the local storage location.

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

Você pode acessar a pasta de armazenamento local do SDK do Azure usando o método GetLocalResource.You can access local storage folder from the Azure SDK by using the GetLocalResource method.

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

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

Executar no emulador ou na nuvemRun in the emulator or cloud

Você pode fazer com que sua tarefa de inicialização execute etapas diferentes quando estiver funcionando na nuvem em comparação a quando estiver no emulador de computação.You can have your startup task perform different steps when it is operating in the cloud compared to when it is in the compute emulator. Por exemplo, convém usar uma cópia atualizada dos dados SQL somente durante a execução no emulador.For example, you may want to use a fresh copy of your SQL data only when running in the emulator. Ou você talvez queira fazer alguma otimização de desempenho para a nuvem que não seja necessária na execução no emulador.Or you may want to do some performance optimizations for the cloud that you don't need to do when running in the emulator.

Essa capacidade de executar ações diferentes no emulador de computação e na nuvem pode ser obtida criando uma variável de ambiente no arquivo ServiceDefinition.csdef.This ability to perform different actions on the compute emulator and the cloud can be accomplished by creating an environment variable in the ServiceDefinition.csdef file. Você testa então essa variável de ambiente para um valor em sua tarefa de inicialização.You then test that environment variable for a value in your startup task.

Para criar a variável de ambiente, adicione o elemento Variable/RoleInstanceValue e crie um valor XPath de /RoleEnvironment/Deployment/@emulated.To create the environment variable, add the Variable/RoleInstanceValue element and create an XPath value of /RoleEnvironment/Deployment/@emulated. O valor da variável de ambiente %ComputeEmulatorRunning% é true na execução no emulador de computação e false na execução na nuvem.The value of the %ComputeEmulatorRunning% environment variable is true when running on the compute emulator, and false when running on the cloud.

<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>

Agora a tarefa pode verificar a variável de ambiente %ComputeEmulatorRunning% para executar ações diferentes com base na função estar em execução na nuvem ou no emulador.The task can now check the %ComputeEmulatorRunning% environment variable to perform different actions based on whether the role is running in the cloud or the emulator. A seguir, um script de shell .cmd que verifica essa variável de ambiente.Here is a .cmd shell script that checks for that environment variable.

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.
)

Detectar se a tarefa já foi executadaDetect that your task has already run

A função pode ser reciclada sem uma reinicialização, fazendo com que suas tarefas de inicialização sejam executadas novamente.The role may recycle without a reboot causing your startup tasks to run again. Não há um sinalizador para indicar se uma tarefa já foi executada na VM de host.There is no flag to indicate that a task has already run on the hosting VM. Talvez você tenha algumas tarefas onde não importará se elas forem executadas várias vezes.You may have some tasks where it doesn't matter that they run multiple times. No entanto, você poderá encontrar uma situação em que precisará impedir que uma tarefa seja executada mais de uma vez.However, you may run into a situation where you need to prevent a task from running more than once.

A maneira mais simples de detectar se uma tarefa já foi executada é criar um arquivo na pasta %TEMP% quando a tarefa for bem-sucedida e procurá-lo no início da tarefa.The simplest way to detect that a task has already run is to create a file in the %TEMP% folder when the task is successful and look for it at the start of the task. A seguir, um script de shell cmd de exemplo que faz isso para você.Here is a sample cmd shell script that does that for you.

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

Práticas recomendadas para tarefasTask best practices

A seguir, algumas práticas recomendadas que você deve seguir ao configurar a tarefa para sua função Web ou de trabalho.Here are some best practices you should follow when configuring task for your web or worker role.

Sempre registrar em log as atividades de inicializaçãoAlways log startup activities

O Visual Studio não fornece um depurador para percorrer arquivos em lotes e, portanto, será bom ter tantos dados sobre a operação de arquivos em lotes quanto possível.Visual Studio does not provide a debugger to step through batch files, so it's good to get as much data on the operation of batch files as possible. O registro em log da saída de arquivos em lotes, stdout e stderr, pode fornecer informações importantes ao tentar depurar e corrigir arquivos em lotes.Logging the output of batch files, both stdout and stderr, can give you important information when trying to debug and fix batch files. Para registrar em log stdout e stderr para o arquivo StartupLog.txt no diretório apontado pela variável de ambiente %TEMP%, adicione o texto >> "%TEMP%\\StartupLog.txt" 2>&1 ao final de linhas específicas que deseja registrar em log.To log both stdout and stderr to the StartupLog.txt file in the directory pointed to by the %TEMP% environment variable, add the text >> "%TEMP%\\StartupLog.txt" 2>&1 to the end of specific lines you want to log. Por exemplo, para executar setup.exe no diretório %PathToApp1Install% :For example, to execute setup.exe in the %PathToApp1Install% directory:

"%PathToApp1Install%\setup.exe" >> "%TEMP%\StartupLog.txt" 2>&1

Para simplificar o xml, você pode criar um arquivo wrapper cmd que chama todas as tarefas de inicialização, juntamente com o registro em log, e garante que cada tarefa filho compartilhe as mesmas variáveis de ambiente.To simplify your xml, you can create a wrapper cmd file that calls all of your startup tasks along with logging and ensures each child-task shares the same environment variables.

Porém, talvez você ache incômodo usar >> "%TEMP%\StartupLog.txt" 2>&1 ao fim de cada tarefa de inicialização.You may find it annoying though to use >> "%TEMP%\StartupLog.txt" 2>&1 on the end of each startup task. Você pode impor o log de tarefas criando um invólucro que manipula o registro em log para você.You can enforce task logging by creating a wrapper that handles logging for you. Este wrapper chama o arquivo de lote real que você deseja executar.This wrapper calls the real batch file you want to run. Nenhuma saída do arquivo de lote de destino será redirecionada para o arquivo startuplog.Any output from the target batch file will be redirected to the Startuplog.txt file.

O exemplo a seguir mostra como redirecionar todas as saídas de um arquivo em lotes de inicialização.The following example shows how to redirect all output from a startup batch file. Neste exemplo, o arquivo ServerDefinition.csdef cria uma tarefa de inicialização que chama logwrap.cmd.In this example, the ServerDefinition.csdef file creates a startup task that calls logwrap.cmd. logwrap.cmd chama Startup2.cmd, redirecionando toda a saída para %TEMP%\StartupLog.txt.logwrap.cmd calls Startup2.cmd, redirecting all output to %TEMP%\StartupLog.txt.

ServiceDefinition.cmd:ServiceDefinition.cmd:

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

logwrap.cmd: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: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%

Exemplo de saída no arquivo Startuplog:Sample output in the StartupLog.txt file:

[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 ================================================ 

Dica

O arquivo Startuplog está localizado na pasta C:\Resources\temp\{role identifier}\RoleTemp.The StartupLog.txt file is located in the C:\Resources\temp\{role identifier}\RoleTemp folder.

Definir executionContext adequadamente para tarefas de inicializaçãoSet executionContext appropriately for startup tasks

Definir privilégios adequadamente para a tarefa de inicialização.Set privileges appropriately for the startup task. Às vezes, as tarefas de inicialização devem ser executadas com privilégios elevados, mesmo que a função seja executada com privilégios normais.Sometimes startup tasks must run with elevated privileges even though the role runs with normal privileges.

A ferramenta de linha de comando executionContext define o nível de privilégio da tarefa de inicialização.The executionContext attribute sets the privilege level of the startup task. A utilização de executionContext="limited" significa que a tarefa de inicialização tem o mesmo nível de privilégio que a função.Using executionContext="limited" means the startup task has the same privilege level as the role. A utilização de executionContext="elevated" significa que a tarefa de inicialização tem privilégios de administrador, o que permite que a tarefa de inicialização execute tarefas de administrador sem conceder privilégios de administrador à sua função.Using executionContext="elevated" means the startup task has administrator privileges, which allows the startup task to perform administrator tasks without giving administrator privileges to your role.

Um exemplo de uma tarefa de inicialização que exija privilégios elevados é uma tarefa de inicialização que usa AppCmd.exe para configurar o IIS.An example of a startup task that requires elevated privileges is a startup task that uses AppCmd.exe to configure IIS. AppCmd.exe requer executionContext="elevated".AppCmd.exe requires executionContext="elevated".

Usar o taskType adequadoUse the appropriate taskType

A ferramenta de linha de comando taskType determina a maneira como a tarefa de inicialização é executada.The taskType attribute determines the way the startup task is executed. Há três valores: simples, segundo plano e primeiro plano.There are three values: simple, background, and foreground. As tarefas em primeiro e segundo plano são iniciadas de forma assíncrona e as tarefas simples são executadas de forma síncrona, uma de cada vez.The background and foreground tasks are started asynchronously, and then the simple tasks are executed synchronously one at a time.

Com as tarefas de inicialização simples, você pode definir a ordem na qual as tarefas são executadas pela ordem na qual as tarefas são listadas no arquivo ServiceDefinition.csdef.With simple startup tasks, you can set the order in which the tasks run by the order in which the tasks are listed in the ServiceDefinition.csdef file. Se uma tarefa simples terminar com um código de saída diferente de zero, o procedimento de inicialização será interrompido e a função não será iniciada.If a simple task ends with a non-zero exit code, then the startup procedure stops and the role does not start.

A diferença entre as tarefas de inicialização em segundo plano e em primeiro plano é que as tarefas de inicialização em primeiro plano mantêm a função em execução até a tarefa em primeiro plano ser encerrada.The difference between background startup tasks and foreground startup tasks is that foreground tasks keep the role running until the foreground task ends. Isso também significa que, se a tarefa em primeiro plano congelar ou falhar, a função não será reciclada até a tarefa em primeiro plano ser forçada a fechar.This also means that if the foreground task hangs or crashes, the role will not recycle until the foreground task is forced closed. Por esse motivo, as tarefas em segundo plano são recomendadas para tarefas de inicialização assíncronas, a menos que você precise desse recurso da tarefa em primeiro plano.For this reason, background tasks are recommended for asynchronous startup tasks unless you need that feature of the foreground task.

Encerrar arquivos em lotes com EXIT /B 0End batch files with EXIT /B 0

A função só será iniciada se o errorlevel de cada uma de suas tarefas de inicialização simples for zero.The role will only start if the errorlevel from each of your simple startup task is zero. Nem todos os programas definem o errorlevel (código de saída) corretamente e, portanto, o arquivo em lotes deverá terminar com um EXIT /B 0 se tudo tiver sido executado corretamente.Not all programs set the errorlevel (exit code) correctly, so the batch file should end with an EXIT /B 0 if everything ran correctly.

Um EXIT /B 0 ausente no final de um arquivo em lotes de inicialização é uma causa comum de funções que não são iniciadas.A missing EXIT /B 0 at the end of a startup batch file is a common cause of roles that do not start.

Observação

Observei que arquivos em lotes aninhados às vezes travarm ao usar o parâmetro /B.I've noticed that nested batch files sometimes hang when using the /B parameter. Convém verificar se esse problema de suspensão não acontece se outro arquivo em lotes chama o arquivo em lotes atual, como quando você usa o wrapper de log.You may want to make sure that this hang problem does not happen if another batch file calls your current batch file, like if you use the log wrapper. Você pode omitir o parâmetro /B nesse caso.You can omit the /B parameter in this case.

Esperar que tarefas de inicialização sejam executadas mais de uma vezExpect startup tasks to run more than once

Nem todas as reciclagens de função incluem uma reinicialização, mas todas as reciclagens incluem a execução de todas as tarefas de inicialização.Not all role recycles include a reboot, but all role recycles include running all startup tasks. Isso significa que deve ser possível executar as tarefas de inicialização várias vezes entre as reinicializações sem problemas.This means that startup tasks must be able to run multiple times between reboots without any problems. Isso é discutido na seção anterior.This is discussed in the preceding section.

Usar o armazenamento local para armazenar arquivos que devem ser acessados na funçãoUse local storage to store files that must be accessed in the role

Se você quiser copiar ou criar um arquivo enquanto sua tarefa de inicialização estiver acessível para sua função, esse arquivo deverá ser colocado no armazenamento local.If you want to copy or create a file during your startup task that is then accessible to your role, then that file must be placed in local storage. Confira a seção anterior.See the preceding section.

Próximas etapasNext steps

Examine o modelo de serviço e o pacote da nuvemReview the cloud service model and package

Saiba mais sobre o funcionamento de Tarefas .Learn more about how Tasks work.

Crie e implante seu pacote de serviço de nuvem.Create and deploy your cloud service package.