Typowe zadania uruchamiania usługi Cloud Service (klasyczne)

Ważne

Cloud Services (wersja klasyczna) jest teraz przestarzała dla nowych klientów i zostanie wycofana 31 sierpnia 2024 r. dla wszystkich klientów. Nowe wdrożenia powinny korzystać z nowego modelu wdrażania opartego na usłudze Azure Resource Manager Azure Cloud Services (rozszerzona obsługa)."

Ten artykuł zawiera kilka przykładów typowych zadań uruchamiania, które warto wykonać w usłudze w chmurze. Zadania uruchamiania umożliwiają wykonywanie operacji przed rozpoczęciem roli. Operacje, które można wykonać, obejmują instalowanie składnika, rejestrowanie składników COM, ustawianie kluczy rejestru lub uruchamianie długotrwałego procesu.

Zapoznaj się z tym artykułem , aby dowiedzieć się, jak działają zadania uruchamiania, a w szczególności jak utworzyć wpisy definiujące zadanie uruchamiania.

Uwaga

Zadania uruchamiania nie mają zastosowania do Virtual Machines tylko do ról sieci Web i procesu roboczego usługi w chmurze.

Definiowanie zmiennych środowiskowych przed rozpoczęciem roli

Jeśli potrzebujesz zmiennych środowiskowych zdefiniowanych dla określonego zadania, użyj elementu Środowisko wewnątrz elementu 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>

Zmienne mogą również używać prawidłowej wartości usługi Azure XPath , aby odwoływać się do czegoś o wdrożeniu. Zamiast używać atrybutu, zdefiniuj value element podrzędny RoleInstanceValue .

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

Konfigurowanie uruchamiania usług IIS przy użyciu AppCmd.exe

Narzędzie wiersza polecenia AppCmd.exe może służyć do zarządzania ustawieniami usług IIS podczas uruchamiania na platformie Azure. AppCmd.exe zapewnia wygodny dostęp wiersza polecenia do ustawień konfiguracji do użycia w zadaniach uruchamiania na platformie Azure. Za pomocą AppCmd.exemożna dodawać, modyfikować lub usuwać ustawienia witryny sieci Web dla aplikacji i witryn.

Istnieje jednak kilka rzeczy, które należy wziąć pod uwagę podczas korzystania z AppCmd.exe jako zadania uruchamiania:

  • Zadania uruchamiania można uruchamiać więcej niż raz między ponownym uruchomieniem. Na przykład w przypadku recyklingu roli.
  • Jeśli akcjaAppCmd.exe jest wykonywana więcej niż raz, może wygenerować błąd. Na przykład próba dodania sekcji do Web.config dwukrotnie może spowodować wystąpienie błędu.
  • Zadania uruchamiania kończą się niepowodzeniem, jeśli zwracają kod zakończenia niezerowy lub błąd. Na przykład gdy AppCmd.exe generuje błąd.

Dobrym rozwiązaniem jest sprawdzenie poziomu błędu po wywołaniu AppCmd.exe, co jest łatwe w przypadku zawijania wywołania w celu AppCmd.exe z plikiem cmd . Jeśli wykryjesz znaną odpowiedź na poziom błędów , możesz ją zignorować lub przekazać ją z powrotem.

Poziom błędu zwrócony przez AppCmd.exe znajduje się w pliku winerror.h, który można również zobaczyć w witrynie MSDN.

Przykład zarządzania poziomem błędu

W tym przykładzie dodano sekcję kompresji i wpis kompresji dla formatu JSON do pliku Web.config z obsługą błędów i rejestrowaniem.

W tym miejscu przedstawiono odpowiednie sekcje pliku ServiceDefinition.csdef , w tym ustawienie atrybutu executionContext w celu elevated udzielenia AppCmd.exe wystarczających uprawnień do zmiany ustawień w pliku 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>

Plik wsadowy Startup.cmd używa AppCmd.exe do dodawania sekcji kompresji i wpisu kompresji dla pliku JSON do pliku Web.config . Oczekiwany poziom błędu 183 jest ustawiony na zero przy użyciu programu wiersza polecenia VERIFY.EXE. Nieoczekiwane błędy są rejestrowane w 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%

Dodawanie reguł zapory

Na platformie Azure istnieją skutecznie dwie zapory. Pierwsza zapora kontroluje połączenia między maszyną wirtualną a światem zewnętrznym. Ta zapora jest kontrolowana przez element EndPoints w pliku ServiceDefinition.csdef .

Druga zapora kontroluje połączenia między maszyną wirtualną a procesami w ramach tej maszyny wirtualnej. Ta zapora może być kontrolowana netsh advfirewall firewall przez narzędzie wiersza polecenia.

Platforma Azure tworzy reguły zapory dla procesów uruchomionych w ramach Twoich ról. Na przykład po uruchomieniu usługi lub programu platforma Azure automatycznie tworzy niezbędne reguły zapory, aby umożliwić tej usłudze komunikację z Internetem. Jeśli jednak utworzysz usługę uruchomioną przez proces poza rolą (np. usługę COM+ lub zaplanowane zadanie systemu Windows), musisz ręcznie utworzyć regułę zapory, aby zezwolić na dostęp do tej usługi. Te reguły zapory można utworzyć przy użyciu zadania uruchamiania.

Zadanie uruchamiania, które tworzy regułę zapory, musi mieć wartość executionContextz podwyższonym poziomem uprawnień. Dodaj następujące zadanie uruchamiania do pliku 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>

Aby dodać regułę zapory, należy użyć odpowiednich netsh advfirewall firewall poleceń w pliku wsadowym uruchamiania. W tym przykładzie zadanie uruchamiania wymaga zabezpieczeń i szyfrowania dla portu 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%

Blokowanie określonego adresu IP

Dostęp do roli internetowej platformy Azure można ograniczyć do zestawu określonych adresów IP, modyfikując plik web.config usług IIS. Należy również użyć pliku polecenia, który odblokuje sekcję ipSecurity w pliku ApplicationHost.config .

Aby odblokować sekcję ipSecurity pliku ApplicationHost.config , utwórz plik polecenia, który jest uruchamiany na początku roli. Utwórz folder na poziomie głównym roli internetowej o nazwie startup i w tym folderze utwórz plik wsadowy o nazwie startup.cmd. Dodaj ten plik do projektu programu Visual Studio i ustaw właściwości na Kopiuj zawsze , aby upewnić się, że jest on uwzględniony w pakiecie.

Dodaj następujące zadanie uruchamiania do pliku 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>

Dodaj to polecenie do pliku 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

To zadanie powoduje uruchomienie pliku wsadowego startup.cmd za każdym razem, gdy rola sieci Web zostanie zainicjowana, upewniając się, że wymagana sekcja ipSecurity została odblokowana.

Na koniec zmodyfikuj sekcję system.webServer pliku web.config roli sieci Web, aby dodać listę adresów IP, które mają udzielony dostęp, jak pokazano w poniższym przykładzie:

Ta przykładowa konfiguracja umożliwia wszystkim adresom IP dostęp do serwera z wyjątkiem dwóch zdefiniowanych

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

Ta przykładowa konfiguracja odrzuca wszystkie adresy IP z dostępu do serwera z wyjątkiem dwóch zdefiniowanych.

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

Tworzenie zadania uruchamiania programu PowerShell

skrypty Windows PowerShell nie mogą być wywoływane bezpośrednio z pliku ServiceDefinition.csdef, ale można je wywołać z pliku wsadowego uruchamiania.

Program PowerShell (domyślnie) nie uruchamia niepodpisanych skryptów. Jeśli skrypt nie zostanie podpisany, musisz skonfigurować program PowerShell do uruchamiania niepodpisanych skryptów. Aby uruchamiać niepodpisane skrypty, należy ustawić wartość ExecutionPolicy na Wartość Nieograniczone. Używane ustawienie ExecutionPolicy jest oparte na wersji 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%

Jeśli używasz systemu operacyjnego gościa z uruchomionym programem PowerShell 2.0 lub 1.0, możesz wymusić uruchomienie wersji 2, a jeśli jest niedostępna, użyj wersji 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%

Tworzenie plików w magazynie lokalnym na podstawie zadania uruchamiania

Za pomocą zasobu magazynu lokalnego można przechowywać pliki utworzone przez zadanie uruchamiania, do których uzyskuje dostęp później aplikacja.

Aby utworzyć zasób magazynu lokalnego, dodaj sekcję LocalResources do pliku ServiceDefinition.csdef , a następnie dodaj element podrzędny LocalStorage . Nadaj zasobowi magazynu lokalnego unikatową nazwę i odpowiedni rozmiar zadania uruchamiania.

Aby użyć lokalnego zasobu magazynu w zadaniu uruchamiania, należy utworzyć zmienną środowiskową, aby odwoływać się do lokalnej lokalizacji zasobu magazynu. Następnie zadanie uruchamiania i aplikacja mogą odczytywać i zapisywać pliki w zasobie magazynu lokalnego.

Poniżej przedstawiono odpowiednie sekcje pliku 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>

Na przykład ten plik wsadowy Startup.cmd używa zmiennej środowiskowej PathToStartupStorage do utworzenia pliku MyTest.txt w lokalnej lokalizacji magazynu.

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

Dostęp do lokalnego folderu magazynu można uzyskać z poziomu zestawu Azure SDK przy użyciu metody GetLocalResource .

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

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

Uruchamianie w emulatorze lub chmurze

Zadanie uruchamiania może wykonać różne kroki, gdy działa w chmurze w porównaniu do tego, kiedy znajduje się w emulatorze obliczeniowym. Na przykład możesz użyć nowej kopii danych SQL tylko podczas uruchamiania w emulatorze. Możesz też chcieć wykonać pewne optymalizacje wydajności chmury, które nie muszą być wykonywane podczas uruchamiania w emulatorze.

Tę możliwość wykonywania różnych akcji w emulatorze obliczeniowym i w chmurze można wykonać, tworząc zmienną środowiskową w pliku ServiceDefinition.csdef . Następnie przetestujesz zmienną środowiskową dla wartości w zadaniu uruchamiania.

Aby utworzyć zmienną środowiskową, dodaj element Zmienna/RoleInstanceValue i utwórz wartość XPath ./RoleEnvironment/Deployment/@emulated Wartość zmiennej środowiskowej %ComputeEmulatorRunning% jest true uruchamiana w emulatorze obliczeniowym i false podczas uruchamiania w chmurze.

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

Zadanie może teraz sprawdzić zmienną środowiskową %ComputeEmulatorRunning% w celu wykonania różnych akcji na podstawie tego, czy rola jest uruchomiona w chmurze, czy w emulatorze. Oto skrypt powłoki cmd, który sprawdza, czy ta zmienna środowiskowa jest sprawdzana.

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

Wykryj, że zadanie zostało już uruchomione

Rola może zostać ponownie uruchomiona bez ponownego uruchomienia, co powoduje ponowne uruchomienie zadań uruchamiania. Nie ma flagi wskazującej, że zadanie zostało już uruchomione na maszynie wirtualnej hostingu. Może istnieć kilka zadań, w których nie ma znaczenia, że są one uruchamiane wiele razy. Jednak może wystąpić sytuacja, w której trzeba zapobiec uruchamianiu zadania więcej niż raz.

Najprostszym sposobem wykrycia, że zadanie zostało już uruchomione, jest utworzenie pliku w folderze %TEMP% po pomyślnym wykonaniu zadania i wyszukaniu go na początku zadania. Oto przykładowy skrypt powłoki cmd, który wykonuje to dla Ciebie.

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

Najlepsze rozwiązania dotyczące zadań

Poniżej przedstawiono kilka najlepszych rozwiązań, które należy wykonać podczas konfigurowania zadania dla roli sieci Web lub procesu roboczego.

Zawsze rejestruj działania uruchamiania

Program Visual Studio nie udostępnia debugera do przechodzenia przez pliki wsadowe, więc dobrze jest uzyskać jak najwięcej danych dotyczących operacji plików wsadowych. Rejestrowanie danych wyjściowych plików wsadowych, zarówno stdout , jak i stderr, może dostarczyć ważnych informacji podczas próby debugowania i naprawiania plików wsadowych. Aby zarejestrować plik stdout i stderr do pliku StartupLog.txt w katalogu wskazywany przez zmienną środowiskową %TEMP% , dodaj tekst >> "%TEMP%\\StartupLog.txt" 2>&1 na końcu określonych wierszy, które chcesz zarejestrować. Aby na przykład wykonać setup.exe w katalogu %PathToApp1Install% : "%PathToApp1Install%\setup.exe" >> "%TEMP%\StartupLog.txt" 2>&1

Aby uprościć kod XML, można utworzyć plik cmd otoki, który wywołuje wszystkie zadania uruchamiania wraz z rejestrowaniem i zapewnia, że każde zadanie podrzędne współudzieli te same zmienne środowiskowe.

Może to być irytujące, choć do użycia >> "%TEMP%\StartupLog.txt" 2>&1 na końcu każdego zadania uruchamiania. Rejestrowanie zadań można wymusić, tworząc otokę, która obsługuje rejestrowanie. Ta otoka wywołuje rzeczywisty plik wsadowy, który chcesz uruchomić. Wszystkie dane wyjściowe z docelowego pliku wsadowego zostaną przekierowane do pliku Startuplog.txt .

W poniższym przykładzie pokazano, jak przekierować wszystkie dane wyjściowe z pliku wsadowego uruchamiania. W tym przykładzie plik ServerDefinition.csdef tworzy zadanie uruchamiania, które wywołuje plik logwrap.cmd. logwrap.cmd wywołuje plik Startup2.cmd, przekierowując wszystkie dane wyjściowe do folderu %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%

Przykładowe dane wyjściowe w pliku 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 ================================================ 

Porada

Plik StartupLog.txt znajduje się w folderze C:\Resources\temp\{role identifier}\RoleTemp .

Ustaw właściwość executionContext odpowiednio dla zadań uruchamiania

Ustaw odpowiednie uprawnienia dla zadania uruchamiania. Czasami zadania uruchamiania muszą być uruchamiane z podwyższonym poziomem uprawnień, mimo że rola jest uruchamiana z normalnymi uprawnieniami.

Atrybut executionContext ustawia poziom uprawnień zadania uruchamiania. Użycie executionContext="limited" oznacza, że zadanie uruchamiania ma ten sam poziom uprawnień co rola. Użycie executionContext="elevated" oznacza, że zadanie uruchamiania ma uprawnienia administratora, co umożliwia zadanie uruchamiania wykonywanie zadań administratora bez nadawania uprawnień administratora roli.

Przykładem zadania uruchamiania wymagającego podwyższonego poziomu uprawnień jest zadanie uruchamiania, które używa AppCmd.exe do konfigurowania usług IIS. AppCmd.exe wymaga .executionContext="elevated"

Użyj odpowiedniego typu zadania

Atrybut taskType określa sposób wykonywania zadania uruchamiania. Istnieją trzy wartości: proste, tło i pierwszy plan. Zadania w tle i na pierwszym planie są uruchamiane asynchronicznie, a następnie proste zadania są wykonywane synchronicznie pojedynczo.

Za pomocą prostych zadań uruchamiania można ustawić kolejność, w jakiej zadania są uruchamiane w kolejności, w której zadania są wymienione w pliku ServiceDefinition.csdef. Jeśli proste zadanie kończy się kodem zakończenia niezerowym, procedura uruchamiania zostanie zatrzymana, a rola nie zostanie uruchomiona.

Różnica między zadaniami uruchamiania w tlei zadaniami uruchamiania pierwszego planu polega na tym, że zadania pierwszego planu zachowują rolę uruchomioną do momentu zakończenia zadania pierwszego planu . Oznacza to również, że jeśli zadanie pierwszego planu zawiesza się lub ulega awarii, rola nie będzie przetwarzać do momentu zamknięcia zadania pierwszego planu . Z tego powodu zadania w tle są zalecane w przypadku zadań uruchamiania asynchronicznego, chyba że potrzebujesz tej funkcji zadania pierwszego planu .

Kończ pliki wsadowe z wyjściem /B 0

Rola zostanie uruchomiona tylko wtedy, gdy poziom błędu z każdego prostego zadania uruchamiania wynosi zero. Nie wszystkie programy prawidłowo ustawiają wartość errorlevel (kod zakończenia), więc plik wsadowy powinien kończyć się wartością EXIT /B 0 , jeśli wszystko działa poprawnie.

Brak EXIT /B 0 pliku wsadowego uruchamiania na końcu jest typową przyczyną ról, które nie są uruchamiane.

Uwaga

Zauważyłem, że zagnieżdżone pliki wsadowe czasami przestają odpowiadać podczas korzystania z parametru /B . Możesz upewnić się, że ten problem nie występuje, jeśli inny plik wsadowy wywołuje bieżący plik wsadowy, na przykład jeśli używasz otoki dzienników. W tym przypadku można pominąć /B parametr.

Oczekiwano, że zadania uruchamiania będą uruchamiane więcej niż raz

Nie wszystkie kosze ról obejmują ponowny rozruch, ale wszystkie kosze ról obejmują uruchamianie wszystkich zadań uruchamiania. Oznacza to, że zadania uruchamiania muszą być uruchamiane wiele razy między ponownym uruchomieniem bez żadnych problemów. Omówiono to w poprzedniej sekcji.

Używanie magazynu lokalnego do przechowywania plików, do których należy uzyskać dostęp w roli

Jeśli chcesz skopiować lub utworzyć plik podczas zadania uruchamiania, który jest dostępny dla twojej roli, ten plik musi zostać umieszczony w magazynie lokalnym. Zobacz poprzednią sekcję.

Następne kroki

Przeglądanie modelu i pakietu usług w chmurze

Dowiedz się więcej o sposobie działania zadań .

Utwórz i wdróż pakiet usługi w chmurze.