Ce post a pour but de présenter la manière dont je travaille au quotidien sur mes projets SharePoint, qui s'appuie sur l'outil WSPBuilder (la version en ligne de commande).
Il fait suite à un projet de démonstration que j'ai réalisé avec Visual Studio 2005 dans le cadre d'une formation sur le développement SharePoint. Il contient quelques features et peut servir de modèle lors du démarrage d'un projet SharePoint. Je le propose donc au téléchargement : DemoWSP.zip
Un projet SharePoint qui se respecte doit être livré sous la forme d'un SharePoint Solution Package, afin de pouvoir être déployé sur une ferme SharePoint par son administrateur.
Si on attend la fin du développement avant de s'intéresser au packaging, on risque d'aboutir à un refactoring couteux en temps, une solution en forme de plat de spaghettis, et une facture d'aspirines salée.
Alors que si on pense dès le début du projet à la problématique du packaging, la solution sera plus propre, et on gagnera en temps de développement et de maintenance. C’est là qu’intervient la magie de WSPBuilder, outil open source permettant d'automatiser le packaging d'un développement SharePoint.
L'avantage principal de WSPBuilder par rapport aux extensions Visual Studio pour WSS (qui de manière transparente génèrent un package et le déploient à chaque fois qu’on presse F5) est que le développeur exerce un réel contrôle sur la structure et le contenu de son package. De plus, ce modèle permet le déploiement de fichiers dans des répertoires non supportés par les extensions visual studio pour WSS: 12\Resources, 12\TEMPLATE\LAYOUTS, 12\TEMPLATE\IMAGES, etc.
Bien que WSPBuilder soit indépendant de Visual Studio (dans sa version en ligne de commande), la manière la plus pratique de l'utiliser est de créer un projet vide dans Visual Studio (qu'on appellera projet de packaging) dans lequel on créé 3 répertoires :
- un répertoire "12" qui aura la même structure de sous répertoire que celle du répertoire 12 de SharePoint,
- un répertoire "GAC" dans lequel iront les assemblii à déployer dans le GAC,
- et un répertoire "80" dans lequel iront les fichiers à déployer dans les répertoires des web applications.
Chacun de ces répertoires est optionnel, mais dans la majorité des cas on aura besoin des répertoires "12" et "GAC". Il suffit alors d'exécuter WSPBuilder.exe dans le répertoire du projet de packaging pour générer le package .wsp.
Note : Il est conseillé de renommer le package en .cab et de vérifier son contenu, car il peut arriver que WSPBuilder ne produise pas le résultat attendu. Il faut alors utiliser la méthode traditionnelle : création manuelle du .ddf et manifest.xml. Cela m'est arrivé une seule fois, c'est donc très rare, d’ailleurs je pense que le problème a été corrigé dans une des dernières versions de l’outil.
De par la simplicité d'utilisation de WSPBuilder, il n'est pas rare de trouver en entreprise des projets qui l'exécutent directement dans le build-event du projet.
Cela a deux avantages :
- après chaque compilation, un package à jour est généré et il suffit de le déployer via STSADM pour le tester.
- Si on travaille avec Team System, Il suffit dans le team build d'indiquer la solution cible pour que le package .wsp soit généré à chaque compilation, sans paramétrage supplémentaire. Ca, c’est génial.
Malheureusement, en phase de développement il y a de sérieux désavantages :
- Chaque compilation déclenche une génération du package ce qui prend beaucoup plus de temps
- Il faut ensuite déployer le package via STSADM ce qui prend aussi pas mal de temps
Je vais présenter ici la manière dont je travaille, qui permet d'optimiser le temps d'attente entre le moment de la compilation du projet et le moment où on en apprécie le résultat dans son navigateur web, tout en bénéficiant des avantages de WSPBuilder.
L'idée est de faire un déploiement "manuel" en phase de développement pour minimiser le temps d'attente, et de n'utiliser WSPBuilder que lors d'une compilation en mode Release (pour les team builds, et de temps en temps pendant la phase de développement pour ne pas avoir à modifier le fichier web.config de la web application à la main).
Ce modèle requiert un temps de préparation pour organiser la solution et créer les scripts au début du projet, mais le gain de productivité pour la suite est appréciable. Les temps d'attentes entre les déploiements et les tests seront réduit au strict minimum.
 |
La solution Visual Studio comprendra 3 projets de type class library :
- DemoWSP : Le projet de packaging qui servira de structure de répertoires conforme à ce qu'attend WSPBuilder. Il contient les fichiers à déployer dans répertoire 12 (features, resources, etc.), un répertoire GAC et un répertoire 80. - DemoGAC qui produit une assembly signée (contenant le code applicatif), vouée à être déployée dans le GAC. - Demo80 qui produit une assembly non signée (contenant le code des web parts), vouée à être déployée dans le répertoire bin de la web application.
Afin de s'assurer que notre projet pourra être compilé sur un serveur TFS, on prévoit un répertoire Lib dans le répertoire de notre solution, on y place les assemblii SharePoint, et on les référence dans nos projets à partir de ce répertoire Lib. On devra aussi installer WSPBuilder sur le serveur TFS dans le même répertoire que sur nos machines virtuelles de développement (ou le mettre lui aussi dans le répertoire Lib).
A gauche, une capture d’écran de la structure de ma solution.
Le projet de packaging dispose d'un build-event qui appelle CreatePackage.bat lors d'une compilation en mode Release :

|
En phase de développement, j'utilise deux scripts situés à la racine du projet de packaging:
- QuickDeploy.bat qui effectue un déploiement complet, copiant chaque fichier au bon endroit et recyclant ma pool d'application. Il met environ 1 seconde à s'exécuter, énorme gain comparé à la méthode consistant à générer puis déployer le package.
- HiveDeploy.bat qui copie uniquement les fichiers du répertoire 12, ne nécessitant pas le recyclage de ma pool d'application. L’exécution étant instantanée, ce script est très utile lorsque l'on effectue une modification sur une page .aspx par exemple, on peut la tester immédiatement car l’application n’a pas besoin d'être redémarrée.
HiveDeploy.bat
Ici, on tire le meilleur parti de WSPBuilder car on profite du fait que la structure de répertoires attendue correspond exactement à celle du répertoire 12. Il suffit de copier notre répertoire 12 dans celui de SharePoint.
@echo off
@SET SPDIR="c:\program files\common files\microsoft shared\web server extensions\12"
cls
ECHO.
Echo ================= Copying files to 12 directory ====================
ECHO.
xcopy /e /y /q 12\* %SPDIR%
ECHO.
QuickDeploy.bat
De même, on copie notre 12 dans le 12 de SharePoint, ensuite on installe chaque assembly dans son répertoire cible. Enfin, on recycle le pool d'application que l'on utilise pour nos tests.
@echo off
@SET SPDIR="c:\program files\common files\microsoft shared\web server extensions\12"
@SET GACUTIL="C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe"
cls
ECHO.
Echo ================= Copying files to 12 directory ====================
ECHO.
xcopy /e /y /q 12\* %SPDIR%
ECHO.
Echo =================== Installing assemblies to GAC ===================
ECHO.
%GACUTIL% /uf "DemoGAC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=53439e9aa159f9fe" /silent
%GACUTIL% -if ..\DemoGAC\bin\debug\DemoGAC.dll
ECHO.
echo ========== Installing assemblies in Web Application's bin ==========
ECHO.
xcopy /e /y /q ..\Demo80\bin\debug\Demo80.dll "C:\Inetpub\wwwroot\wss\VirtualDirectories\80\bin\"
ECHO.
Echo ================== Recycling Application Pools =====================
ECHO.
cscript C:\WINDOWS\System32\iisapp.vbs /a "SharePoint - 80" /r
ECHO.
Ce qui donne a l’écran :
CreatePackage.bat
On récupère les assemblii provenant de nos 2 autres projets, puis on exécute WSPBuilder afin que le package .wsp soit généré.
@echo off
@SET WSPBUILDER="M:\Utilitaires\WSPBuilder\WSPBuilder.exe"
cls
ECHO ================== Updating solution directory =====================
ECHO.
REM deleting bin directory to make sure WSPBuilder won't include unnecessary assemblies in the package
rd .\bin /s /q
copy ..\Demo80\bin\release\Demo80.dll .\80\bin\
copy ..\DemoGAC\bin\release\DemoGAC.dll .\GAC\
ECHO.
ECHO ================== Building package with WSPBuilder ===================
%WSPBUILDER% -WSPName DemoWSPBuilder.wsp -DLLReferencePath ..\Lib\
ECHO.
Pour s’assurer que les assemblii soient compilés avant l’appel à CreatePackage.bat, il faut aussi faire attention à ce que le projet de packaging soit "compilé" en dernier en paramétrant le build-order de la solution. Pour ce faire, on déclare une dépendance de DemoWSP sur les 2 autres projets :
Remarques :
- WSPBuilder génère automatiquement toutes les policies et balises SafeControl nécessaires, un autre avantage de l’outil. Lorsque c’est nécessaire, pendant la phase de développement, on peut donc déployer le package généré pour éviter d’avoir à faire ces modifications à la main dans le fichier web.config.
- Ce modèle de travail peut être étendu aux solutions utilisant le pattern MVP, moyennant quelques modifications des scripts .bat.
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :