Il arrive fréquemment, que lors de vos développements, vous deviez interagir avec un dossier relatif à IIS. Effectivement, comme vous le savez, SharePoint utilise des dossiers "à lui" contenus principalement dans le dossier 12. Cependant, SharePoint utilise également beaucoup de fonctionnalités relatives à l'ASP.NET et ayant souvent attrait à IIS lui même, donc au dossier C:\inetpub\wwwroot\wss\VirtualDirectories. Dans ce dossier se trouvent d'autres dossiers contenant chacun les site collections de SharePoint.
Les exemples ne manquent pas pour illustrer la problématique. Par exemple, si vous écrivez un "Control Adapter", vous devrez déployer un fichier .browser dans le dossier App_Browsers d'IIS. Si vous utilisez des ressources dans une de vos pages applicatives et que vous voulez les utiliser directement dans le code ASP de cette page, vous devrez les déployer dans le dossier App_GlobalResources,...
Pour faire tout cela, il existe une fonction qui se nomme ApplyApplicationContentToLocalServer. Cette fonction s'exécute au niveau de la ferme et possède certain désavantage. Effectivement, celle-ci est prévu pour fonctionner exclusivement de la manière dont elle a été programmée, donc elle gère les fichiers ressources, les fichiers de sitemap mais, je ne pense pas qu'elle gère les fichiers .browser. D'un manière générale, cette fonction s'exécute sans nous permettre d'interagir sur la manière dont les fichiers seront copiés,... En plus, les fichiers seront copiés dans TOUS les dossiers d'IIS, ce qui n'est pas toujours le comportement désiré.
Il existe une alternative permettant d'accéder au dossier d'IIS et qui plus est, ne nécessite qu'une feature de Web Application et non une feature de ferme. Nous allons voir cela par un simple exemple. Cette feature sera un event handler de feature permettant simplement d'exécuter la copie de certains fichiers dans les répertoires adéquat d'IIS. Pour cela, commencez par créer un projet WSP Builder vide à l'aide de Visual Studio 2008. Nous allons ensuite ajouter une feature de Web Application. Pour cela, cliquez avec le bouton droit de votre souris sur votre projet choisissez Add > New Item. Dans la partie gauche de la fenêtre, choisissez WSP Builder et Blank feature dans la partie de droite. Nommez cette feature WebAppCopy.
Dans la fenêtre qui apparait ensuite, remplissez les champs de cette manière :
Ici, étant donné que notre feature ne fera rien, il n'est pas utile de garder le fichier elements.xml, supprimez le donc du dossier de votre feature. Ouvrez ensuite le fichier feature.xml pour supprimer la référence au fichier que nous venons de supprimer. Modifiez donc ce passage :
Pour qu'il ne devienne que :
Nous allons maintenant ajouter un event handler à cette feature pour exécuter du code à son activation. Cliquez donc avec le bouton droit de votre souris sur votre projet et choisissez Add > Class et nommez cette classe WebAppCopy.cs. Avant de continuer, nous allons devoir ajouter une référence à SharePoint pour le projet. Cliquez donc avec le bouton droit sur le dossier References de votre projet et choisissez Add Reference. Dans la liste qui apparaît, choisissez Windows SharePoint Services et validez votre choix. Avant de continuer, nous allons créer des fichiers "factices" à déployer dans les répertoires d'IIS. Ceux ci ne serviront à rien d'autre que de montrer que le déploiement a fonctionné. Créez donc un dossier que vous appellerez "Files" dans le dossier de votre feature. Dans ce fichier, ajoutez deux fichiers texte que vous nommerez "file1.txt" et "file2.txt". Rentrez ce que vous désirez dans ces fichiers.
Ouvrez ensuite le fichier .cs que vous venez de créer. La première chose à faire est d'ajouter les directives suivantes :
La deuxième chose à faire est de permettre à notre classe de surcharger les fonctions de l'activation d'une feature. Pour cela, faites la dériver de la classe SPFeatureReceiver et surchargez les 4 méthodes de cette classe :
Ici, nous ne surchargerons que les deux premières méthodes, c'est à dire l'activation et la désactivation de la feature. Commençons d'abord par la fonction FeatureActivated et tapez :
Vous allez voir, ce n'est pas très compliqué. Tout d'abord, nous récupérons une référence vers l'objet SPWebApplication identifiant la Web Application sur laquelle la feature est activée. Effectivement, la feature étant "scopée" au niveau de la Web Application, la propriété Parent de cette feature contiendra une référence à cette Web Application. Étant donné qu'il existe 4 scopes différents, nous sommes obligés de caster cette propriété.
Tout d'abord, nous faisons une simple vérification pour voir si la Web Application n'est pas nulle. Si c'est le cas, nous itérons sur le contenu de la collection Keys de la propriété IisSettings de l'objet référençant la Web Application. Dans la boucle, nous récupérons l'objet SPIisSettings courant. Pour cela, nous faisons passer la clé courante dans la collection IisSettings. Un objet de type SPIisSettings contient plusieurs propriétés permettant d'en savoir plus sur IIS, ici, nous n'utiliserons qu'une seule de ces propriétés.
Les 6 lignes suivantes servent à copier les deux fichiers dans les répertoires adéquats d'IIS. Nous n'expliquerons que les 3 premières étant donné que les 3 suivantes sont les mêmes, mais copient l'autre fichier dans un dossier différent d'IIS. La première ligne permet de constituer le chemin d'accès vers le premier fichier à copier. Effectivement, il ne suffit pas de taper son nom. Ici, la subtilité est de récupérer le chemin d'accès vers le dossier TEMPLATE de SharePoint. Pour cela, nous utilisons la fonction GetGenericSetupPath de la classe SPUtility. Nous faisons passer en paramètre le nom du dossier que nous voulons récupérer et cette fonction nous renvoie le chemin d'accès vers ce dossier. Nous concaténons ce chemin d'accès avec le reste de l'emplacement du fichier "file1.txt". La deuxième ligne va nous permettre de constituer la destination du fichier, c'est donc ici que nous allons récupérer le chemin d'accès vers le dossier courant du dossier IIS. Comme vous le voyez, nous utilisons la propriété Path de l'objet SPIisSettings.
Effectivement, la collection IisSettings va contenir une référence à tous les dossiers IIS relatifs à la Web Application. Donc dans le cas où 2 site collections sont attachées à la même Web Application, nous sommes obligé de boucler sur la collection pour copier les fichiers dans les deux dossiers. Une fois que nous avons la source et la destination, il nous suffit de faire passer ces deux paramètres dans la fonction Copy de la classe statique File. Le troisième argument définit si les fichiers seront écrasés ou non, nous la mettons donc à true pour être sûr que les fichiers soient les bons dans le cas d'une mise à jour. Comme vous le voyez, ce n'est vraiment pas très compliqué.
La fonction FeatureDeactivated va être du même acabit à l'exception près qu'ici, il ne faudra plus copier, mais supprimer les fichiers. Tapez donc dans cette fonction :
Comme vous voyez, ici, nous faisons exactement la même chose, mais nous appelons la fonction Delete de la classe File pour supprimer les deux fichiers que la Web Application feature déploie. A ce stade il manque encore quelque chose à votre feature. Effectivement, nous n'avons pas fait le lien entre votre fichier de définition de la feature et votre code. Compilez donc votre projet et récupérez en la signature grâce à Reflector (vu dans la partie Matériel de ce site). Ouvrez ensuite votre fichier feature.xml et rajoutez ces deux attributs à l'élément Feature :
Ceci sert à faire le lien entre l'activation de votre feature et le code que vous venez de taper. Bien évidemment, vous devez remplacer [Signature] par la signature de la assembly récupérée grâce à Reflector. Si vous n'avez pas nommé votre classe et votre namespace de la même façon que dans ce tutoriel, vous devrez également modifier quelque peu l'attribut ReceiverClass.
Compilez et déployez maintenant votre feature. Une fois ceci fait, ouvrez votre centrale d'administration et allez dans Application Management > Manage web application features. Dans la fenêtre qui apparaît, sélectionnez la Web Application sur laquelle vous voulez déployer vos fichiers dans la liste de choix en haut à droite de la liste des features. Une fois ceci fait, cliquez sur Activate pour activer votre feature. Ensuite, allez dans les répertoire d'IIS et vérifiez que les fichiers s'y trouvent bien. Désactivez alors votre feature et vous remarquerez que les deux fichiers auront disparu.
Plus de tutoriel sur AreaProg et Développez
Les exemples ne manquent pas pour illustrer la problématique. Par exemple, si vous écrivez un "Control Adapter", vous devrez déployer un fichier .browser dans le dossier App_Browsers d'IIS. Si vous utilisez des ressources dans une de vos pages applicatives et que vous voulez les utiliser directement dans le code ASP de cette page, vous devrez les déployer dans le dossier App_GlobalResources,...
Pour faire tout cela, il existe une fonction qui se nomme ApplyApplicationContentToLocalServer. Cette fonction s'exécute au niveau de la ferme et possède certain désavantage. Effectivement, celle-ci est prévu pour fonctionner exclusivement de la manière dont elle a été programmée, donc elle gère les fichiers ressources, les fichiers de sitemap mais, je ne pense pas qu'elle gère les fichiers .browser. D'un manière générale, cette fonction s'exécute sans nous permettre d'interagir sur la manière dont les fichiers seront copiés,... En plus, les fichiers seront copiés dans TOUS les dossiers d'IIS, ce qui n'est pas toujours le comportement désiré.
Il existe une alternative permettant d'accéder au dossier d'IIS et qui plus est, ne nécessite qu'une feature de Web Application et non une feature de ferme. Nous allons voir cela par un simple exemple. Cette feature sera un event handler de feature permettant simplement d'exécuter la copie de certains fichiers dans les répertoires adéquat d'IIS. Pour cela, commencez par créer un projet WSP Builder vide à l'aide de Visual Studio 2008. Nous allons ensuite ajouter une feature de Web Application. Pour cela, cliquez avec le bouton droit de votre souris sur votre projet choisissez Add > New Item. Dans la partie gauche de la fenêtre, choisissez WSP Builder et Blank feature dans la partie de droite. Nommez cette feature WebAppCopy.
Dans la fenêtre qui apparait ensuite, remplissez les champs de cette manière :
Ici, étant donné que notre feature ne fera rien, il n'est pas utile de garder le fichier elements.xml, supprimez le donc du dossier de votre feature. Ouvrez ensuite le fichier feature.xml pour supprimer la référence au fichier que nous venons de supprimer. Modifiez donc ce passage :
<ElementManifests>
<ElementManifest Location="elements.xml" />
</ElementManifests>
<ElementManifest Location="elements.xml" />
</ElementManifests>
Pour qu'il ne devienne que :
<ElementManifests />
Nous allons maintenant ajouter un event handler à cette feature pour exécuter du code à son activation. Cliquez donc avec le bouton droit de votre souris sur votre projet et choisissez Add > Class et nommez cette classe WebAppCopy.cs. Avant de continuer, nous allons devoir ajouter une référence à SharePoint pour le projet. Cliquez donc avec le bouton droit sur le dossier References de votre projet et choisissez Add Reference. Dans la liste qui apparaît, choisissez Windows SharePoint Services et validez votre choix. Avant de continuer, nous allons créer des fichiers "factices" à déployer dans les répertoires d'IIS. Ceux ci ne serviront à rien d'autre que de montrer que le déploiement a fonctionné. Créez donc un dossier que vous appellerez "Files" dans le dossier de votre feature. Dans ce fichier, ajoutez deux fichiers texte que vous nommerez "file1.txt" et "file2.txt". Rentrez ce que vous désirez dans ces fichiers.
Ouvrez ensuite le fichier .cs que vous venez de créer. La première chose à faire est d'ajouter les directives suivantes :
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.IO;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Administration;
using System.IO;
using Microsoft.SharePoint.Utilities;
La deuxième chose à faire est de permettre à notre classe de surcharger les fonctions de l'activation d'une feature. Pour cela, faites la dériver de la classe SPFeatureReceiver et surchargez les 4 méthodes de cette classe :
public class WebAppCopy : SPFeatureReceiver
{
}
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties) {}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties) {}
{
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties) {}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties) {}
}
Ici, nous ne surchargerons que les deux premières méthodes, c'est à dire l'activation et la désactivation de la feature. Commençons d'abord par la fonction FeatureActivated et tapez :
SPWebApplication CurrentWebApp = properties.Feature.Parent as SPWebApplication;
if (CurrentWebApp != null)
{
}
else
if (CurrentWebApp != null)
{
foreach (SPUrlZone Zone in CurrentWebApp.IisSettings.Keys)
{
}
{
SPIisSettings CurrentSettings = CurrentWebApp.IisSettings[Zone];
string sourcePath = string.Format("{0}\FEATURES\WebAppCopy\Files\file1.txt", SPUtility.GetGenericSetupPath("Template"));
string destinationPath = Path.Combine(CurrentSettings.Path.ToString(), "App_GlobalResourcesfile1.txt");
File.Copy(sourcePath, destinationPath, true);
sourcePath = string.Format("{0}\FEATURES\WebAppCopy\Files\file2.txt", SPUtility.GetGenericSetupPath("Template"));
destinationPath = Path.Combine(CurrentSettings.Path.ToString(), "_app_binfile2.txt");
File.Copy(sourcePath, destinationPath, true);
string sourcePath = string.Format("{0}\FEATURES\WebAppCopy\Files\file1.txt", SPUtility.GetGenericSetupPath("Template"));
string destinationPath = Path.Combine(CurrentSettings.Path.ToString(), "App_GlobalResourcesfile1.txt");
File.Copy(sourcePath, destinationPath, true);
sourcePath = string.Format("{0}\FEATURES\WebAppCopy\Files\file2.txt", SPUtility.GetGenericSetupPath("Template"));
destinationPath = Path.Combine(CurrentSettings.Path.ToString(), "_app_binfile2.txt");
File.Copy(sourcePath, destinationPath, true);
}
}
else
throw new ApplicationException("The Web Application object is null.");
Vous allez voir, ce n'est pas très compliqué. Tout d'abord, nous récupérons une référence vers l'objet SPWebApplication identifiant la Web Application sur laquelle la feature est activée. Effectivement, la feature étant "scopée" au niveau de la Web Application, la propriété Parent de cette feature contiendra une référence à cette Web Application. Étant donné qu'il existe 4 scopes différents, nous sommes obligés de caster cette propriété.
Tout d'abord, nous faisons une simple vérification pour voir si la Web Application n'est pas nulle. Si c'est le cas, nous itérons sur le contenu de la collection Keys de la propriété IisSettings de l'objet référençant la Web Application. Dans la boucle, nous récupérons l'objet SPIisSettings courant. Pour cela, nous faisons passer la clé courante dans la collection IisSettings. Un objet de type SPIisSettings contient plusieurs propriétés permettant d'en savoir plus sur IIS, ici, nous n'utiliserons qu'une seule de ces propriétés.
Les 6 lignes suivantes servent à copier les deux fichiers dans les répertoires adéquats d'IIS. Nous n'expliquerons que les 3 premières étant donné que les 3 suivantes sont les mêmes, mais copient l'autre fichier dans un dossier différent d'IIS. La première ligne permet de constituer le chemin d'accès vers le premier fichier à copier. Effectivement, il ne suffit pas de taper son nom. Ici, la subtilité est de récupérer le chemin d'accès vers le dossier TEMPLATE de SharePoint. Pour cela, nous utilisons la fonction GetGenericSetupPath de la classe SPUtility. Nous faisons passer en paramètre le nom du dossier que nous voulons récupérer et cette fonction nous renvoie le chemin d'accès vers ce dossier. Nous concaténons ce chemin d'accès avec le reste de l'emplacement du fichier "file1.txt". La deuxième ligne va nous permettre de constituer la destination du fichier, c'est donc ici que nous allons récupérer le chemin d'accès vers le dossier courant du dossier IIS. Comme vous le voyez, nous utilisons la propriété Path de l'objet SPIisSettings.
Effectivement, la collection IisSettings va contenir une référence à tous les dossiers IIS relatifs à la Web Application. Donc dans le cas où 2 site collections sont attachées à la même Web Application, nous sommes obligé de boucler sur la collection pour copier les fichiers dans les deux dossiers. Une fois que nous avons la source et la destination, il nous suffit de faire passer ces deux paramètres dans la fonction Copy de la classe statique File. Le troisième argument définit si les fichiers seront écrasés ou non, nous la mettons donc à true pour être sûr que les fichiers soient les bons dans le cas d'une mise à jour. Comme vous le voyez, ce n'est vraiment pas très compliqué.
La fonction FeatureDeactivated va être du même acabit à l'exception près qu'ici, il ne faudra plus copier, mais supprimer les fichiers. Tapez donc dans cette fonction :
SPWebApplication CurrentWebApp = properties.Feature.Parent as SPWebApplication;
if (CurrentWebApp != null)
{
}
else
if (CurrentWebApp != null)
{
foreach (SPUrlZone Zone in CurrentWebApp.IisSettings.Keys)
{
}
{
SPIisSettings CurrentSettings = CurrentWebApp.IisSettings[Zone];
File.Delete(Path.Combine(CurrentSettings.Path.ToString(), "_app_binfile2.txt"));
File.Delete(Path.Combine(CurrentSettings.Path.ToString(), "App_GlobalResourcesfile1.txt"));
File.Delete(Path.Combine(CurrentSettings.Path.ToString(), "_app_binfile2.txt"));
File.Delete(Path.Combine(CurrentSettings.Path.ToString(), "App_GlobalResourcesfile1.txt"));
}
}
else
throw new ApplicationException("The Web Application object is null.");
Comme vous voyez, ici, nous faisons exactement la même chose, mais nous appelons la fonction Delete de la classe File pour supprimer les deux fichiers que la Web Application feature déploie. A ce stade il manque encore quelque chose à votre feature. Effectivement, nous n'avons pas fait le lien entre votre fichier de définition de la feature et votre code. Compilez donc votre projet et récupérez en la signature grâce à Reflector (vu dans la partie Matériel de ce site). Ouvrez ensuite votre fichier feature.xml et rajoutez ces deux attributs à l'élément Feature :
ReceiverAssembly = "[Signature]"
ReceiverClass = "WebApplicationCopy.WebAppCopy"
ReceiverClass = "WebApplicationCopy.WebAppCopy"
Ceci sert à faire le lien entre l'activation de votre feature et le code que vous venez de taper. Bien évidemment, vous devez remplacer [Signature] par la signature de la assembly récupérée grâce à Reflector. Si vous n'avez pas nommé votre classe et votre namespace de la même façon que dans ce tutoriel, vous devrez également modifier quelque peu l'attribut ReceiverClass.
Compilez et déployez maintenant votre feature. Une fois ceci fait, ouvrez votre centrale d'administration et allez dans Application Management > Manage web application features. Dans la fenêtre qui apparaît, sélectionnez la Web Application sur laquelle vous voulez déployer vos fichiers dans la liste de choix en haut à droite de la liste des features. Une fois ceci fait, cliquez sur Activate pour activer votre feature. Ensuite, allez dans les répertoire d'IIS et vérifiez que les fichiers s'y trouvent bien. Désactivez alors votre feature et vous remarquerez que les deux fichiers auront disparu.
Plus de tutoriel sur AreaProg et Développez