Ein End-to-End-Erweiterbarkeitsbeispiel für IIS 7.0-Entwickler

von Saad Ladki

IIS 7 und höher werden mit einer vollständig modularen Architektur erstellt, über umfangreiche Erweiterbarkeits-APIs. Auf diese Weise können Entwickler integrierte IIS-Komponenten ganz einfach hinzufügen, entfernen und sogar durch handgefertigte Komponenten ersetzen, die speziell für jede bestimmte Website geeignet sind. Es war noch nie so einfach, Code tief in die IIS-Kernpipeline einzuschließen und IIS auf eine Weise zu erweitern, die zuvor unmöglich war.

Um einige Beispiele zu geben: Mit einigen Codezeilen können Entwickler Module oder Handler schreiben, die neue Authentifizierungs- und Autorisierungsschemas bereitstellen, Laufzeit- oder Sicherheitsanalysen eingehender Anforderungen durchführen und Antworten überprüfen. Um jedoch einen echten Mehrwert zu bieten, müssen diese Module über Programmierschnittstellen, Befehlszeilenprogramme und eine Benutzeroberfläche verwaltbar sein.

Dieses Whitepaper ist ein End-to-End-Beispiel zum Erweitern des IIS-Webservers mit einem benutzerdefinierten Anforderungshandler. Es zeigt, wie Sie API- und Befehlszeilenunterstützung für die Konfiguration dieses Handlers hinzufügen und wie ein Benutzeroberflächenmodul in die IIS-Verwaltungsschnittstelle geschrieben wird.

Die Lösung wurde unter Windows Vista und Windows Server® 2008 Beta 3 getestet. Sie wird aktualisiert, sobald die endgültige Version von Windows Server 2008 verfügbar ist.

Funktionen

  • Verwalteter Handler fügt eine Copyrightnachricht in Bilddateien ein
  • Die Funktion für Copyright-Nachrichten ist konfigurationsgesteuert und verwendet das neue IIS-Konfigurationssystem
  • Die Konfiguration kann schematisiert und für Konfigurations-APIs, WMI-Skripting und IIS-Befehlszeilentools zugänglich gemacht werden
  • Das User Interface Extension Module ermöglicht die Konfiguration des Features für Copyrightnachrichten über die IIS-Benutzeroberfläche

Voraussetzungen

Um die Schritte in diesem Dokument auszuführen, muss die folgende Software installiert werden:

ASP.NET

Installieren Sie ASP.NET über die Windows Vista-Systemsteuerung. Wählen Sie "Programme" – "Windows-Features aktivieren oder deaktivieren" aus. Öffnen Sie "Internetinformationsdienste" – „World Wide Web-Dienste“ – "Anwendungsentwicklungsfeatures" und prüfen Sie "ASP.NET“.

Wenn Sie über einen Windows Server 2008-Build verfügen. öffnen Sie "Server-Manager" – "Rollen verwalten", und wählen Sie "Webserver (IIS)" aus. Klicken Sie auf "Rollendienste hinzufügen". Aktivieren Sie unter "Anwendungsentwicklung" das Kontrollkästchen "ASP.NET".

Sie müssen auch "IIS-Verwaltungsskripts und -tools" installieren, um die WMI-Erweiterbarkeit in IIS zu nutzen. Wählen Sie dafür "Programme" – "Windows-Features aktivieren oder deaktivieren" aus. Öffnen Sie dann "Internetinformationsdienste" – "Webverwaltungstools" und überprüfen Sie "IIS-Verwaltungsskripts und -tools".

Wenn Sie über einen Windows Server 2008-Build verfügen, öffnen Sie "Server-Manager" – "Rollen", und wählen Sie "Webserver (IIS)" aus. Klicken Sie auf "Rollendienste hinzufügen". Aktivieren Sie unter "Webverwaltungstools" die Option "IIS-Verwaltungsskripts und -tools".

Visual C# Express Edition oder Visual Studio 2005

Für das Benutzeroberflächenmodul benötigen Sie ein C#-Entwicklungstool. Wenn Sie nicht über eine Kopie von Visual Studio 2005 verfügen, laden Sie Visual Studio kostenlos herunter.

Umgang mit Problemen mit der Benutzerkontensteuerung

Der Windows Vista-Benutzerkontoschutz entfernt die Administratorrechte aus Ihrem Zugriffstoken. Standardmäßig haben Sie keinen Zugriff auf IIS-Konfiguration und Inhaltsspeicherorte. Um dieses Problem zu beheben, empfehlen wir, diesen Artikel mithilfe einer Eingabeaufforderung mit erhöhten Rechten zu durchlaufen.

Um eine Eingabeaufforderung mit erhöhten Rechten zu starten, wechseln Sie zum Menü "Start", klicken Sie auf "Alle Programme" – "Zubehör". Klicken Sie mit der rechten Maustaste auf "Eingabeaufforderung", und klicken Sie dann auf "Als Administrator ausführen". Bestätigen Sie die Eingabeaufforderung zur Erhöhung.

Szenario

Im folgenden Beispiel werden Bilder, die von unserem Webserver bereitgestellt werden, dynamisch mit Copyrightinformationen in der unteren linken Ecke versehen, wie in Abbildung 1 dargestellt.

Screenshot of the web page displaying an image of snow covered rocky mountains on the backdrop of a cloudy sky.
Abbildung 1: Bild Copyright-Modul in Aktion

Wir verwenden verwalteten Code zum Entwickeln des Handlers, der die Bilder schmückt. Im Rahmen des Beispiels geben wir auch die Konfiguration für diesen Handler an und speichern sie im IIS-Konfigurationsspeicher. Zuletzt entwickeln wir ein Benutzeroberflächen-Plug-In für IIS-Manager.

Der IIS-Konfigurationsspeicher kann erweitert werden, indem einfach eine Schemadatei in das IIS-Schemaverzeichnis kopiert wird. Das Schema deklariert den Namen des neuen Konfigurationsabschnitts sowie seine Attribute, Typen und Standardwerte. In unserem Beispiel deklarieren wir einen neuen Konfigurationsabschnitt namens imageCopyright. Sie befindet sich in der Konfigurationsgruppe "system.webServer". Seine Eigenschaften sind:

  • Ein boolesches Flag, das die ImageCopyright-Funktionalität aktiviert oder deaktiviert
  • Ein Zeichenfolgen-Attribut, das die Copyrightnachricht enthält
  • Ein Farbattribute, das die Farbe der Copyrightnachricht angibt

Schemadeklaration

Speichern Sie die folgende Schemadefinition als imagecopyright.xml in %windir%\system32\inetsrv\config\schema:

<configSchema>
    <sectionSchema name="system.webServer/imageCopyright">
        <attribute name="enabled" type="bool" defaultValue="false" />
        <attribute name="message" type="string" defaultValue="Your Copyright Message" />
        <attribute name="color" type="string" defaultValue="Red"/> 
   </sectionSchema>
</configSchema>

Wenn Sie eine Meldung "Zugriff verweigert" erhalten, haben Sie dies nicht über die Eingabeaufforderung mit erhöhten Rechten ausgeführt. Nachdem die Schemadatei hinzugefügt wurde, muss das Schema in der Datei applicationhost.config deklariert werden. Fügen Sie den folgenden XML-Code hinzu %windir%\system32\inetsrv\config\applicationhost.config

<configSections>
...
<sectionGroup name="system.webServer">
<section name="imageCopyright"  overrideModeDefault="Allow"/>
...    
</sectionGroup>
</configSections>

Konfigurieren Sie es

Der Prozess ist abgeschlossen. Sie können die neuen Konfigurationseinstellungen über die Befehlszeile oder direkt in applicationhost.config oder web.config festlegen. Probieren Sie es aus. Öffnen Sie eine Befehlsshell, und geben Sie Folgendes ein:

<system.webServer>
    <imageCopyright />
</system.webServer>

Die Ausgabe zeigt, dass der Konfigurationsabschnitt mit der Standardkonfiguration erkannt wurde:

%windir%\system32\inetsrv\appcmd set config -section:system.webServer/imageCopyright 

/color:yellow /message:"Copyright (C) Contoso.COM" /enabled:true

Fügen Sie nun Ihre Konfigurationseinstellungen über appcmd.exe hinzu, z. B.

%windir%\system32\inetsrv\appcmd set config -section:system.webServer/imageCopyright 

/color:yellow /message:"Copyright (C) Contoso.COM" /enabled:true

Überprüfen Sie, ob die Konfiguration gespeichert wurde, indem Sie Folgendes ausführen:

%windir%\system32\inetsrv\appcmd list config -section:system.webServer/imageCopyright

Siehe die gespeicherte Konfiguration:

<system.webServer> 
    <imageCopyright enabled="true" message="Copyright (C) Contoso.COM" color="yellow" />
</system.webServer>

imageCopyright-Konfiguration skriptfähig machen

Hinweis

Die ImageCopyright-Handlerkonfiguration für WMI-Skripts verfügbar zu machen, ist optional. Sie können direkt zu "Schritt 2 – Core Extensibility: The Image Copyright Handler" wechseln, ohne die verbleibenden Schritte zu beeinträchtigen.

Führen Sie die folgenden Schritte aus, um die imageCopyright-Handlerkonfiguration für WMI-Skripts verfügbar zu machen:

  • Installation der IIS-WMI-Unterstützung
  • Erstellen der Datei imageCopyright.mof
  • Einschließen der Datei imageCopyright.mof in webadministration.mof und Kompilierung der WMI-Schemadateien
  • Schreiben und Ausführen des Skripts

Installation der IIS-WMI-Unterstützung

Die Standardinstallation von IIS enthält nicht die WMI-Skriptkomponenten. Sie müssen sie hinzufügen.

Installation der WMI-Unterstützung auf Vista-Client-SKUs

Installieren Sie "IIS-Verwaltungsskripts und -tools" über die Windows Vista-Systemsteuerung. Wählen Sie "Programme" – "Windows-Features aktivieren oder deaktivieren" aus. Öffnen Sie dann "Internetinformationsdienste" – "Webverwaltungstools", und überprüfen Sie "IIS-Verwaltungsskripts und -tools".

Installation der WMI-Unterstützung unter Windows Server 2008-SKUs

Wenn Sie über einen Windows Server 2008-Build verfügen, öffnen Sie "Server-Manager" – "Rollen", und wählen Sie "Webserver (IIS)" aus. Klicken Sie auf "Rollendienste hinzufügen". Aktivieren Sie unter "Verwaltungstools" "IIS-Verwaltungsskripts und -tools".

Erstellen der ImageCopyright.mof-Datei

Die Schemadeklaration von WMI-Eigenschaften ist der Schemadeklaration von IIS-Eigenschaften im vorherigen Schritt sehr ähnlich. WMI-Schemas werden in MOF-Dateien deklariert und von einem Tool mit dem Namen "mofcomp" kompiliert. Mofcomp fügt dem WMI-Repository die Schemadeklaration hinzu.

Aufgaben zum Hinzufügen der Schemainformationen

Öffnen Sie eine Editorinstanz, und kopieren Sie die folgenden Zeilen darin:

#pragma AUTORECOVER
#pragma namespace("\\\\.\\Root\\WebAdministration")
[            
    dynamic : ToInstance ToSubClass,
    provider("WebAdministrationProvider") : ToInstance ToSubClass,
    Description("imageCopyright Section") : ToSubClass,
    Locale(1033) : ToInstance ToSubClass,
    factory_clsid("{901a70b2-0f7a-44ea-b97b-1e9299dec8ca}"),
    section_path("system.webServer/imageCopyright"),
    SupportsUpdate
]
 
class imageCopyright : ConfigurationSection
{      
    [
        read: ToSubClass ToInstance,
        write: ToSubClass ToInstance,
        DefaultValue("False"): ToSubClass ToInstance,
        Description("To be written"): ToSubClass ToInstance
    ]
    boolean Enabled;
  
    [
        read: ToSubClass ToInstance,
        write: ToSubClass ToInstance,
        DefaultValue("Your Copyright Message"): ToSubClass ToInstance,
        Description("Copyright Message"): ToSubClass ToInstance
    ]
    string Message;

    [
        read: ToSubClass ToInstance,
        write: ToSubClass ToInstance,
        DefaultValue("Yellow"): ToSubClass ToInstance,
        Description("Color of Copyright Message"): ToSubClass ToInstance
    ]
    string Color;
};

Die Schemadeklaration enthält die gleichen Einträge wie imageCopyright.xml im vorherigen Schritt, nämlich den Namen und typ der Konfigurationseinstellung und den Standardwert. Speichern Sie die Datei unter dem Namen %windir%\system32\inetsrv\imageCopyright.mof.

Kompilierung von WMI-Schemadateien

Kompilieren von imageCopyright.mof durch Ausführen des folgenden Befehls

mofcomp webadministration.mof

Das WMI-Skript

Mofcomp hat dem WMI-Repository das imageCopyright-Schema hinzugefügt. Legen Sie IIS-Konfigurationseinstellungen fest, indem Sie den IIS-WMI-Anbieter skripten. Hier ist ein Beispiel:

Aufgaben

Öffnen Sie eine Instanz von NOTEPAD, und kopieren Sie die folgenden Zeilen darin. Speichern Sie die Datei als SetCopyrightConfig.vbs:

Set oIIS = GetObject("winmgmts:root\WebAdministration")        
Set oSection = oIIS.Get("ImageCopyright.Path='MACHINE/WEBROOT/APPHOST/Default Web Site',Location=''")
oSection.Enabled = true
oSection.Message = "Copyright (C) IIS7 Team - Date: " & date
oSection.Color = "White"
oSection.Put_

Dies ist ein Standardmäßiges WMI-Skript, das eine Verbindung mit dem IIS-WMI-Anbieter herstellt. Er ruft den Konfigurationsabschnitt am angegebenen Speicherort ("Standardwebsite") ab und ändert seine Werte. Der Aufruf Put_ speichert die Änderungen auf dem Datenträger.

Wenn Sie das Skript ausführen, wird die Copyright-Nachricht mit dem aktuellen Datum hinzugefügt %systemdrive%\inetpub\wwwroot\web.config. Werfen Sie einen Blick darauf.

Fügen Sie als Nächstes den Bild-Copyright-Handler selbst hinzu.

Ein Handler ist ein Codeteil, der ausgeführt wird, wenn die Anforderung mit einem bestimmten Muster übereinstimmt, in der Regel eine Dateierweiterung. Anforderungen, die mit . ASP wird beispielsweise ASP.DLL zugeordnet. In IIS 6.0 mussten Sie eine ISAPI-Erweiterung schreiben, um Anforderungen mit einer bestimmten Dateierweiterung zu verarbeiten. ASP.NET auch die Verarbeitung von Dateierweiterungen erlaubt, aber nur, wenn Sie die Anforderung zuerst ASP.NET zugeordnet haben. In IIS können Sie beliebige Dateierweiterungen verarbeiten, ohne ASP.NET einzubeziehen. In unserem Beispiel behandeln wir Anforderungen mit der Erweiterung .JPG. Gehen Sie wie folgt vor:

Erstellen des Inhaltsverzeichnisses

Erstellen Sie beispielsweise c:\inetpub\mypictures ein Inhaltsverzeichnis, und kopieren Sie einige digitale Bilder Ihrer Wahl in das Verzeichnis. Stellen Sie sicher, dass diese Dateien Bilddateien mit der Erweiterung .JPG sind.

Hinweis

Aus Gründen der Einfachheit enthalten die hier gezeigten Codebeispiele keinen Fehlerbehandlungscode für Dateien, die keine Bilddateien sind.

Erstellen Sie ein Unterverzeichnis namens App_Code unter Ihrem neuen Verzeichnis, z. B. c:\inetpub\mypictures\App\_Code.

Erstellen der mypictures-Anwendung

Sie können eine Anwendung erstellen, die über die IIS-Verwaltungskonsole verweist c:\inetpub\mypictures, aber es gibt interessantere Möglichkeiten, dies zu tun. Erstellen Sie eine neue Anwendung über appcmd. Mit dem folgenden Befehl wird eine App namens "mypictures" auf der "Standardwebsite" mit dem physischen Pfad c:\inetpub\mypictures erstellt:

%windir%\system32\inetsrv\appcmd add app -site.name:"Default Web Site"

-path:/mypictures -physicalPath:%systemdrive%\inetpub\mypictures

Da die JPG-Dateien, die in dieses Verzeichnis kopiert wurden, angezeigt werden sollen, aktivieren Sie die Verzeichnissuche. Verwenden Sie dazu die IIS-Verwaltungskonsole, oder greifen Sie auf eine interessantere Methode zurück und verwenden Sie appcmd. Hier erfahren Sie, wie Sie die Verzeichnissuche über appcmd auf "true" festlegen:

%windir%\system32\inetsrv\appcmd set config "Default Web Site/mypictures"

 -section:directoryBrowse -enabled:true

Wenn Sie http://localhost/mypictures anfordern, wird ein Verzeichniseintrag mit Ihren Bildern angezeigt.

Zeit zum Schreiben von Code

Schreiben Sie nun den tatsächlichen Code für das Bildhandling. Schreiben Sie ein paar Zeilen C#-Code, und Sie haben das Ergebnis: Verwenden Sie den folgenden Code als Verweis, und speichern Sie ihn als imagecopyrighthandler.cs in Ihrem App_Code Verzeichnis, z. B. c:\inetpub\mypictures\App\_Code\imagecopyrighthandler.cs.

#region Using directives
using System;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.Web.Administration;
#endregion
  
namespace IIS7Demos
{
    public class imageCopyrightHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            ConfigurationSection imageCopyrightHandlerSection = 
                WebConfigurationManager.GetSection("system.webServer/imageCopyright");
  
            HandleImage(    context,
                            (bool)imageCopyrightHandlerSection.Attributes["enabled"].Value,
                            (string)imageCopyrightHandlerSection.Attributes["message"].Value,
                            (string)imageCopyrightHandlerSection.Attributes["color"].Value                            
                        );
        }
  
        void HandleImage(   HttpContext context,
                            bool enabled,
                            string copyrightText,
                            string color
                        )           
        {
            try
            {
                string strPath = context.Request.PhysicalPath;
                if (enabled)
                {
                    Bitmap bitmap = new Bitmap(strPath);
                    // add copyright message
                    Graphics g = Graphics.FromImage(bitmap);
                    Font f = new Font("Arial", 50, GraphicsUnit.Pixel);
                    SolidBrush sb = new SolidBrush(Color.FromName(color));
                    g.DrawString(   copyrightText,
                                    f,
                                    sb,
                                    5,
                                    bitmap.Height - f.Height - 5
                                );
                    f.Dispose();
                    g.Dispose();
                    // slow, but good looking resize for large images
                    context.Response.ContentType = "image/jpeg";
                    bitmap.Save(
                                        context.Response.OutputStream,
                                        System.Drawing.Imaging.ImageFormat.Jpeg
                                     );
                    bitmap.Dispose();
                }
                else
                {
                    context.Response.WriteFile(strPath);
                }
            }
            catch (Exception e)
            {
                context.Response.Write(e.Message);
            }
        }
  
        public bool IsReusable
        {
            get { return true; }
        }
    }
}

Der obige Code führt die folgenden Aktionen aus:

  • Liest die Konfiguration
  • Ruft HandleImage auf

HandleImage führt die folgenden Aktionen aus:

  • Erstellt ein Grafikobjekt aus der Bitmap
  • Erstellt ein Schriftartobjekt mit den konfigurierten Werten
  • Zeichnet die Nachricht in die Bitmap

Um die Microsoft.Web.Administration-Klasse zu verwenden, müssen Sie den Verweis auf die IIS-Verwaltungs-API-Assembly hinzufügen. Öffnen Sie dazu %systemdrive%\inetpub\mypictures\web.config und fügen Sie die folgenden Einträge hinzu:

<system.web>
    <compilation>
      <assemblies>
        <add assembly="Microsoft.Web.Administration, Version=7.0.0.0, 
Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
      </assemblies>
    </compilation>
</system.web>

Sie können den Handler auch in eine Assembly kompilieren und in den mypictures/bin einfügen. Wenn Sie dies tun, müssen Sie der Datei "web.config" die Assembly "Microsoft.Web.Administration" nicht hinzufügen.

Handlerkonfiguration

Sie müssen IIS nur anweisen, den neuen Handler aufzurufen, wenn eine .JPG Datei angefordert wird. Gehen Sie dazu über die IIS-Verwaltungskonsole vor, oder verwenden Sie appcmd:

appcmd set config "Default Web Site/mypictures/" -section:handlers 

/+[name='JPG-imageCopyrightHandler',path='*.jpg',verb='GET',type='IIS7Demos.imageCopyrightHandler']

Der obige Befehl "appcmd" konfiguriert nur den neuen Handler im Verzeichnis "/mypictures". Da sich Handlereinträge in einer Auflistung befinden, müssen Sie die Syntax +[] verwenden. Diese Syntax wird immer verwendet, wenn der Auflistung Elemente hinzugefügt werden müssen. Die Elemente der Handlerkonfiguration sind:

name

Dies kann ein beliebiger eindeutiger Name sein. Der Name wird nur verwendet, um den Handler eindeutig zu identifizieren.

path

Weist IIS an, wann dieser Handler ausgeführt werden soll. *.JPG weist IIS an, diesen Handler für alle Dateien auszuführen, die auf .JPG enden. Wenn Sie foo*.JPG als Pfad verwenden, werden nur JPG-Dateien, die mit foo beginnen, von diesem Handler ausgeführt.

Verb

Kommagetrennte Liste der HTTP-Verben, die übereinstimmen müssen, um diesen Handler auszuführen. In unserem Fall möchten wir die Anforderung nur ausführen, wenn eine GET-Anforderung eingeht.

type

Der verwaltete Typ der Klasse, die ausgeführt werden soll, wenn die Anforderung übereinstimmt. Sie besteht aus dem Namespace und der von IHttpHandler abgeleiteten Klasse in Ihrem App_Code Verzeichnis.

Eine letzte Notiz

Bevor Sie mit dem Testen der urheberrechtlich geschützten Bilder beginnen, stellen Sie sicher, dass der IIS-Arbeitsprozess, der die Anforderung ausführt, die von Ihnen vorgenommenen Schemaänderungen erfasst. Es ist möglich, dass der Arbeitsprozess bereits ausgeführt wurde, wenn Sie die imageCopyright.xml Datei zum Schemaverzeichnis hinzugefügt haben. In diesem Fall erhalten Sie eine Konfigurationsausnahme in imagecopyrightconfig.cs. Der Autor ist in diesem Problem aufgetreten, wenn er diesen Artikel schreibt und ziemlich viel Zeit kostet.

Das Einfache Recycling des Anwendungspools löst dieses Problem:

appcmd recycle AppPool DefaultAppPool

Der Prozess ist abgeschlossen. Wenn Sie jetzt anfordern http://localhost/mypictures/<imageOfYourChoice>.jpg), wird die Copyrightnachricht angezeigt.

Optionen:

  • Sie können die Copyright-Nachrichtenoptionen über appcmd ändern oder die Datei "web.config" direkt bearbeiten
  • Sie können den imageCopyright-Handler anderen Bildtypen, e.g. BMP oder GIF zuordnen, indem Sie denselben Handler für eine andere Erweiterung hinzufügen. Beispiel:
appcmd set config "Default Web Site/mypictures/" -section:handlers /+[name='BMP-imageCopyrightHandler',path='*.bmp',verb='GET',type='IIS7Demos.imageCopyrightHandler']

Zeit für die letzten Berührungen. Wir haben den IIS-Kernserver bereits mit einigen Codezeilen erweitert. wir haben das IIS-Konfigurationssystem ohne Code erweitert und erhalten kostenlosen Befehlszeilensupport. Konfigurieren Sie nun unseren imageCopyright-Handler über die IIS-Verwaltungskonsole.

Dies tun wir über die folgenden Aufgaben:

  • Erstellen des Projekts in Microsoft Visual Studio oder Microsoft Visual C# Express, sodass die Assembly in der IIS-Verwaltungskonsole verwendet werden kann
  • Erstellen eines Modulanbieters
  • Erstellen eines Moduls, das imageCopyright-Eigenschaften liest und festlegt.

Erstellen des Projekts

Zum Erstellen eines Erweiterbarkeitsmoduls für InetMgr müssen Sie ein DLL-Projekt erstellen, das auch als Klassenbibliotheksprojekt bezeichnet wird. Diese DLL muss stark benannt werden, damit sie im GAC (Global Assembly Cache) registriert werden kann, was eine Anforderung für Module ist, die von der IIS-Verwaltungskonsole verwendet werden.

Schritte

  1. Klicken Sie auf "Start", klicken Sie auf "Programme", und führen Sie Microsoft Visual Studio 2005 oder Microsoft Visual C# 2005 Express Edition aus.

  2. Wählen Sie im Menü "Datei" die Option "Neues Projekt" aus.

  3. Wählen Sie im Dialogfeld "Neues Projekt" "Klassenbibliothek" als Projekttyp aus, und geben Sie "imageCopyrightUI" als Namen des Projekts ein, und klicken Sie auf "OK".

    Screenshot of New Project dialog box with Class Library selected and image Copyright U I entered in the Name filed as the name of the project.
    Abbildung 2: Dialogfeld "Neues Projekt"

  4. Entfernen Sie die Datei Class1.cs, die standardmäßig hinzugefügt wurde, da wir dies nicht verwenden.

  5. Fügen Sie mithilfe der Option "Neue Referenz hinzufügen" im Menü "Projekt" einen Verweis auf Microsoft.Web.Management.dll hinzu, der sich im Verzeichnis "\Windows\system32\inetsrv" befindet. Dies ist die DLL, die alle Erweiterungsklassen enthält, die zum Erstellen von Modulen für die IIS-Verwaltungskonsole erforderlich sind.

  6. Fügen Sie mithilfe der Option "Neue Referenz hinzufügen" im Menü "Projekt" einen Verweis auf Microsoft.Web.Administration.dll hinzu, der sich im Verzeichnis "\Windows\system32\inetsrv" befindet. Dies ist die DLL, die alle Konfigurationsklassen enthält, die zum Lesen der IIS-Konfiguration benötigt werden.

  7. Da wir Code zum Erstellen der Benutzeroberfläche basierend auf WinForms verwenden, möchten wir auch einen Verweis auf System.Windows.Forms.dll hinzufügen. wählen Sie dazu erneut mithilfe der Option "Neue Referenz hinzufügen" im Menü "Projekt" System.Windows.Forms.dll und System.Web.dll in the.NET Liste der Assemblys aus.

  8. Einer der Anforderungen für Bibliotheken, die in InetMgr verwendet werden sollen, besteht darin, dass sie innerhalb des GAC registriert werden müssen. Dafür müssen wir sicherstellen, dass unsere DLL stark benannt ist (manchmal auch als signiert bezeichnet). Visual Studio bietet eine einfache Möglichkeit, neue Namen zu erstellen und eins für das Projekt auszuwählen. Wählen Sie dazu im Menü "Projekt" die Option imageCopyrightUI-Eigenschaften aus.

  9. Aktivieren Sie auf der Registerkarte "Signieren" die Assembly signieren.

  10. Geben Sie im Feld „Schlüssel mit starkem Namen erstellen“ den Namen imageCopyrightUI ein und deaktivieren Sie das Kontrollkästchen „Meine Schlüsseldatei mit einem Kennwort schützen“. Klicken Sie auf OK.

    Screenshot of Create Strong Name Key dialog box displaying image Copyright U I entered as Key file name and password created and confirmed.
    Abbildung 3: Dialogfeld "Starker Name erstellen"

    Auf der Registerkarte "Signieren" wird Folgendes angezeigt:

    Screenshot of Signing tab with image Copyright U I dot s n k selected in the Choose a strong name key file field.
    Abbildung 4: Registerkarte "VS-Projektsignierung"

  11. Da die Assembly im GAC sein soll, fügen wir einige Postbuildereignisse hinzu, damit sie bei jeder Kompilierung automatisch dem GAC hinzugefügt wird. Dadurch wird es wirklich direkt zum Debuggen und Vornehmen von Änderungen führen, wenn wir neue Funktionen hinzufügen. Wählen Sie dazu die RegisterkarteBuildereignisse aus, und fügen Sie die folgende Befehlszeile für das Postbuildereignis hinzu:

    call "%VS80COMNTOOLS%\vsvars32.bat" > NULL
    
    gacutil.exe /if "$(TargetPath)"
    

    Screenshot of Post Build Event command line populated with code.
    Abbildung 5: Registerkarte "VS PostBuildereignisse"

    (Optional) Wenn Sie Microsoft Visual Studio 2005 verwenden (dies funktioniert nicht mit der Visual C# Express Edition), richten Sie das Debuggen ordnungsgemäß ein, um F5 zum Ausführen des Codes zu verwenden. Wechseln Sie dazu zu den Projekteigenschaften, wählen Sie die Registerkarte "Debuggen" aus, und legen Sie fest, dass ein externes Programm unter \windows\system32\inetsrv\inetmgr.exe

    Screenshot of Debug tab set to Start external program action.
    Abbildung 6: Registerkarte "Debuggen"

  12. Schließen Sie schließlich die Projekteigenschaften, wählen Sie die Option "Alle speichern" im Menü "Datei" aus, und klicken Sie auf "OK".

    Kompilieren Sie das Projekt nun mithilfe des Menüs "Projektmappe erstellen" im Menü "Erstellen". Dadurch wird die DLL automatisch erstellt und dem GAC hinzugefügt.

Erstellen des Modulanbieters

Die IIS-Benutzeroberfläche ist so anpassbar und modular wie der IIS-Kernserver und das IIS-Konfigurationssystem. Die IIS-Benutzeroberfläche ist eine Reihe von Featuremodulen, die entfernt oder ersetzt werden können. Der Einstiegspunkt für jedes Benutzeroberflächenmodul ist ein Modulanbieter. Eine Liste aller Modulanbieter finden Sie im %windir%\system32\inetsrv\Administration.config<modules> Abschnitt.

Erstellen Sie als ersten Schritt den imageCopyrightUI-Modulanbieter.

Schritte

  1. Wählen Sie die Option "Neues Element hinzufügen" aus dem Projektmenü aus. Wählen Sie im Dialogfeld "Neues Element hinzufügen" die Klassenvorlage aus, und geben Sie imageCopyrightUIModuleProvider.cs als Namen für die Datei ein.

    Screenshot of Add New Item dialog box with Class template selected and the Name field populated with image Copyright U I Module Provider dot c s.
    Abbildung 7: Dialogfeld "Neues Element hinzufügen"

  2. Ändern Sie den Code so, dass er wie folgt aussieht:

    using System;
    using System.Security;
    using Microsoft.Web.Management.Server;
        
    namespace IIS7Demos           
    {
        class imageCopyrightUIProvider : ModuleProvider
        {
            public override Type ServiceType              
            {
                get { return null; }
            }
    
            public override ModuleDefinition GetModuleDefinition(IManagementContext context)
            {
                return new ModuleDefinition(Name, typeof(imageCopyrightUI).AssemblyQualifiedName);
            }
    
            public override bool SupportsScope(ManagementScope scope)
            {
                return true;
            }
        }            
    }
    

    Dieser Code erstellt einen ModuleProvider, der alle Arten von Bereichen (Server, Standort und Anwendung) unterstützt und ein clientseitiges Modul namens imageCopyrightUI registriert. Damit Ihr Modul nur auf Anwendungsebene angezeigt wird, sieht die SupportsScope-Funktion wie folgt aus:

    public override bool SupportsScope(ManagementScope scope)
    {
        return (scope == ManagementScope.Application) ;
    }
    

Erstellen des Benutzeroberflächenmoduls

Ein Modul ist der Haupteinstiegspunkt im Client für alle Erweiterbarkeitsobjekte. Es verfügt über eine Hauptmethode namens Initialisieren. Dies ist die Methode, bei der alle Aktionen ausgeführt werden.

Schritte

  1. Wählen Sie die Option "Neues Element hinzufügen" im Projektmenü aus.

  2. Wählen Sie die Klassenvorlage aus, und geben Sie imageCopyrightUI.cs als Dateinamen ein. Ändern Sie den Code so, dass er wie folgt aussieht:

    using System;
    using System.Windows.Forms;
    using Microsoft.Web.Management.Client;
    using Microsoft.Web.Management.Server;
    
    namespace IIS7Demos
    {
        internal class imageCopyrightUI : Module
        {
            protected override void Initialize(IServiceProvider serviceProvider, ModuleInfo moduleInfo)
            {
                base.Initialize(serviceProvider, moduleInfo);
                IControlPanel controlPanel = (IControlPanel)GetService(typeof(IControlPanel));
                ModulePageInfo modulePageInfo = new ModulePageInfo(this, typeof(imageCopyrightUIPage), "Image Copyright", "Image Copyright");
                controlPanel.RegisterPage(modulePageInfo);
            }
        }              
    }
    

    Im obigen Code geben wir den Text des Eintrags in der Liste der Benutzeroberflächenmodule und den Typ einer einzelnen Seite an, die angezeigt werden soll, wenn ein Benutzer auf diesen Text klickt.

Alles, was übrig ist, besteht darin, die Seite selbst zu schreiben.

Erstellen der Modulseite

In dieser Aufgabe erstellen Sie die einfachste Modulseite. ModulePage ist die Basisklasse, die vom Framework bereitgestellt wird, um eine neue Benutzeroberfläche zu erstellen. Es gibt vier verschiedene Klassen, die vom Framework bereitgestellt werden, die hilfreich sind, je nach Szenario, das Sie erstellen möchten.

  • ModulePage. Diese Basisklasse bietet nur die einfachsten Dienste und bietet überhaupt keine spezielle Benutzeroberfläche. Keiner der Features, die in InetMgr enthalten sind, wird direkt von dieser Klasse abgeleitet.
  • ModuleDialogPage. Diese Basisklasse bietet ähnliche Semantik als Dialogfeld, einschließlich einer Verknüpfung "Anwenden" und "Abbrechen" in der Aufgabenliste und bietet spezifische Methoden, die Sie überschreiben können, um diese häufig verwendeten Aufgaben zu behandeln. Außerdem werden Elemente wie "Aktualisieren" und andere Funktionen automatisch behandelt. Beispiele für Features, die von dieser Seite abgeleitet werden, sind Computerschlüssel, Verwaltungsdienst usw.
  • ModulePropertiesPage. Diese Basisklasse bietet eine Benutzeroberfläche, die dem Visual Studio-Eigenschaftenraster ähnelt, in dem alle Eigenschaften in einem hierarchischen rasterähnlichen Steuerelement angezeigt werden. Beispiele hierfür sind CGI, ASP, .NET-Kompilierung usw.
  • ModuleListPage. Diese Basisklasse ist nützlich, wenn Sie eine Liste von Elementen anzeigen müssen. Es enthält ein ListView-Steuerelement, mit dem Sie die Einstellungen anzeigen und Suchen, Gruppieren und Ansichten automatisch anbieten können. Beispiele sind Anwendungseinstellungen, Module, Arbeitsprozesse usw.

Schritte

  1. Wählen Sie die Option "Neues Element hinzufügen" aus dem Projektmenü aus.

  2. Wählen Sie im Dialogfeld "Neues Element hinzufügen" die Vorlage "Klasse" aus, und geben Sie imageCopyrightUIPage.cs als Namen für die Datei ein. Ändern Sie den Code so, dass er wie folgt aussieht:

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using Microsoft.Web.Management.Client.Win32;
    using Microsoft.Web.Administration;
    using Microsoft.Web.Management.Client;
    using Microsoft.Web.Management.Server;
    namespace IIS7Demos
    {
        public sealed class imageCopyrightUIPage : ModulePage
        {
            public string message;
            public bool featureenabled;
            public string color;
    
            ComboBox _colCombo = new ComboBox();
            TextBox _msgTB = new TextBox();
            CheckBox _enabledCB = new CheckBox();
            public imageCopyrightUIPage()
            {
                this.Initialize();
            }
            protected override void OnActivated(bool initialActivation)
            {
               base.OnActivated(initialActivation);
               if (initialActivation)
               {
                    ReadConfig();
                    UpdateUI();
                }
            }
    
            void UpdateUI()
            {
                _enabledCB.Checked = featureenabled;
                int n = _colCombo.FindString(color, 0);
                _colCombo.SelectedIndex = n;
                _msgTB.Text = message;
            }
    
            void Initialize()
            {
                Label crlabel = new Label();
                crlabel.Left = 50;
                crlabel.Top = 100;
                crlabel.AutoSize = true;
                crlabel.Text = "Enable Image Copyright:";
                _enabledCB.Text = "";
                _enabledCB.Left = 200;
                _enabledCB.Top = 100;
                _enabledCB.AutoSize = true;
    
                Label msglabel = new Label();
                msglabel.Left = 150;
                msglabel.Top = 130;
                msglabel.AutoSize = true;
                msglabel.Text = "Message:";
                _msgTB.Left = 200;
                _msgTB.Top = 130;
                _msgTB.Width = 200;
                _msgTB.Height = 50;
    
                Label collabel = new Label();
                collabel.Left = 160;
                collabel.Top = 160;
                collabel.AutoSize = true;
                collabel.Text = "Color:";
                _colCombo.Left = 200;
                _colCombo.Top = 160;
                _colCombo.Width = 50;
                _colCombo.Height = 90;
                _colCombo.Items.Add((object)"Yellow");
                _colCombo.Items.Add((object)"Blue");
                _colCombo.Items.Add((object)"Red");
                _colCombo.Items.Add((object)"White");
    
                Button apply = new Button();
                apply.Text = "Apply";
                apply.Click += new EventHandler(this.applyClick);
                apply.Left = 200;
                apply.AutoSize = true;
                apply.Top = 250;
    
                Controls.Add(crlabel);
                Controls.Add(_enabledCB);
                Controls.Add(collabel);
                Controls.Add(_colCombo);
                Controls.Add(msglabel);
                Controls.Add(_msgTB);
                Controls.Add(apply);
            }
    
            private void applyClick(Object sender, EventArgs e)
            {
                try
                {
                    UpdateVariables();
                    ServerManager mgr;
                    ConfigurationSection section;
                    mgr = new ServerManager();
                    Configuration config =
                    mgr.GetWebConfiguration
                    (
                           Connection.ConfigurationPath.SiteName, 
                           Connection.ConfigurationPath.ApplicationPath +
                           Connection.ConfigurationPath.FolderPath
                    );
    
                section = config.GetSection("system.webServer/imageCopyright");
                section.GetAttribute("color").Value = (object)color;
                section.GetAttribute("message").Value = (object)message;
                section.GetAttribute("enabled").Value = (object)featureenabled;
    
                mgr.CommitChanges();
    
                }
    
                catch
                {}
    
            }
    
            public void UpdateVariables()
            {
                featureenabled = _enabledCB.Checked;
                color = _colCombo.Text;
                message = _msgTB.Text;
            }
    
            public void ReadConfig()
            {
                try
                {
                    ServerManager mgr;
                    ConfigurationSection section;
                    mgr = new ServerManager();
                    Configuration config =
                    mgr.GetWebConfiguration(
                           Connection.ConfigurationPath.SiteName,
                           Connection.ConfigurationPath.ApplicationPath +
                           Connection.ConfigurationPath.FolderPath);
    
                    section = config.GetSection("system.webServer/imageCopyright");
                    color = (string)section.GetAttribute("color").Value;
                    message = (string)section.GetAttribute("message").Value;
                    featureenabled = (bool)section.GetAttribute("enabled").Value;
    
                }
    
                catch
                {}
    
            }
        }
    }
    

    Obwohl es viel gibt, erledigt dieser Code nicht mehr als ein paar Steuerelemente auf der ModulePage und liest und schreibt in den IIS-Konfigurationsspeicher.

Lesen der Konfiguration

Die ReadConfig-Funktion verwendet die gleichen Microsoft.Web.Administration-Schnittstellen, um den IIS-Konfigurationsspeicher zu öffnen. Die Benutzeroberfläche selbst stellt den Bereich bereit, in dem die Konfigurationseinstellungen angewendet werden.

Beispiel:

Connection.ConfigurationPath.SiteName,

Connection.ConfigurationPath.ApplicationPath+

Connection.ConfigurationPath.FolderPath

Konfiguration wird gespeichert

Die Konfiguration wird gespeichert, wenn auf die Schaltfläche "Übernehmen" geklickt wird (applyClick-Funktion). Die Änderungen, die an der UI-Übertragung in die Abschnittsattribute vorgenommen wurden, und der Abschnitt speichert auf dem Datenträger.

section.GetAttribute("enabled").Value = (object)featureenabled;

mgr.CommitChanges();

An diesem Punkt können Sie alles erneut mithilfe von "Projektmappe erstellen" aus dem Menü "Erstellen" kompilieren. Dadurch wird das Assembly imageCopyrightUI erstellt und in den globalen Assemblycache eingefügt.

Modulregistrierung

Das Benutzeroberflächenmodul ist erstellt, aber wir müssen die IIS-Verwaltungskonsole dennoch anweisen, es zu laden. Gehen Sie dazu wie folgt vor:

  • Abrufen des starken Namens des Ui-Moduls aus dem globalen Assemblycache
  • Hinzufügen des starken Namens und Typs zur Konfigurationsdatei der IIS-Verwaltungskonsole. Dies führt dazu, dass die IIS-Verwaltungskonsole den Typ beim Start lädt
  • Aktivieren des Moduls in der Benutzeroberflächenmodulliste

Schritte

  1. Öffnen oder verwenden Sie eine vorhandene Befehlsshell mit erhöhten Rechten, und registrieren Sie die Visual Studio 8.0-Umgebungsvariablen, indem Sie den folgenden Befehl ausführen:

    "%vs80comntools%\vsvars32.bat
    
  2. Run GacUtil

    GACUTIL /l imageCopyrightUI
    
  3. Öffnen Sie %windir%\system32\inetsrv\config\administration.config und fügen Sie es direkt hinter dem <moduleProviders> Eintrag hinzu:

    <add name="imageCopyrightUI" type="IIS7Demos.imageCopyrightUIProvider, IIS7Demos, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3fd9bd5e992ee757"/>
    

Das Ergebnis

Die Aufgabe ist abgeschlossen. Sehen Sie sich die Ergebnisse an.

Öffnen Sie die IIS-Verwaltungskonsole, und navigieren Sie zur /mypictures-Anwendung.

Doppelklicken Sie auf den Eintrag "Bild Copyright".

Screenshot of I I S Management Console with my pictures application selected and image Copyright message displayed.
Abbildung 8: Bild-Copyright-Benutzeroberfläche

Ändern Sie die Copyrightnachricht, klicken Sie auf "Anwenden", und aktualisieren Sie Ihren Browser. Die Copyright-Nachricht wurde geändert. Sehen Sie sich die Datei "web.config" im %systemdrive%\inetpub\mypictures Verzeichnis an, um die geänderte Konfiguration anzuzeigen.

Zusammenfassung

IIS ist auf Arten erweiterbar, die zuvor nicht möglich waren. Sie können die IIS-Kernverarbeitungspipeline mit Ihrer eigenen Komponente erweitern, die Konfiguration für diese Komponente zusammen mit der IIS-Konfiguration speichern und sogar ein Benutzeroberflächen-Plug-In schreiben, das sich parallel mit den Standardeinstellungen von IIS befindet. So überprüfen Sie, was wir im vorherigen Beispiel getan haben:

IIS Core Extensibility

Wir haben dem IIS-Kern einen Bildhandler hinzugefügt, der eine Copyrightnachricht in jede .JPG Datei einfügt, die bereitgestellt wird. Dies wurde mit nur wenigen Zeilen C#-Code erreicht. Die Funktionalität des Handlers war konfigurationsgesteuert. Wir haben die Konfiguration in den regulären IIS-Konfigurationsdateien applicationhost.config und web.config gespeichert. Wir haben auch Unterstützung für die Zwischenspeicherung für die Bilder hinzugefügt.

IIS-Konfigurationssystemerweiterung

Wir haben die Image Copyright-Handlerkonfiguration zum IIS-Konfigurationssystem hinzugefügt. Vorteile wie ein hochlesbarer und XML-Speicher, sofortige API- und Befehlszeilenunterstützung, Delegierung und verteilte Bereitstellungen waren kostenlos. Wir mussten keine einzelne Codezeile schreiben.

Erweiterbarkeit der IIS-Benutzeroberfläche

Um unserem Feature die Sichtbarkeit zu verleihen, die es verdient, haben wir ein IIS-Benutzeroberflächenmodul hinzugefügt. Obwohl nicht angezeigt, ist die IIS-Benutzeroberfläche über HTTPS vollständig remotable.