> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Ausführen in Azure Cloud Service

> Stellen Sie ABBYY FineReader Engine 12 for Windows in Azure Cloud Service mit einem Worker-Rollenprojekt und einer Online-Lizenz bereit, die eine Verbindung zu den ABBYY-Lizenzservern herstellt.

Dieser Abschnitt enthält Anweisungen zum Bereitstellen einer FRE 12 for Windows-Anwendung in Azure Cloud Service. Als Beispiel dient ein Worker, der Dateien in einem Container eines Azure Speicherkontos verarbeitet.

Zur Implementierung dieses Szenarios wird eine [Online-Lizenz](/de/fine-reader/engine/licensing/online-licensing) verwendet, die eine Verbindung zum Lizenzserver unter \*.abbyy.com herstellt.

<Note>
  ABBYY Licensing Service kann jeweils nur eine Online-Lizenz gleichzeitig verwenden.
</Note>

Das Bereitstellen Ihrer Anwendung in Cloud Service umfasst mehrere Schritte:

1. Einrichten Ihrer Online-Lizenz, Ihres lokalen Rechners und Ihrer Cloud-Instanz anhand der [Voraussetzungen](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#prerequisites)
2. Durchführen [der vorbereitenden Schritte](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#preparatorysteps) vor dem Bereitstellen Ihrer Anwendung
3. [Bereitstellen Ihrer Anwendung in Cloud Service](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#deployingabbyyfinereaderengineincloudservice)

Siehe die [Codebeispiele](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#scripts), die veranschaulichen, wie die Methoden von ABBYY FineReader Engine für die Dokumentverarbeitung verwendet werden.

<div id="prerequisites">
  ## Voraussetzungen
</div>

<div id="online-license">
  ### Online-Lizenz
</div>

Um eine Online-Lizenz zu verwenden, sollten Sie die folgenden Informationen vom Vertrieb erhalten:

* Ihre [Customer Project ID](/de/fine-reader/engine/api-reference/functions/initializeengine-function#customerprojectid)
* eine Token-Datei für die Online-Lizenz
* das Kennwort für die Token-Datei der Online-Lizenz

Für die Verwendung einer Online-Lizenz müssen an allen Orten, an denen der ABBYY Licensing Service installiert ist, die folgenden Bedingungen erfüllt sein:

* Aktive Internetverbindung
* Erlaubte Verbindungen zu \*.abbyy.com über Port 443 (HTTPS)
* GoDaddy-Root-Zertifikat für die Zertifizierungsstelle (Es muss im Zertifikatsspeicher „Vertrauenswürdige Stammzertifizierungsstellen“ des lokalen Computers installiert sein. Ausführliche Informationen zum Zertifikat finden Sie auf der GoDaddy-[Website](http://www.godaddy.com/).)

<div id="local-machine">
  ### Lokaler Rechner
</div>

Bevor Sie Ihren Cloud Service erstellen, verwenden Sie die folgende Spezifikation, um Ihren lokalen Rechner vorzubereiten:

* Visual Studio 2019 und die zugehörigen Module für die Entwicklung von Anwendungen für Azure (siehe [Azure-Features in Visual Studio](http://visualstudio.microsoft.com/vs/features/azure/) oder verwenden Sie das Visual Studio-Installationsprogramm, um diese Module herunterzuladen)
* Cloud Service-Emulatoren und Speicher für einfaches Debugging (weitere Informationen [hier](https://docs.microsoft.com/en-us/visualstudio/azure/vs-azure-tools-debug-cloud-services-virtual-machines?view=vs-2019); Download über das Visual Studio-Installationsprogramm)
* Vorlagenlösung für Azure Cloud Service (Extended Preview) mit einem einzelnen Worker-Rollenprojekt (weitere Informationen [hier](https://docs.microsoft.com/en-us/visualstudio/azure/vs-azure-tools-debug-cloud-services-virtual-machines?view=vs-2019))
* .NET Framework 4.7.2
* Azure SDK (Download [hier](https://azure.microsoft.com/en-us/downloads/))
* NuGet-Paket für die Arbeit mit Azure Storage und Blob-Containern – Azure.Storage.Blobs (Download [hier](https://www.nuget.org/packages/Azure.Storage.Blobs/))
* ABBYY FineReader Engine-Wrapper für .NET Framework 4.7 (im Ordner C:\ProgramData\ABBYY\SDK\12\FineReader Engine\Inc.NET interops nach der Developer-Installation)
* Für die Arbeit mit Blob-Containern überschriebene [IFileWriter](/de/fine-reader/engine/api-reference/supplementary-objects-and-methods/ifilewriter)-Schnittstelle (siehe das [Beispiel](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#ifilewriter) unten)
* Azure Storage Explorer (optional – Download [hier](http://azure.microsoft.com/en-us/features/storage-explorer/))

<div id="cloud-service-instance">
  ### Cloud Service-Instanz
</div>

Die Cloud Service-Instanz dient zum Speichern Ihres WorkerRole-Projekts in Azure. Verwenden Sie die folgende Spezifikation, um diese Instanz einzurichten:

* .NET Framework-Version für Ihren Service
* PowerShell zum Bereitstellen von ABBYY FineReader Engine
* NuGet 2.8.5.201 oder höher zum Hochladen des Azure SDK
* Azure SDK für die Arbeit mit einem Azure Speicherkonto mithilfe von PowerShell

<div id="preparatory-steps">
  ## Vorbereitungsschritte
</div>

Die Vorbereitungsschritte sind auf Ihrem lokalen Rechner durchzuführen. Wenn Sie diese Schritte abschließen, bereiten Sie alle erforderlichen Einstellungen und Dateien vor, um mit der Bereitstellung Ihrer Anwendung zu beginnen:

1. Erstellen Sie zwei Archive mit der ABBYY FineReader Engine-Bibliothek und dem Licensing Service (zum Beispiel LibraryPackage.zip und LSPackage.zip). Sie können die Dateiliste mithilfe der Datei FREngineDistribution.csv automatisch erstellen. Verwenden Sie ABBYY FineReader Engine und License Server aus demselben Paket; andernfalls ist die Kompatibilität nicht gewährleistet.
2. Erstellen Sie das Azure Speicherkonto (in diesem Artikel frestorage). Alle erforderlichen Anleitungen finden Sie auf der [Azure](http://docs.microsoft.com/en-us/azure/?product=featured)-Website.
3. Erstellen Sie drei Blob-Container in frestorage:

* fre-lib - für die Dateien von ABBYY FineReader Engine
* fre-input - für eingehende Dateien
* fre-output - für die Verarbeitungsergebnisse

4. Laden Sie LibraryPackage.zip und LSPackage.zip auf die für Sie bequemste Weise in den Container fre-lib hoch (mit .NET, PowerShell, einem Python-Skript oder den Anwendungen Azure Storage Explorer/Azure Portal).

Als Beispiel wird ein WorkerRole-Projekt für die Ausführung in einer konfigurierten Umgebung verwendet. Alle erforderlichen Konfigurationsdateien (.csdef und Cloud.cscfg) werden nach dem Erstellen Ihres Projekts automatisch generiert.

<div id="deploying-abbyy-finereader-engine-to-cloud-service">
  ## Bereitstellen von ABBYY FineReader Engine in Cloud Service
</div>

So stellen Sie ABBYY FineReader Engine in Ihrem neuen WorkerRole-Projekt bereit:

1. Geben Sie die Parameter in Cloud.cscfg wie gewünscht an.
2. Geben Sie die Parameter der Datei .csdef an:

* (optional) Ihre WorkerRole-Einstellungen
* (optional) die Größe Ihrer virtuellen Maschine
* (erforderlich) den lokalen Speicher Ihrer Rolle (Abschnitt LocalStorage – in diesem Artikel der Speicher mit dem Namen LocalStorage1). Legen Sie ihn auf mindestens 3 GB fest, damit das ABBYY FineReader Engine-Paket ordnungsgemäß bereitgestellt werden kann.
* (erforderlich) die Startreihenfolge Ihrer Rolle (verwenden Sie die Codebeispiele und Einstellungen aus dem Abschnitt [Codebeispiel](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#scripts))

3. Implementieren Sie Ihr WorkerRole-Projekt so, dass es Dateien aus dem Container fre-input verarbeitet und die Verarbeitungsergebnisse im Container fre-output ablegt:

* die Methode OnStart, um Ihren Cloud Service für den Betrieb vorzubereiten. Diese Methode wird verwendet, um die Engine zu initialisieren und das TLS-Protokoll einzurichten.
* die Methode RunAsync zur zyklischen Verarbeitung der Dateien aus dem Container fre-input. Diese Methode erkennt die Dateien im Container fre-input, verarbeitet sie im Speicher und legt sie im Container fre-output ab (siehe [Processor.cs](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#processor.cs), [IFileWriter.cs](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#ifilewriter) und [Config.cs](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#config)).
* die Methode OnStop, um den Betrieb des Cloud Service zu beenden. Diese Methode wird verwendet, um die Engine zu deinitialisieren.

<div id="code-samples">
  ## Codebeispiele
</div>

Dieser Abschnitt enthält Codebeispiele zum Konfigurieren der Startreihenfolge von Rollen und der Einstellungen von ABBYY FineReader Engine:

* CleanUpOnStart - löscht die vorherige Version von ABBYY FineReader Engine und vereinfacht deren Aktualisierung (siehe die Auflistung unten in den Dateien [CleanUpOnStart.cmd](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#cleanuponstart.cmd) und [CleanUpOnStart.ps1](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#cleanuponstart.ps1)).
* PreparePoShModules - lädt das SDK herunter, das benötigt wird, damit PowerShell mit Azure Storage arbeiten kann (siehe die Auflistung unten in den Dateien [PreparePoShModules.cmd](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#prepareposhmodules.cmd) und [PreparePoShModules.ps1](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#preparemodules.ps1)).
* PrepareLibrary - lädt die ABBYY FineReader Engine-Bibliothek aus dem Container fre-lib in den lokalen Speicher und entpackt sie dort (siehe die Auflistung unten in den Dateien [PrepareLibrary.cmd](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#preparelibrary.cmd) und [PrepareLibrary.ps1](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#preparelibrary.ps1)).
* PrepareLS - lädt den Licensing Service aus dem Container fre-lib, entpackt ihn und startet ihn (siehe die Auflistung unten in den Dateien [PrepareLS.cmd](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#preparels.cmd) und [PrepareLS.ps1](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#preparels.ps1)).

Die oben aufgeführten Skripte müssen vor dem Starten Ihrer Anwendung genau in der angegebenen Reihenfolge ausgeführt werden. Um die Ausführungsreihenfolge der Skripte festzulegen, geben Sie die folgenden Attribute an:

* taskType="simple" - Aufgaben werden synchron nacheinander ausgeführt.
* executionContext="elevated" - Ausführen eines Startskripts mit Administratorrechten (erforderlich, um Anwendungen installieren und LicensingService.exe ausführen zu können)

Dadurch wird ein Ordner erstellt, den Cloud Service verwalten kann. Dieser Ordner wird verwendet, um ABBYY FineReader Engine mithilfe der oben aufgeführten Skripte hochzuladen und die FREngine.dll zur weiteren Verwendung im [Beispiel](/de/fine-reader/engine/distribution/distribution-windows/running-abbyy-finereader-engine-inside-azure-services/running-in-azure-cloud-service#processingsample) zu laden.

<Accordion title="CleanUpOnStart.cmd">
  ```
  rem   Skript zum Bereinigen vorheriger Pakete von ABBYY FineReader Engine und Licensing Service
  echo Cleaning up before launching service >> ".\CleanUpOnStart.log" 2>&1
  PowerShell -ExecutionPolicy Unrestricted .\StartupScripts\CleanUpOnStart.ps1 >> ".\CleanUpOnStart.log" 2>&1
  echo Cleaning up beafore launching service. >> ".\CleanUpOnStart.log" 2>&1
   
  exit /B %errorlevel%
  ```
</Accordion>

<Accordion title="CleanUpOnStart.ps1">
  ```
  Write-Host "CleanUpOnStart.ps1 started...";
  # Pfad zum lokalen Speicher (siehe ServiceDefinition.csdef)
  $local_storage_name = "LocalStorage1";
  [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.WindowsAzure.ServiceRuntime");
  $local_storage_path = ([Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::GetLocalResource($local_storage_name)).RootPath.TrimEnd('\\');
  # Licensing Service-Prozess beenden, falls er ausgeführt wird
  $processes = Get-Process;
  foreach( $process in $processes ) {
      if( $process.Name -eq "LicesingService" ) {
          Stop-Process $process;
      }
  }
   
  # den Ordner fre_packages bereinigen und neu erstellen
  $destination_path = Join-Path -Path $local_storage_path -ChildPath 'fre_packages';
  if( Test-Path -Path $destination_path ) {
      Remove-Item $destination_path -Recurse -Force;
  }
  New-Item -ItemType Directory -Path $destination_path;
  # den Eingabeordner bereinigen und neu erstellen
  $destination_path = Join-Path -Path $local_storage_path -ChildPath 'Input';
  if( Test-Path -Path $destination_path ) {
      Remove-Item $destination_path -Recurse -Force;
  }
  New-Item -ItemType Directory -Path $destination_path;
  # den Ordner Results bereinigen und neu erstellen
  $destination_path = Join-Path -Path $local_storage_path -ChildPath 'Results';
  if( Test-Path -Path $destination_path ) {
      Remove-Item $destination_path -Recurse -Force;
  }
  New-Item -ItemType Directory -Path $destination_path;
  Write-Host ("Resource folder was cleaned up.");
  ```
</Accordion>

<Accordion title="PreparePoShModules.cmd">
  ```
  rem   Skript zum Vorbereiten von Modulen, um eine Verbindung mit dem Speicherkonto herzustellen und ABBYY FineReader Engine- und Licensing Service-Pakete herunterzuladen
   
  echo Preparing PoSh Modules >> ".\PreparePoShModules.log" 2>&1
  PowerShell -ExecutionPolicy Unrestricted .\StartupScripts\PreparePoShModules.ps1 >> ".\PreparePoShModules.log" 2>&1
  echo PoSh Modules wer prepared. >> ".\PreparePoShModules.log" 2>&1
   
  exit /B %errorlevel%
  ```
</Accordion>

<Accordion title="PreparePoShModules.ps1">
  ```bash theme={null}
  # Module installieren
  Write-Host "PreparePoShModules.ps1 started...";
  # NuGet-Paketanbieter zum Herunterladen von Azure-Modulen installieren
  Write-Host "Installing NuGet package provider...";
  Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force;
   
  # Az.Storage-Modul für die Arbeit mit Blob Storage installieren
  Write-Host "Installing Az.Storage module...";
  Install-Module -Name Az.Storage -Scope CurrentUser -Repository PSGallery -Force -AllowClobber;
  Write-Host ("PoSh modules were prepared.");
  ```
</Accordion>

<Accordion title="PrepareLibrary.cmd">
  ```
  rem   Skript zum Vorbereiten des ABBYY FineReader Engine-Pakets
  echo Preparing Library >> ".\PrepareLibrary.log" 2>&1
  PowerShell -ExecutionPolicy Unrestricted .\StartupScripts\PrepareLibrary.ps1 >> ".\PrepareLibrary.log" 2>&1
  echo Library was prepared. >> ".\PrepareLibrary.log" 2>&1
  exit /B %errorlevel%
  ```
</Accordion>

<Accordion title="PrepareLibrary.ps1">
  ```
  Write-Host "PrepareLibrary.ps1 gestartet...";
  # Container mit Paketen für ABBYY FineReader Engine und Licensing Service
  $container_name = 'fre-lib';
  # Verbindungszeichenfolge für das Speicherkonto 
  $connection_string = "<connection_string_to_frestorage>";
  Write-Host "Konfiguration";
  Write-Host ("Containername: " + $container_name);
  Write-Host ("Verbindungszeichenfolge: " + $storage_account);
  # Verbindung mit dem Speicherkonto herstellen
  Write-Host ("Verbindung mit dem Speicherkonto wird hergestellt...");
  $storage_account = New-AzStorageContext -ConnectionString $connection_string;
  # Blobs abrufen (im Wesentlichen Dateien)
  Write-Host ("Blobs aus dem Container werden abgerufen...");
  $fre_blobs = Get-AzStorageBlob -Container $container_name -Context $storage_account;
  # Pfad zum lokalen Speicher (siehe ServiceDefinition.csdef)
  $local_storage_name = "LocalStorage1";
  [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.WindowsAzure.ServiceRuntime");
  $local_storage_path = ([Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::GetLocalResource($local_storage_name)).RootPath.TrimEnd('\\');
  $destination_path = Join-Path -Path $local_storage_path -ChildPath 'fre_packages';
  # nur den benötigten Blob herunterladen
  Write-Host ("FRE-Paket aus dem Container wird heruntergeladen...");
  foreach( $blob in $fre_blobs ) {
      Write-Host $blob.Name;
      if( $blob.Name -eq "LibraryPackage.zip" ) {
          Write-Host ("Blob wird heruntergeladen: " + $blob.Name + " nach " + $destination_path);
          Get-AzStorageBlobContent -Container $container_name -Blob $blob.Name `
              -Destination (Join-Path -Path $destination_path -ChildPath $blob.Name) -Context $storage_account;
      } else {
          Write-Host ("Blob " + $blob.Name + " wird nicht heruntergeladen.");
      }
  }
  # heruntergeladenes Paket entpacken (die vorhandene Bibliothek wird dabei zwangsweise überschrieben)
  Write-Host ("Bibliothekspaket wird entpackt...");
  Expand-Archive -Path (Join-Path -Path $destination_path -ChildPath "LibraryPackage.zip") `
      -DestinationPath (Join-Path -Path $destination_path -ChildPath "LibraryPackage") -Force;
  Write-Host ("Bibliothekspaket wurde vorbereitet.");
  ```
</Accordion>

<Accordion title="PrepareLS.cmd">
  ```
  rem   Skript zum Vorbereiten des Licensing Service-Pakets und zum Starten von LicensingService.exe
  echo LS wird vorbereitet >> ".\PrepareLS.log" 2>&1
  PowerShell -ExecutionPolicy Unrestricted .\StartupScripts\PrepareLS.ps1 >> ".\PrepareLS.log" 2>&1
  echo LS wurde vorbereitet. >> ".\PrepareLS.log" 2>&1
  exit /B %errorlevel%
  ```
</Accordion>

<Accordion title="PrepareLS.ps1">
  ```
  Write-Host "PrepareLS.ps1 wurde gestartet...";
  # Container mit Paketen für ABBYY FineReader Engine und Licensing Service
  $container_name = 'fre-lib';
  # Verbindungszeichenfolge für das Speicherkonto
  $connection_string = "<connection_string_to_frestorage>";
  Write-Host "Konfiguration";
  Write-Host ("Containername: " + $container_name);
  Write-Host ("Verbindungszeichenfolge: " + $storage_account);
  # Verbindung mit dem Speicherobjekt herstellen
  Write-Host ("Verbindung mit dem Speicherkonto wird hergestellt...");
  $storage_account = New-AzStorageContext -ConnectionString $connection_string;
  # Blobs abrufen (im Grunde Dateien)
  Write-Host ("Blobs aus dem Container werden abgerufen...");
  $fre_blobs = Get-AzStorageBlob -Container $container_name -Context $storage_account;
  # Pfad zum lokalen Speicher (siehe ServiceDefinition.csdef)
  $local_storage_name = "LocalStorage1";
  [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.WindowsAzure.ServiceRuntime");
  $local_storage_path = ([Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::GetLocalResource($local_storage_name)).RootPath.TrimEnd('\\');
  $destination_path = Join-Path -Path $local_storage_path -ChildPath 'fre_packages'; 
  # Licensing Service-Paket herunterladen
  Write-Host ("Licensing Service-Paket wird aus dem Container heruntergeladen...");
  foreach( $blob in $fre_blobs ) {
      Write-Host $blob.Name;
      if( $blob.Name -eq "LSPackage.zip" ) {
          Write-Host ("Blob wird heruntergeladen: " + $blob.Name + " nach " + $destination_path);
          Get-AzStorageBlobContent -Container $container_name -Blob $blob.Name `
              -Destination (Join-Path -Path $destination_path -ChildPath $blob.Name) -Context $storage_account;
      } else {
          Write-Host ("Herunterladen von Blob " + $blob.Name + " wurde übersprungen.");
      }
  }
  # Heruntergeladenes Paket entpacken
  Write-Host ("Bibliothekspaket wird entpackt...");
  Expand-Archive -Path (Join-Path -Path $destination_path -ChildPath "LSPackage.zip") `
      -DestinationPath (Join-Path -Path $destination_path -ChildPath "LSPackage") -Force;
  # Ordner für Lizenzen erstellen
  $program_data_path = [System.Environment]::ExpandEnvironmentVariables("%programdata%");
  $path = Join-Path -Path $program_data_path -ChildPath "ABBYY\SDK\12\Licenses";
  New-Item -ItemType Directory -Path $path -Force;
  # Licensing Service im Standalone-Modus starten
  Write-Host ("Licensing Service wird gestartet...");
   
  $licensing_service_app = Join-Path -Path $destination_path -ChildPath "LSPackage\LicensingService.exe";
  Start-Process -FilePath $licesing_service_app -ArgumentList "/standalone";
  Write-Host ("LS-Paket wurde vorbereitet und LS wurde gestartet.");
  ```
</Accordion>

<Accordion title="Implementierung der IFileWriter-Schnittstelle">
  ```csharp theme={null}
  namespace WorkerRole1.Engine
  {
      public class FileWriter : FREngine.IFileWriter, IDisposable
      {
          public FileWriter(string _resultBlobName, string _fileExtension)
          {
              resultBlobName = _resultBlobName;
              fileExtension = _fileExtension;
          }
          public void Open(string fileName, ref int bufferSize)
          {
              stream = new MemoryStream();
          }
          public void Write(byte[] data)
          {
              stream.Write(data, 0, data.Length);
          }
          public void Close() 
          {
              // Verbindung mit einem neuen Blob in <OutputContainerName> herstellen
              // Das Verarbeitungsergebnis wird dort gespeichert
              BlobClient resultBlobClient = new BlobClient(Config.ConnectionString, Config.OutputContainerName,
                  resultBlobName + fileExtension);
              // Vorhandene Datei überschreiben
              resultBlobClient.DeleteIfExists();
              // Position auf 0 setzen, damit die Datei von Anfang an geschrieben wird
              stream.Position = 0;
              resultBlobClient.Upload(stream);
   
              stream.Close();
          }
          public void Dispose()
          {
              // MemoryStream beim Freigeben schließen, damit nach dem Schreiben der Daten darauf zugegriffen werden kann
              stream.Close();
          }
          private string resultBlobName;
          private string fileExtension;
          private MemoryStream stream;
      }
  }
  ```
</Accordion>

<Accordion title="Beispiel für die Verarbeitung von Dateien mit ABBYY FineReader Engine">
  ```csharp theme={null}
  namespace WorkerRole1
  {
      public class WorkerRole : RoleEntryPoint
      {
          private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
          private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false);
          Processor processor = new Processor();
   
          public override void Run()
          {
              Trace.TraceInformation("WorkerRole1 is running");
   
              try
              {
                  this.RunAsync(this.cancellationTokenSource.Token).Wait();
              }
              finally
              {
                  this.runCompleteEvent.Set();
              }
          }
          public override bool OnStart()
          {
              // Legen Sie die maximale Anzahl gleichzeitiger Verbindungen fest
              ServicePointManager.DefaultConnectionLimit = 12;
   
              // Setzen Sie TLS auf 12, damit eine Verbindung mit dem Speicherkonto hergestellt werden kann
              System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
   
              // Informationen zum Umgang mit Konfigurationsänderungen
              // finden Sie im entsprechenden MSDN-Thema unter https://go.microsoft.com/fwlink/?LinkId=166357
   
              bool result = base.OnStart();
              Trace.TraceInformation("WorkerRole1 has been started");
   
              processor.LoadEngine();
              return result;
          }
   
          public override void OnStop()
          {
              processor.UnloadEngine();
              Trace.TraceInformation("WorkerRole1 is stopping");
              this.cancellationTokenSource.Cancel();
              this.runCompleteEvent.WaitOne();
              base.OnStop();
              Trace.TraceInformation("WorkerRole1 has stopped");
          }
   
          private async Task RunAsync(CancellationToken cancellationToken)
          {
              // TODO: Ersetzen Sie den folgenden Code durch Ihre eigene Logik
              while (!cancellationToken.IsCancellationRequested)
              {
                  Trace.TraceInformation("Working");
   
                  try
                  {
                      // Erstellen Sie den Container und geben Sie ein Container-Clientobjekt zurück
                      BlobContainerClient inputContainerClient = new BlobContainerClient(Config.ConnectionString, Config.InputContainerName);
                      foreach (BlobItem blobItem in inputContainerClient.GetBlobs())
                      {
                          Trace.TraceInformation("\t" + blobItem.Name);
                          BlobClient blobClient = new BlobClient(Config.ConnectionString, Config.InputContainerName, blobItem.Name);
   
                          Trace.TraceInformation("\t Downloading blob to memory: " + blobItem.Name);
                          MemoryStream memoryStream = new MemoryStream();
                          blobClient.DownloadTo(memoryStream);
                          Trace.TraceInformation("\t Processing in FRE: " + blobItem.Name);
                          string resultBlobName = processor.ProcessImage(memoryStream, blobItem.Name);
                          Trace.TraceInformation("\t Result blob name in output container: " + resultBlobName);
                          Trace.TraceInformation("\t Deleting from input container: " + blobItem.Name);
                          blobClient.Delete();
                      }
                  }
                  catch (Exception error)
                  {
                      Trace.TraceInformation("error: " + error.Message);
                  }
   
                  await Task.Delay(1000);
              }
          }
      }
  }
  ```
</Accordion>

<Accordion title="Processor.cs">
  ```csharp theme={null}
  namespace WorkerRole1
  {
      class Processor : IDisposable
      {
          EngineLoader engineLoader = null;
          private void displayMessage(string text)
          {
              File.AppendAllText(".\\FRE.log", text + "\n");
              Trace.TraceInformation("\t" + text );
          }        
          private void loadProfile()
          {
              engineLoader.Engine.LoadPredefinedProfile("DocumentConversion_Accuracy");
          }        
          private void setupFREngine()
          {
              displayMessage("Loading predefined profile...");
              loadProfile();
          }
          public void LoadEngine()
          {
              try {
                  if (engineLoader == null)
                  {
                      // Derselbe EngineLoader wie im Hello-Beispiel
                      engineLoader = new EngineLoader();
                  }
                  setupFREngine();
              }
              catch (Exception error)
              {
                  displayMessage("error: " + error.Message);
              }
          }
          public void UnloadEngine()
          {
              try
              {
                  if (engineLoader != null)
                  {
                      engineLoader.Dispose();
                      engineLoader = null;
                  }
              }
              catch (Exception error)
              {
                  displayMessage("error: " + error.Message);
              }
          }
   
          public string ProcessImage( MemoryStream inputMemoryStream, string inputBlobName )
          {
              FRDocument document = engineLoader.Engine.CreateFRDocument();
              string resultBlobName = "";
              try
              {
                 document.PageFlushingPolicy = FREngine.PageFlushingPolicyEnum.PFP_KeepInMemory;
   
                  // Bilddatei zum Dokument hinzufügen
                  displayMessage("Loading image...");
                  IntPtr handle = Marshal.AllocHGlobal(inputMemoryStream.GetBuffer().Length);
                  Marshal.Copy(inputMemoryStream.GetBuffer(), 0, handle, inputMemoryStream.GetBuffer().Length);
                  document.AddImageFileFromMemory(handle.ToInt64(), null, null);
   
                  // Dokument erkennen
                  displayMessage("Recognizing...");
                  document.Process(null);
   
                  // Ergebnisse speichern
                  displayMessage("Saving results...");
                  // Ergebnisse mit dem Szenario 'balanced' als PDF speichern
                  // FREngine.PDFExportParams pdfParams = engineLoader.Engine.CreatePDFExportParams();
                  // pdfParams.Scenario = FREngine.PDFExportScenarioEnum.PES_Balanced;
   
                  WorkerRole1.Engine.FileWriter fileWriter = new WorkerRole1.Engine.FileWriter(inputBlobName, ".pdf");
                  resultBlobName = inputBlobName + ".pdf";
                  document.ExportToMemory(fileWriter, FREngine.FileExportFormatEnum.FEF_PDF, null);
   
              }
              catch (Exception error)
              {
                  displayMessage("error: " + error.Message);
              }
              finally
              {
                  // Dokument schließen
                  document.Close();
              }
   
              return resultBlobName;
          }
   
          public void Dispose()
          {
              UnloadEngine();
          }
      }
  }
  ```
</Accordion>

<Accordion title="Config.cs">
  ```
  class Config
  {
      // Lokaler Speicher, wie in ServiceDefinition.csdef definiert
      private static string LocalStorageName = "LocalStorage1";
      // Verbindungszeichenfolge für den Blob-Container
      public static readonly string ConnectionString = "<connection_string_to_frestorage>";
      // Namen der Eingabe- und Ausgabe-Container in Ihrem Speicher
      public static readonly string InputContainerName = "fre-input";
      public static readonly string OutputContainerName = "fre-output";
   
      // Customer Project ID für ABBYY FineReader Engine zurückgeben
      public static String GetCustomerProjectId()
      {
          return "<Your_Customer_Project_ID>";
      }
   
      // Name des Lizenz-Tokens zurückgeben
      public static String GetLicenseTokenName()
      {
          return "<Token_number>.ABBYY.ActivationToken";
      }
   
      // Lizenz-Kennwort zurückgeben
      public static String GetLicensePassword()
      {
          return "<Your_Online_License_token_password>";
      }
      // Engine-Pfad zurückgeben
      public static String GetEngineFolder()
      {
          string engineSubfolder = "fre_packages\\LibraryPackage\\Bin64";
          string engineDllFolder = Path.Combine(RoleEnvironment.GetLocalResource(LocalStorageName).RootPath, engineSubfolder);
          return engineDllFolder;
      }
  }
  ```
</Accordion>
