Verwendung von List & Label mit Microsoft Azure

Hinweis: Ab List & Label in der Version 27 besteht die Möglichkeit, List & Label ohne Druckertreiber zu verwenden. Dies ist insbesondere in Cloud-Umgebungen wie Azure oder AWS wichtig, da hier oftmals keine Drucker installiert sind und aus Sicherheitsgründen auch nicht nachinstalliert werden können. Hosten Sie Ihre Anwendung ab Version 27 einfach in einem Windows-Docker-Container.

Einführung

Dieser Artikel stellt die wichtigsten Konzepte und Code Snippets für die Verwendung von List & Label mit Microsoft Azure vor. Das Beispiel demonstriert die Kommunikation zweier Rollen zur Berichtserstellung als PDF oder JPEG-Datei (weitere Exportformate könnten leicht hinzugefügt werden).

Voraussetzungen

  • Betriebssystem: Windows 10, Windows 8.1, Windows 8, Windows Server 2008 und höher
  • Visual Studio 2015 SP3, Azure SDK 2.9, Azure Tools for Visual Studio

Einschränkungen

Azure WebApps können nicht mit List & Label verwendet werden, da diese keinen Zugriff auf Drucker zulassen. Siehe den entsprechenden Thread im MSDN Forum.

Ebenso können leider auch keine Azure Functions verwendet werden. Diese laufen in einer Sandbox, die aus Sicherheitsgründen alle Aufrufe in das Windows-GDI unterdrückt.

Visual Studio Projekt einrichten

Schritt 1: Ein neues Projekt anlegen

Nachdem die “Azure Tools for Visual Studio” erfolgreich installiert wurden, erstellt man ein neues Projekt in Visual Studio. Im Templates-Baum gibt es dazu nun jeweils unterhalb der Punkte C# und Visual Basic einen neuen Templatetyp mit dem Namen “Cloud”. Selektieren Sie diesen Templatetyp und wählen “Azure Cloud Service” und bestätigen den Dialog mit “OK”.

Nun können Sie die Rollen “Web Role” und “Worker Role” Ihrem Projekt hinzufügen.

Schritt 2: Referenz auf List & Label hinzufügen

Damit List & Label innerhalb dieses Projekts genutzt werden kann, muss die List & Label .NET Assembly combit.ListLabel??.dll dem Projekt über das Kontextmenü “Project > Add Reference …” hinzugefügt werden. Die Assembly befindet sich im List & Label Installationsverzeichnis im Unterordner “Programmierbare Beispiele und Deklarationen\Microsoft .NET\Assemblies”. Alternativ können Sie auch eine Referenz auf das entsprechende NuGet-Paket hinzufügen.

Schritt 3: Microsoft Azure Blob Storage

Ein Blob Storage ist nichts anderes als ein Speicher für große Binärdaten. In diesem Beispiel wird er dazu verwendet, die erstellten Berichte zu speichern. Damit der Storage erzeugt und genutzt werden kann, benötigen Sie einen Connection String. Dieser kann in den Eigenschaften der einzelnen Rollen hinzugefügt werden. Wichtig ist, diesen Connection String bei beiden Rollen, also sowohl bei der “Web Role” als auch bei der “Worker Role”, zu setzen. Um den Connection String zu setzen öffnen Sie den Solution Explorer und navigieren zum Cloud Service Projekt und öffnen die Settings aus dem Kontextmenü durch Klicken auf “Properties” für beide Rollen.

Wählen Sie im Properties Dialog den Reiter Settings und setzen die Service Configuration auf “All Configurations”. Dort sollte ein Connection String mit dem Namen Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString vorhanden sein; falls nicht, legen Sie diesen an und setzen den Typ auf Connection String. Sie sollten den Connection String für die Service Configurations Local (Entwicklungsumgebung) und Cloud (Produktivumgebung) separat setzen. Nachdem Sie die Connection String Einstellung in den “All Configurations” Modus versetzt haben, wechseln Sie die Service Configuration auf Local und setzen den Connection String auf “UseDevelopmentStorage=true”. (Hinweis: Wir empfehlen eine direkte Eingabe im Value Eingabefeld, da die … Schaltfläche zum Einfrieren von Visual Studio führen kann.)

Wechseln Sie anschließend die Service Configuration auf Cloud und setzen den Connection String Wert auf

DefaultEndpointsProtocol=https;AccountName=<YourCloudStorageAccountName>;AccountKey=<YourCloudStorageAccountKey>.

Speichern Sie anschließend die Änderungen an den Web Role Properties und wiederholen den Prozess für die Worker Role Properties.

Danach lässt sich mit wenigen Zeilen Code ein Blob Storage erzeugen:

// Create container
CloudStorageAccount storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
_container = blobClient.GetContainerReference("reports");
_container.CreateIfNotExists();

Schritt 4: Microsoft Azure Queue

Für die Kommunikation der beiden Rollen wird eine Queue verwendet. Über diese können beide Rollen Nachrichten austauschen. Eine solche Queue wird wie folgt erzeugt:

// Create queue
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
_queueWork = queueClient.GetQueueReference("llqueuework");
_queueWork.CreateIfNotExists();

Anschließend kann der Queue über die Methode AddMessage() eine neue Nachricht hinzugefügt werden. Die Methode erwartet entweder ein Byte-Array als Parameter oder einen String. In diesem Beispiel wird ein String ausgetauscht. Der Aufbau der Nachricht sieht folgendermaßen aus:

Reportname;Exportformat (z.B. Report.lst;PDF)

Schritt 5: Die Rollen

Eine Web Role ist eine einfache Webanwendung, welche später auf einem Internet Information Service (IIS) läuft. Eine Worker Role ist hingegen eine Rolle, welche sich im Hintergrund um die Verarbeitung von komplexeren Aufgaben kümmert. Ein Cloud Service muss mindestens aus einer dieser Rollen bestehen, kann aber beliebig viele enthalten. Beide Rollen erben standardmäßig von der Klasse RoleEntryPoint. Diese stellt Methoden zum Initialisieren, Starten und Stoppen der Rolle bereit.

Im Beispielprojekt wird die Worker Role verwendet um über List & Label einen Bericht entweder im PDF oder JPEG Format zu exportieren. Die Web Role stellt die Oberfläche des Beispiels zur Verfügung.

Der eigentliche Druck des Projekts ist ein gewöhnlicher “stiller Export”, wie er auch in normalen Webanwendungen implementiert wird:

using (ListLabel ll = new  ListLabel())
{
    ll.DebugLogFilePath = Path.GetTempPath() + "LlLogFile.txt";
    ll.Debug = LlDebug.LogToFile;

    // Set print options
    ll.AutoShowSelectFile = false;
    ll.AutoShowPrintOptions = false;
    ll.AutoDestination = LlPrintMode.Export;
    ll.AutoProjectType = LlProject.List;
    ll.AutoBoxType = LlBoxType.None;
    ...

    // Set export options
    ll.ExportOptions.Add("Export.File", fileName + extName);
    ll.ExportOptions.Add("Export.Path", tempPath);
    ll.ExportOptions.Add("Export.Quiet", "1");

    // Set data source
    ll.DataSource = GenericList.GetGenericList();
    ...
    ll.Print(LlProject.List, stream);
}

Schritt 6: Starten des Projekts

Wenn das Projekt nun gestartet wird öffnet sich in Ihrem Webbrowser die Startseite des Projekts.

Ablauf der Anwendung

  1. Der Benutzer wählt den zu ladenden Bericht aus und drückt die Schaltfläche “Create report”, womit der ausgewählte Bericht in den Blob Storage hochgeladen wird.
  2. Die Nachricht wird der Queue hinzugefügt.
  3. Die Worker Role überwacht die Queue und liest die Nachricht aus. Anschließend erzeugt die Worker Role die Datei im ausgewählten Format (über List & Label).
  4. Nun wird die erzeugte Datei in den Blob Storage hochgeladen.
  5. Abschließend wird die Datei aus dem Blob Storage heruntergeladen und im Browser angezeigt.

img5

Deployment auf Microsoft Azure Server

Es gibt zwei Möglichkeiten den Cloud Service auf Microsoft Azure zu deployen:

Veröffentlichung direkt aus Visual Studio

Der einfache und standardmäßige Weg ist direkt aus Visual Studio zu veröffentlichen. Wählen Sie dazu “Publish…” aus dem Kontextmenü des Cloud Service Projekts. Im “Publish Azure Application” Fenster müssen Sie Ihr Microsoft Konto und Ihre Subscription auswählen.

Hinweis: Während des Erstellens dieses Whitepapers sind wir auf einen Fehler in Visual Studio Azure Publish gestoßen: wenn Sie Ihre Subsciption auswählen, wird manchmal der Hinweis “Cloud Services are not available in this subscription.” angezeigt. Leider konnten wir keine Lösung für dieses Verhalten finden. Momentan empfehlen wir daher die manuelle Veröffentlichung sollten bei Ihnen hier ebenfalls Probleme auftreten.

Manuelle Veröffentlichung durch Azure Portal

  1. Zunächst müssen wir ein Package aus unserem Cloud Service Projekt in Visual Studio erstellen. Wählen Sie dazu “Package…” aus dem Kontextmenü des Cloud Service Projekts.

  2. Im “Package Azure Application” Fenster setzen Sie Service configuration auf Cloud und Build configuration auf Release und wählen “Enable Remote Desktop for all roles” und klicken auf “Settings…”.
    img6

  3. Im “Remote Desktop Configuration” Fenster erstellen Sie ein Zertifikat um die Benutzerinformationen zu verschlüsseln und fügen Benutzername und Passwort, die für die Remoteverbindung verwendet werden sollen, hinzu. (Sie müssen dieses Zertifikat nur für die erste Veröffentlichung erzeugen und hochladen.)
    img7

Nach der Erstellung des Zertifikats klicken Sie auf die “View…” Schaltfläche und öffnen den Reiter “Details” im Zertifikatsdialog und klicken dort dann auf die “Copy to File…” Schaltfläche. Im nächsten Dialog klicken Sie auf “Next” und wählen dann die Option “Yes, export the private key” und klicken auf “Next”. Im nächsten Dialog lassen Sie die Optionen unverändert und klicken auf “Next” und wählen dann “Group or user names (recommended)” und klicken auf “Next”. Anschließend geben Sie einen Dateinamen für die private Schlüsseldatei (die Adresse sollte enthalten sein, z.B. C:\testKey.pfx) und klicken auf “Finish” im nächsten Dialog. Jetzt haben Sie eine Schlüsseldatei, die vor dem Cloud Service im Azure Portal hochgeladen werden muss.

  1. Kehren Sie zum “Package Azure Application” Fenster zurück und klicken auf die “Package” Schaltfläche. Nachdem das Package erstellt wurde, stehen die Package-Dateien im Anwendungsordner unter \bin\Release\app.publish bereit.
  2. Öffnen Sie das Microsoft Azure Portal unter https://portal.azure.com und fügen Sie dort einen neuen Cloud Service hinzu.
  3. Nachdem Sie einen neuen Cloud Service hinzugefügt haben, klicken Sie auf dessen Namen und öffnen dessen Production Environment und Settings. Im Settings Panel klicken Sie auf “Certificates” und klicken dort auf die “Upload” Schaltfläche.
  4. Im “Upload Certificate” Panel öffnen Sie den Dateiauswahl-Dialog und wählen die private Schlüsseldatei (z.B. C:\testKey.pfx), die Sie in Schritt 3 erzeugt haben und geben das Password, das Sie dort definiert haben, ein und klicken auf “Upload”.
  5. Nachdem das Zertifikat erfolgreich hochgeladen wurde, können Sie die Cloud Service Package-Datei hochladen. Im Production Panel des Cloud Service klicken Sie auf die “Upload” Schaltfläche und wählen “Storage account”, geben ein “Deployment label” ein und wählen die “Package” und “Configuration” Dateien aus, die Sie in Schritt 4 erzeugt haben. Wählen Sie die Optionen “Deploy even if one or more roles contain a single instance” und “Start deployment” und klicken Sie auf die “OK” Schaltfläche.

Wichtig: Um Berichte mit List & Label zu exportieren, müssen Sie den Print Spooler Dienst auf dem Worker Role System starten. Nachdem Sie das Projekt erfolgreich hochgeladen haben, gibt es eine LLWebRole und eine LLWorkerRole im “Cloud Service Roles and Instances” Panel. Klicken Sie auf “LLWorkerRole_IN_0” und in dessen Panel auf die “Connect” Schaltfläche. Dies wird die benötigte .rdp Datei zum Verbinden mit dem Worker Role System herunterladen. Öffnen Sie diese Datei und verbinden Sie sich mit dem Worker Role System. In der Worker Role Remoteverbindung öffnen Sie die Dienste und starten den Print Spooler Dienst.