Partager via


Comprendre la création d’extensions d’interface utilisateur

par Gurpreet Singh

Introduction

L’outil d’administration pour IIS 7.0 et versions ultérieures est une plateforme extensible permettant d’ajouter des modules. Les développeurs peuvent écrire leurs propres fonctionnalités d’interface utilisateur et seront traités comme citoyens de première classe par intemgr.

Cette procédure pas à pas montre comment créer un module d’interface utilisateur à partir de zéro. Il présente les meilleures pratiques de création d’un module suivies par l’équipe IIS.

La tâche consiste à créer deux assemblys. Le processus peut être résumé en deux étapes.

  • Création de l’assembly client
  • Création de l’assembly de serveur

Le nouvel inetmgr est conçu pour utiliser une architecture de type service web qui assure une séparation propre entre la logique de l’interface utilisateur et les paramètres du serveur manipulant le code. Cela se fait principalement par l’intermédiaire de deux classes, ModuleService et ModuleServiceProxy. La classe dérivée ModuleService est associée avec son ModuleProvider via la propriété ModuleProvider ServiceType.

Création d’une solution vide

Cliquez sur Démarrer, cliquez sur Programmes, puis exécutez Microsoft Visual Studio 2005 ou Microsoft Visual C# 2005 Express Edition. Dans le Menu Fichier, sélectionnez l’option Nouveau projet, accédez à Autres types de projets et Solutions Visual Studio. Sélectionnez Solution vide dans le côté droit et nommez la solution comme ExtensibilityDemo.

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

Création de l’assembly client

Les tâches illustrées pour créer un assembly client se composent de

  • Configuration du projet pour l’assembly client
  • Création d’un ModuleServiceProxy
  • Création d’un ModuleListPage et utilisation de ModuleServiceProxy.
  • Création d’une classe de module.

Configuration du projet pour l’assembly client

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur la solution, sélectionnez Ajouter et Nouveau projet pour lancer cette fenêtre. Sélectionnez Visual C# et bibliothèque de classes dans le volet droit et nommez le projet en tant que client.

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

Supprimez le fichier Class1.cs ajouté par défaut, car nous n’utiliserons pas ce fichier, à l’aide de l’option Supprimer dans le menu contextuel de l’Explorateur de solutions.

Utilisation d’Ajouter une référence... dans le menu Projet, ajoutez une référence à Microsoft.Web.Management.dll à l’aide de l’onglet Parcourir et recherchez le répertoire \Windows\system32\inetsrv. Il s’agit du répertoire qui contient les classes d’extensibilité pour la création de modules dans inetmgr. Étant donné que nous allons référencer certaines des classes de System.Windows.Forms, incluez donc également la référence à System.Windows.Forms.

Meilleure pratique : ne référencez jamais Microsoft.Web.Administration.dll à partir du projet client.

L’une des conditions requises pour que les bibliothèques puissent être utilisées dans l’InetMgr est qu’elles doivent être inscrites dans GAC. Pour cela, nous devons nous assurer que notre DLL dispose d’un nom fort. Visual Studio offre un moyen simple de créer de nouveaux noms. Pour signer un assembly, accédez aux Propriétés du projet et à l’onglet Signature, cliquez sur Signer l’assembly. Dans la boîte de dialogue, nommez la clé comme ExtensibilityDemoKey et décochez Protéger mon fichier de clé par un mot de passe.

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.

Appuyez sur OK pour signer l’assembly. Nous voulons également que l’assembly se trouve dans le GAC. Ainsi, nous ajouterons des événements post-build afin qu’il soit automatiquement ajouté au GAC chaque fois que nous compilons. Cela vous permettra de déboguer et d’apporter des modifications au fur et à mesure que nous ajoutons de nouvelles fonctionnalités. Pour cela, sélectionnez l’onglet Événements de build et ajoutez la ligne de commande Événement post-build suivante :

gacutil.exe /if "$(TargetPath)"

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

Enfin, fermez les propriétés du projet et sélectionnez l’option Enregistrer tout dans le menu Fichier. Vous pouvez désormais compiler le projet à l’aide de la Solution de build, dans le menu Build. Cela génère automatiquement la dll et l’ajoute au GAC.

Remarque : Si la commande permettant de définir vsvars32.bat ne fonctionne pas et retourne un code d’erreur 9009, vous pouvez également remplacer la commande ajoutée dans les événements Post Build en ajoutant le chemin complet à gacutil.exe. Par exemple :

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

Création du ModuleServiceProxy

Un ModuleServiceProxy est la classe qui simplifie le processus d’appel de méthodes dans la classe ModuleService. Cette classe est importante, car elle extrait la logique lors de l’administration d’un serveur local ou de l’administration d’un ordinateur distant à l’aide du Service de gestion Web (wmsvc).

Dans cet exemple, nous allons écrire le contenu en lecture de "appSettings". Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Sélectionnez le code et tapez DemoModuleServiceProxy comme nom de fichier.

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

Modifiez le code pour qu’il se présente comme suit.

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");
        }
    }
}

Comme nous pouvons le voir, l’écriture d’un proxy est une simple question d’écriture d’une classe dérivée de ModuleServiceProxy et d’appel des méthodes du ModuleService du côté du serveur.

Création d’un ModuleListPage

Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Sélectionnez le code et tapez DemoModuleListPage.cs comme nom de fichier.

Modifiez le code pour qu’il se présente comme suit.

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();
            }
        }
    }
}

Dans cette démonstration, nous étendons la classe ModuleListPage. Elle remplace la méthode InitializeListPage pour initialiser les colonnes et les ajouter à listview. Elle remplace également la méthode OnActivated. Cette méthode est appelée lors de l’accès à cette page

Création de la classe de modules

Il s’agit du point d’entrée du côté client pour tous les objets existants. Elle possède trois méthodes principales appelées Initialize, GetService et Dispose. Il s’agit de la méthode dans laquelle toutes les actions telles que l’inscription de page, l’affectation de catégorie à la page, etc. sont effectuées.

Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Sélectionnez le Code et tapez DemoModule.cs comme nom de fichier.

Modifiez le code pour qu’il se présente comme suit.

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 remplace la méthode Initialize. Il appelle d’abord Initialize sur la classe de base. Il accède ensuite au service Panneau de configuration via GetService. Il s’inscrit ensuite via RegisterPage du ControlPanel.

Création de l’assembly de serveur

L’assembly de serveur consiste à écrire deux classes principales

  • Fournisseur de modules
  • Service de modules

Le serveur doit également référencer deux assemblys principaux à partir du répertoire \Windows\System32\inetsrv appelés Microsoft.Web.Management.dll et Microsoft.Web.Management.Administration.dll. Le premier assembly se compose de toutes les classes de l’infrastructure de création de l’interface utilisateur pour intemgr, et le deuxième assembly se compose de classes pour la lecture et l’écriture de la configuration.

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur la solution, sélectionnez Ajouter et Nouveau projet pour lancer la fenêtre. Sélectionnez Visual C# et bibliothèque de classes dans le volet droit et nommez le projet en tant que Serveur.

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

Supprimez le fichier Class1.cs ajouté par défaut, car nous n’utiliserons pas ce fichier, à l’aide de l’option Supprimer dans le menu contextuel de l’Explorateur de solutions.

Utilisation d’Ajouter une référence... dans le menu Projet, ajoutez une référence à Microsoft.Web.Management.dll et Microsoft.Web.Management.Administration.dll à l’aide de l’onglet Parcourir et recherchez le répertoire \Windows\system32\inetsrv. Il s’agit du répertoire qui contient les classes d’extensibilité pour la création de modules dans inetmgr.

L’une des conditions requises pour que les bibliothèques puissent être utilisées dans l’InetMgr est qu’elles doivent être inscrites dans GAC. Pour cela, nous devons nous assurer que notre DLL dispose d’un nom fort. Visual Studio offre un moyen simple de créer de nouveaux noms. Pour signer un assembly, accédez aux Propriétés du projet et à l’onglet Signature, cliquez sur Signer l’assembly. Dans la liste déroulante, cliquez sur Parcourir. Dans la boîte de dialogue, accédez au dossier Client, puis sélectionnez l’ExtensibilityDemoKey, puis appuyez sur Ouvrir. Enregistrez les propriétés du projet.

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

Appuyez sur OK pour signer l’assembly. Nous voulons également que l’assembly se trouve dans le GAC. Ainsi, nous ajouterons des événements post-build afin qu’il soit automatiquement ajouté au GAC chaque fois que nous compilons. Cela vous permettra de déboguer et d’apporter des modifications au fur et à mesure que nous ajoutons de nouvelles fonctionnalités. Pour cela, sélectionnez l’onglet Événements de build et ajoutez la ligne de commande Événement post-build suivante :

gacutil.exe /if "$(TargetPath)"

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

Enfin, fermez les propriétés du projet et sélectionnez l’option Enregistrer tout dans le menu Fichier. Vous pouvez désormais compiler le projet à l’aide de la Solution de build, dans le menu Build. Cela génère automatiquement la dll et l’ajoute au GAC.

Remarque : Si la commande permettant de définir vsvars32.bat ne fonctionne pas et retourne un code d’erreur 9009, vous pouvez également remplacer la commande ajoutée dans les événements Post Build en ajoutant le chemin complet à gacutil.exe. Par exemple :

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

Création d’un service de module

Dans cette tâche, nous allons créer un nouveau ModuleService. Il s’agit de la classe qui utilise Microsoft.Web.Administration.dll pour lire ou écrire dans les fichiers de configuration sous-jacents.

Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Modèle de code et tapez DemoModuleService.cs comme nom du fichier.

Modifiez le code pour qu’il ressemble à ceci :

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

Création d’une classe AssemblyRef

Dans ce cas, vous allez créer une classe AssemblyRef. Cette classe sera référencée par moduleprovider pour instancier la classe de module.

Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Modèle de code et tapez DemoModuleProvider.cs comme nom du fichier.

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

Création d’un fournisseur de modules

Vous allez créer ici un fournisseur de modules. Il s’agit du point d’entrée principal pour l’inscription de modules dans InetMgr. Ces fournisseurs de modules sont répertoriés dans Administration.config.

Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Modèle de code et tapez DemoModuleProvider.cs comme nom du fichier.

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

Modifiez le code pour qu’il ressemble à ceci :

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

Ajout d’une entrée dans Administration.Config

Dans cette section, nous allons ajouter l’entrée dans administration.config dans la liste moduleProviders. Le nom complet de l’assembly se trouve dans le dossier \Windows\Assembly. Recherchez le client d’assembly et cliquez avec le bouton droit sur Propriétés.

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

Le nom complet de l’assembly peut être déterminé à partir de cette fenêtre. Par exemple, le nom complet de l’assembly dans mon cas est Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e788138af6131538. L’entrée qui doit être ajoutée à administration.config, dans moduleProviders serait

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

../ moduleProviders>

Remarque

En ajoutant cette entrée, ce module est inscrit uniquement pour les connexions serveur.

Générez la solution et exécutez inetmgr, et vous verrez les captures d’écran suivantes

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.

Résumé

Vous avez appris à utiliser le modèle d’extensibilité d’inetmgr et à créer votre propre page personnalisée. Dans les prochains articles, je parlerai également de la façon d’ajouter des taskItems et d’écrire dans les fichiers de configuration.