Freigeben über


Verstehen der Erstellung von UI-Erweiterungen

von Gurpreet Singh

Einführung

Das Verwaltungstool für IIS 7.0 und höher ist eine erweiterbare Plattform zum Anschließen von Modulen. Entwickler können ihre eigenen UI-Features schreiben und werden von intemgr als Bürger der ersten Klasse behandelt.

In dieser exemplarischen Vorgehensweise wird gezeigt, wie Sie ein Benutzeroberflächenmodul von Grund auf neu erstellen. Es zeigt die bewährten Methoden zum Erstellen eines Moduls, gefolgt von einem IIS-Team.

Die Aufgabe besteht aus dem Erstellen von zwei Assemblys. Der Prozess kann als zwei Schritte zusammengefasst werden.

  • Erstellen der Clientassembly
  • Erstellen der Serverassembly

Der neue inetmgr ist so konzipiert, dass er eine webdienstähnliche Architektur verwendet, die eine klare Trennung zwischen der Logik der Benutzeroberfläche und den Servereinstellungen zur Codemanipulation erzwingt. Dies geschieht hauptsächlich über zwei Klassen ModuleService und ModuleServiceProxy. Die abgeleitete ModuleService-Klasse wird mit seinem ModuleProvider über die ModuleProvider ServiceType-Eigenschaft abgeglichen.

Erstellen einer leeren Lösung

Klicken Sie erst auf Start, dann auf Programme, und führen Sie schließlich Microsoft Visual Studio 2005 oder Microsoft Visual C# 2005 Express Edition aus. Wählen Sie im Menü Datei die Option Neues Projekt aus, wechseln Sie zu Andere Projekttypen und Visual Studio-Lösungen. Wählen Sie auf der rechten Seite "Leere Lösung" aus, und nennen Sie die Lösung als ExtensibilityDemo.

Screenshot of New Project dialog box with Visual Studio Solutions as project type and Blank Solution as the template selected.

Erstellen der Clientassembly

Aufgaben zum Erstellen einer Clientassembly bestehen aus

  • Einrichten des Projekts für die Clientassembly
  • Erstellen eines ModuleServiceProxy
  • Erstellen einer ModuleListPage und Verwenden des ModuleServiceProxy.
  • Erstellen einer Modulklasse.

Einrichten des Projekts für die Clientassembly

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Projektmappe, wählen Sie "Hinzufügen" und "Neues Projekt" aus, um dieses Fenster zu starten. Wählen Sie Visual C# und Klassenbibliothek im rechten Bereich aus, und benennen Sie das Projekt als Client.

Screenshot of Add New Project window with Class Library selected and Client entered as project name in the Name field.

Entfernen Sie die Datei „Class1.cs“, die standardmäßig hinzugefügt wird (da wir diese Datei nicht verwenden), indem Sie im Projektmappen-Explorer im Kontextmenü die Option „Löschen“ verwenden.

Fügen Sie mithilfe... der Option Neue Referenz hinzufügen im Menü „Projekt“ einen Verweis auf Microsoft.Web.Management.dll hinzu, indem Sie die Registerkarte „Suchen“ verwenden und die DLL im Verzeichnis \Windows\system32\inetsrv suchen. Dies ist das Verzeichnis, das die Erweiterbarkeitsklassen zum Erstellen von Modulen in inetmgr enthält. Da wir auf einige der Klassen von System.Windows.Forms verweisen, schließen Sie auch Verweise auf System.Windows.Forms ein.

Bewährte Methode: Verweisen Sie niemals auf Microsoft.Web.Administration.dll aus dem Clientprojekt.

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. Visual Studio bietet eine einfache Möglichkeit zum Erstellen und Signieren neuer Namen. Um eine Assembly zu signieren, wechseln Sie zu Projekteigenschaften und zur Registerkarte Signieren, und klicken Sie auf Assembly signieren. Benennen Sie im Dialogfeld den Schlüssel als ExtensibilityDemoKey, und deaktivieren Sie das Kontrollkästchen Meine Schlüsseldatei mit einem Kennwort schützen.

Screenshot of Signing Tab and the dialog box with Extensibility Demo Key entered as the key file name.

Screenshot of Create Strong Name Key dialog box with Extensibility Demo Key displayed in Key file name field.

Drücken Sie OK, um die Assembly zu signieren. Da wir möchten, dass sich die Assembly im GAC befindet, werden wir außerdem einige Post-Build-Ereignisse hinzufügen, damit sie bei jeder Kompilierung automatisch zum 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 RegisterkarteBuild-Ereignisse aus, und fügen Sie die folgende Befehlszeile für das Post-Build-Ereignis hinzu:

gacutil.exe /if "$(TargetPath)"

Screenshot of Build Events tab showing Post build event command line populated with code.

Schließen Sie schließlich die Projekteigenschaften und wählen Sie die Option Alle speichern im Menü Datei aus. Sie können das Projekt jetzt mit „Lösung erstellen“ im Build-Menü kompilieren. Dadurch wird die DLL automatisch erstellt und dem GAC hinzugefügt.

Anmerkung: Wenn der Befehl zum Festlegen von „vsvars32.bat“ nicht funktioniert und den Fehlercode 9009 zurückgibt, können Sie den im Build-Ereignis hinzugefügten Befehl auch ersetzen, indem Sie den vollständigen Pfad zu „gacutil.exe“ hinzufügen, z. B.:

"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" /if "$(TargetPath)

Erstellen des ModuleServiceProxy

Ein ModuleServiceProxy ist die Klasse, die den Prozess des Aufrufens von Methoden in der ModuleService-Klasse vereinfacht. Diese Klasse ist wichtig, da sie die Logik abstrahiert, wenn sie einen lokalen Server verwaltet oder einen Remotecomputer mithilfe des Web Management Service(wmsvc) verwaltet.

In diesem Beispiel schreiben wir Leseinhalte von "appSettings". Wählen Sie im Menü „Projekt“ die Option „Neues Element hinzufügen“ aus. Wählen Sie den Code aus, und geben Sie "DemoModuleServiceProxy" als Dateinamen ein.

Screenshot of Add New Item dash Client dialog box showing Demo Module Service Proxy typed as the file name.

Ändern Sie den Code so, dass er so aussieht.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Server;

namespace Client {
    internal class DemoModuleServiceProxy : ModuleServiceProxy {
        public ArrayList GetAppSettings() {
            return (ArrayList )Invoke("GetAppSettings");
        }
    }
}

Wie wir sehen können, ist das Schreiben eines Proxys eine einfache Angelegenheit beim Schreiben einer Klasse, die von ModuleServiceProxy abgeleitet wird, und das Aufrufen von Methoden im ModuleService auf der Serverseite.

Erstellen einer ModuleListPage

Wählen Sie im Menü „Projekt“ die Option „Neues Element hinzufügen“ aus. Wählen Sie den Code aus, und geben Sie DemoModuleListPage.cs als Dateinamen ein.

Ändern Sie den Code so, dass er so aussieht.

using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using Microsoft.Web.Management.Client.Win32;
using Microsoft.Web.Management.Server;

namespace Client {
    internal class DemoModuleListPage : ModuleListPage {
        private ColumnHeader _keyColumnHeader;
        private ColumnHeader _valueColumnHeader;
        private DemoModuleServiceProxy _serviceProxy;

        private DemoModuleServiceProxy ServiceProxy {
            get {
                if (_serviceProxy == null) {
                    _serviceProxy = (DemoModuleServiceProxy)CreateProxy(typeof(DemoModuleServiceProxy));
                }
                return _serviceProxy;
            }
        }

        protected override void InitializeListPage() {
            _keyColumnHeader = new ColumnHeader();
            _keyColumnHeader.Text = "Key";
            _keyColumnHeader.Width = 200;

            _valueColumnHeader = new ColumnHeader();
            _valueColumnHeader.Text = "Value";
            _valueColumnHeader.Width = 200;

            ListView.Columns.Add(_keyColumnHeader);
            ListView.Columns.Add(_valueColumnHeader);
        }

        protected override void OnActivated(bool initialActivation) {
            base.OnActivated(initialActivation);
            if (initialActivation) {
                GetAppSettings();
            }
        }

        private void GetAppSettings() {
            StartAsyncTask("Getting Settings", new DoWorkEventHandler(GetSettings),
                                              new RunWorkerCompletedEventHandler(GetSettingsCompleted));
        }

        private void GetSettings(object sender, DoWorkEventArgs e) {
            e.Result = ServiceProxy.GetAppSettings();
        }

        private void GetSettingsCompleted(object sender, RunWorkerCompletedEventArgs e) {
            ListView.BeginUpdate();
            try {
                ArrayList settingsList = (ArrayList)e.Result;
                foreach (PropertyBag bag in settingsList) {
                    ListViewItem item = new ListViewItem();
                    item.Text = (string)bag[0];
                    item.SubItems.Add((string)bag[1]);

                    ListView.Items.Add(item);
                }
            }
            finally {
                ListView.EndUpdate();
            }
        }
    }
}

In dieser Demo erweitern wir die ModuleListPage-Klasse. Sie überschreibt die InitializeListPage-Methode, um die Spalten zu initialisieren und sie der Listenansicht hinzuzufügen. Außerdem wird die OnActivated-Methode außer Kraft gesetzt. Diese Methode wird aufgerufen, wenn auf diese Seite zugegriffen wird

Erstellen der Modulklasse

Dies ist der Einstiegspunkt für die Clientseite für alle vorhandenen Objekte. Es verfügt über drei Standard Methoden namens Initialize, GetService und Dispose. Dies ist die Methode, bei der alle Aktionen wie die Registrierung der Seite, das Zuweisen von Kategorie zu Seite usw. erfolgt.

Wählen Sie im Menü „Projekt“ die Option „Neues Element hinzufügen“ aus. Wählen Sie den Code aus, und geben Sie DemoModule.cs als Dateinamen ein.

Ändern Sie den Code so, dass er so aussieht.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Web.Management.Client;

namespace Client {
    internal class DemoModule : Module {
        protected override void Initialize(IServiceProvider serviceProvider, Microsoft.Web.Management.Server.ModuleInfo moduleInfo) {
            base.Initialize(serviceProvider, moduleInfo);

            IControlPanel controlPanel = (IControlPanel)GetService(typeof(IControlPanel));
            controlPanel.RegisterPage(new ModulePageInfo(this, typeof(DemoModuleListPage), "DemoPage"));
        }
    }
}

DemoModule überschreibt die Initialize-Methode. Zuerst wird die Initialize-Klasse aufgerufen. Anschließend wird über GetService auf den Systemsteuerungsdienst zugegriffen. Anschließend wird die Registrierung über RegisterPage von ControlPanel durchgeführt.

Erstellen der Serverassembly

Serverassembly besteht aus dem Schreiben von zwei Hauptklassen

  • Modulanbieter
  • Moduldienst

Der Server sollte auch auf zwei Haupt-Assemblys aus dem Verzeichnis \Windows\System32\inetsrv verweisen, die Microsoft.Web.Management.dll und Microsoft.Web.Management.Administration.dll genannt werden. Die erste Assembly besteht aus allen Frameworkklassen zum Erstellen der Benutzeroberfläche für intemgr und die zweite Assembly besteht aus Klassen für die Lesekonfiguration und die Schreibkonfiguration.

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Projektmappe, wählen Sie "Hinzufügen" und "Neues Projekt" aus, um das Fenster zu starten. Wählen Sie Visual C# und Klassenbibliothek im rechten Bereich aus, und benennen Sie das Projekt als Server.

Screenshot of Add New Project dialog box with Server typed in the Name field as the project name.

Entfernen Sie die Datei „Class1.cs“, die standardmäßig hinzugefügt wird (da wir diese Datei nicht verwenden), indem Sie im Projektmappen-Explorer im Kontextmenü die Option „Löschen“ verwenden.

Fügen Sie mithilfe... der Option Neue Referenz hinzufügen im Menü „Projekt“ einen Verweis auf Microsoft.Web.Management.dll und Microsoft.Web.Management.Administration.dll hinzu, indem Sie die Registerkarte Suchen verwenden und das Verzeichnis \Windows\system32\inetsrv suchen. Dies ist das Verzeichnis, das die Erweiterbarkeitsklassen zum Erstellen von Modulen in inetmgr enthält.

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. Visual Studio bietet eine einfache Möglichkeit zum Erstellen und Signieren neuer Namen. Um eine Assembly zu signieren, wechseln Sie zu Projekteigenschaften und zur Registerkarte Signieren, und klicken Sie auf Assembly signieren. Klicken Sie in der Dropdownliste auf "Durchsuchen". Wechseln Sie im Dialogfeld zum Clientordner, und wählen Sie ExtensibilityDemoKey aus, und drücken Sie "Öffnen". Speichern Sie die Projekteigenschaften.

Screenshot of Signing tab with the dialog box displaying the Extensibility Demo Key selected in the Client folder.

Drücken Sie OK, um die Assembly zu signieren. Da wir möchten, dass sich die Assembly im GAC befindet, werden wir außerdem einige Post-Build-Ereignisse hinzufügen, damit sie bei jeder Kompilierung automatisch zum 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 Registerkarte Build-Ereignisse aus, und fügen Sie die folgende Befehlszeile für das Post-Build-Ereignis hinzu:

gacutil.exe /if "$(TargetPath)"

Screenshot of dialog box with Post Build event command line populated with argument.

Schließen Sie schließlich die Projekteigenschaften und wählen Sie die Option Alle speichern im Menü Datei aus. Sie können das Projekt jetzt mit „Lösung erstellen“ im Build-Menü kompilieren. Dadurch wird die DLL automatisch erstellt und dem GAC hinzugefügt.

Anmerkung: Wenn der Befehl zum Festlegen von „vsvars32.bat“ nicht funktioniert und den Fehlercode 9009 zurückgibt, können Sie den im Build-Ereignis hinzugefügten Befehl auch ersetzen, indem Sie den vollständigen Pfad zu „gacutil.exe“ hinzufügen, z. B.:

"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" /if "$(TargetPath)"

Erstellen eines Moduldiensts

In dieser Aufgabe erstellen wir einen neuen ModuleService. Dies ist die Klasse, die Microsoft.Web.Administration.dll verwendet, um die zugrunde liegenden Konfigurationsdateien zu lesen oder zu schreiben.

Wählen Sie im Menü „Projekt“ die Option Neues Element hinzufügen aus. Wählen Sie im Dialogfeld "Neues Element hinzufügen" die Codevorlage aus, und geben Sie DemoModuleService.cs als Namen der Datei ein.

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

using System.Collections;
using Microsoft.Web.Administration;
using Microsoft.Web.Management.Server;

namespace Server {
    internal class DemoModuleService : ModuleService {

        [ModuleServiceMethod(PassThrough = true)]
        public ArrayList GetAppSettings() {

            ArrayList settingsList = new ArrayList();

            ConfigurationSection appSettingsSection =
                ManagementUnit.Configuration.GetSection(@"appSettings");
            ConfigurationElementCollection settingsCollection = appSettingsSection.GetCollection();

            foreach (ConfigurationElement element in settingsCollection) {
                PropertyBag bag = new PropertyBag();
                bag[0] = element.GetAttributeValue("key");
                bag[1] = element.GetAttributeValue("value");
                settingsList.Add(bag);
            }

            return settingsList;
        }
    }
}

Erstellen einer AssemblyRef-Klasse

Hier erstellen Sie eine AssemblyRef-Klasse. Auf diese Klasse wird vom Modulprovider verwiesen, um die Modulklasse zu instanziieren.

Wählen Sie im Menü „Projekt“ die Option Neues Element hinzufügen aus. Wählen Sie im Dialogfeld "Neues Element hinzufügen" die Codevorlage aus, und geben Sie DemoModuleProvider.cs als Namen der Datei ein.

using System.Reflection;

internal static class AssemblyRef {

    private static string client;

    internal static string Client {
        get {
            if (client == null) {
                AssemblyName assemblyName = typeof(AssemblyRef).Assembly.GetName();
                string assemblyFullName = assemblyName.FullName;
                client = assemblyFullName.Replace(assemblyName.Name, "Client");
            }

            return client;
        }
    }
}

Erstellen eines Modulanbieters

In dieser Aufgabe erstellen Sie einen Modulanbieter. Er ist der Haupteinstiegspunkt für die Registrierung von Modulen in InetMgr. Diese Modulanbieter werden in „Administration.config“ aufgeführt.

Wählen Sie im Menü „Projekt“ die Option Neues Element hinzufügen aus. Wählen Sie im Dialogfeld "Neues Element hinzufügen" die Codevorlage aus, und geben Sie DemoModuleProvider.cs als Namen der Datei ein.

Screenshot of Add New Item dialog box with Demo Module Provider dot c s typed as the name of the file.

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

using System;
using Microsoft.Web.Management.Server;

namespace Server {
    internal class DemoModuleProvider : ModuleProvider {
        public override ModuleDefinition GetModuleDefinition(IManagementContext context) {
            return new ModuleDefinition(Name, "Client.DemoModule," + AssemblyRef.Client);
        }

        public override Type ServiceType {
            get {
                return typeof(DemoModuleService);
            }
        }

        public override bool SupportsScope(ManagementScope scope) {
            return true;
        }
    }
}

Hinzufügen des Eintrags in "Administration.Config"

In diesem Abschnitt fügen wir den Eintrag in "administration.config" in der Liste "moduleProviders" hinzu. Den vollständigen Namen der Assembly finden Sie im Ordner \Windows\Assembly. Suchen Sie nach dem Assemblyclient, und klicken Sie mit der rechten Maustaste auf Eigenschaften.

Screenshot of Server Properties dialog box displaying full name of the assembly.

Der vollständige Name der Assembly kann aus diesem Fenster bestimmt werden. Beispielsweise lautet der vollständige Name der Assembly in meinem Fall Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e788138af6131538. Der Eintrag, der "administration.config" hinzugefügt werden soll, in "moduleProviders" wäre

<moduleProviders>
<..
<add name="DemoModule" type="Server.DemoModuleProvider,Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e788138af6131538"/>

../ moduleProviders>

Hinweis

Durch Hinzufügen dieses Eintrags ist dieses Modul nur für Serververbindungen registriert.

Erstellen Sie die Lösung, und führen Sie inetmgr aus, und Sie sehen die folgenden Screenshots

Screenshot of Internet Information Services I I S console with Actions menu displayed.

Screenshot of Internet Information Services I I S Demo Page with Actions menu for Help and Online Help displayed.

Zusammenfassung

Sie haben gelernt, wie Sie das Erweiterbarkeitsmodell von inetmgr verwenden und ihre eigene benutzerdefinierte Seite erstellen. In zukünftigen Artikeln werde ich auch darüber sprechen, wie taskItems hinzugefügt und in die Konfigurationsdateien geschrieben werden.