Cette documentation est archivée et n’est pas conservée.

Procédure : créer une classe de contenu qui peut être sauvegardée et restaurée

Windows SharePoint Services 3

Si vous avez un composant de contenu personnalisé que vous souhaitez inclure dans les sauvegardes et les restaurations Windows SharePoint Services 3.0, vous devez représenter le composant par une classe qui implémente l'interface IBackupRestore. Cette rubrique explique la procédure à suivre, avec un exemple complet pour l'illustrer.

Votre classe n'a pas à dériver de SPPersistedObject, mais si votre contenu est une base de données, il est recommandé que votre classe dérive de SPDatabase ou de SPContentDatabase. Ces deux classes sont dérivées de SPPersistedObject et implémentent toutes deux IBackupRestore. Par conséquent, vous aurez des implémentations par défaut de membres de IBackupRestore que vous pouvez utiliser si nécessaire.

Vous pouvez créer autant de types de classes IBackupRestore que vous le souhaitez ; elles peuvent être imbriquées sous la forme d'une arborescence de classes de composants. Mais la classe la plus élevée dans cette arborescence doit dériver (directement ou indirectement) de l'objet SPPersistedObject et doit être enfant de SPFarm. Si votre classe de contenu n'est pas enfant d'une autre classe personnalisée de contenu, elle doit dériver (directement ou indirectement) de l'objet SPPersistedObject et doit être enfant de SPFarm.

Si votre classe dérive d'une classe qui implémente déjà l'objet IBackupRestore (qui dérive ou non de SPPersistedObject) et que vous souhaitez remplacer une implémentation héritée d'un membre IBackupRestore, votre déclaration de classe doit référencer explicitement IBackupRestore comme suit :

public class MyClass : SPPersistedObject, IBackupRestore

Votre « remplacement » de tout membre IBackupRestore doit inclure explicitement IBackupRestore dans le nom du membre et ne pas inclure le mot clé public. Voici un exemple :

UInt64 IBackupRestore.DiskSizeRequired { ... }

Ou bien, si l'implémentation du membre dans la classe parente utilise le mot clé virtual ou override, vous pouvez utiliser le mot clé override dans votre implémentation comme suit :

public override UInt64 DiskSizeRequired { ... }
Cc264020.warning(fr-fr,office.12).gif Avertissement :

Ne masquez pas l'implémentation des membres hérités en redéclarant le membre avec ou sans le mot clé new ([new] public UInt64 DiskSizeRequired { ... }). Dans la procédure ci-dessous, les signatures de membre sont écrites comme elles le seraient pour une classe qui ne dérive pas d'une classe implémentant déjà IBackupRestore. Veillez à les modifier selon le modèle requis si votre classe dérive d'un tel parent.

Si votre classe dérive de SPPersistedObject, laissez les propriétés Microsoft.SharePoint.Administration.Backup.SPPersistedObject.Id et Microsoft.SharePoint.Administration.Backup.SPPersistedObject.Name de cette classe servir d'implémentation des propriétés Microsoft.SharePoint.Administration.Backup.IBackupRestore.Id et Microsoft.SharePoint.Administration.Backup.IBackupRestore.Name. Vous pouvez substituer les propriétés, mais n'en créez pas de seconde implémentation. Votre classe doit avoir un seul nom et une seule propriété Id.

Pour implémenter les membres de IBackupRestore

  1. Commencez un nouveau projet de classe dans Visual Studio.

  2. Ajoutez à votre projet Visual Studio une référence à Windows SharePoint Services et ajoutez des instructions using pour les espaces de noms Microsoft.SharePoint.Administration et Microsoft.SharePoint.Administration.Backup à votre fichier de classe.

  3. Si votre classe ne dérive pas de SPPersistedObject, implémentez la propriété Name. Elle servira de nom pour le composant de contenu dans l'interface utilisateur de stsadm.exe, l'application Administration centrale et l'interface utilisateur de toute application personnalisée de sauvegarde et de restauration. Dans la plupart des cas, vous implémentez la propriété en créant un champ privé pour la valeur du nom et implémentez la propriété publique en tant que wrapper du champ. Pour plus d'informations sur les diverses implémentations possibles, voir la rubrique de référence de la propriété.

    private String name;
    public String Name
    {
    get {return name;}
    set {name = value;}
    }
    
  4. Si votre classe ne dérive pas de SPPersistedObject, implémentez la propriété Id. Dans la plupart des cas, vous implémentez la propriété en créant un champ privé pour la valeur du nom et implémentez la propriété publique en tant que wrapper du champ. Pour plus d'informations sur les diverses implémentations possibles, voir la rubrique de référence de la propriété.

    private Guid id;
    public Guid Id
    {
    get {return id;}
    set {id = value;}
    }
    
  5. Implémentez la propriété DiskSizeRequired. Si votre classe est simplement conteneur de certaines classes IBackupRestore enfants, la propriété doit retourner 0. Sinon, la propriété doit calculer la taille du contenu. (Incluez la taille de tous les objets enfants non-IBackupRestore, mais pas celle des objets enfants IBackupRestore. Ils ont leur propre propriété DiskSizeRequired et Windows SharePoint Services 3.0 ajoutera ces valeurs automatiquement.) L'exemple suivant totalise les tailles de tous les fichiers dont les chemins d'accès sont contenus dans une collection appelée FrontEndFilePaths.

    public UInt64 DiskSizeRequired
    {
        get 
        {
            UInt64 total = 0;
            List<FileInfo> FrontEndFiles = new List<FileInfo>(NUMBER_OF_FILES_TO_BACK_UP);
            
            foreach (String path in FrontEndFilePaths)
            {
                FileInfo file = new FileInfo(path);
                FrontEndFiles.Add(file);
            }
            
            foreach (FileInfo file in FrontEndFiles)
            {
                total = total + (UInt64)file.Length;
            }
            
            return total;
        }
    } 
    
  6. Implémentez la propriété CanSelectForBackup. Si les utilisateurs ne doivent jamais pouvoir sauvegarder les objets de votre classe indépendamment d'une sauvegarde de l'objet parent, l'accesseur get doit retourner false. Si les utilisateurs doivent toujours être en mesure de sélectionner n'importe quel objet de votre classe pour une sauvegarde indépendante, l'accesseur get doit retourner true. Dans les deux cas, l'accesseur set doit être une paire d'accolades vide « {} ». Si certains objets de votre classe peuvent être sauvegardés indépendamment de leur parent, mais que pour d'autres ce soit impossible, implémentez la propriété en tant que wrapper d'un champ privé Boolean.

  7. Implémentez la propriété CanSelectForRestore. Si les utilisateurs ne doivent jamais pouvoir restaurer les objets de votre classe personnalisée de composant indépendamment d'une restauration de l'objet parent, l'accesseur get doit retourner false. Si les utilisateurs doivent toujours être en mesure de sélectionner n'importe quel objet de votre classe pour une restauration indépendante, l'accesseur get doit retourner true. Dans les deux cas, l'accesseur set doit être une paire d'accolades vide « {} ». Si certains objets de votre classe peuvent être restaurés indépendamment de leur parent, mais que pour d'autres ce soit impossible, implémentez la propriété en tant que wrapper d'un champ privé Boolean.

  8. Implémentez la propriété CanRenameOnRestore. Si les utilisateurs ne doivent jamais être en mesure de restaurer des objets de votre classe personnalisée de composant vers un nouvel emplacement, l'accesseur get doit retourner false. Si les utilisateurs doivent pouvoir effectuer la migration de n'importe quel objet de votre classe, l'accesseur get doit retourner true. Si les objets de votre classe peuvent parfois être migrés, mais pas toujours, implémentez la propriété en tant que wrapper d'un champ privé Boolean.

  9. Implémentez la méthode AddBackupObjects.

    1. Votre code d'implémentation doit commencer par lever une exception s'il n'existe aucun parent valide auquel le composant peut être ajouté.

    2. Utilisez la méthode AddChild pour ajouter votre composant à l'arborescence d'objets que l'opération de sauvegarde ou de restauration traitera.

    3. Utilisez la méthode SetParameter pour spécifier un nom de type et la description du composant qui peut être utilisé par l'interface utilisateur des applications de sauvegarde/restauration.

    4. Si le composant possède des objets enfants IBackupRestore, votre implémentation doit les parcourir et appeler de façon récursive la méthode AddBackupObjects de chacun.

    5. Voir la rubrique de référence sur la méthode AddBackupObjects pour plus d'informations sur les implémentations de celle-ci.

    L'exemple de code suivant suppose que votre classe de contenu a une ChildContentCollection d'objets enfants IBackupRestore. Si votre classe possède plus d'un type de composant enfant, vous pouvez avoir des collections distinctes pour chaque type et itérer dans chacune.

    public void AddBackupObjects(SPBackupRestoreObject parent)
    {
        if (parent == null)
        {
            throw new ArgumentNullException("parent");
        }
    
        SPBackupRestoreObject self = parent.AddChild(this);
        self.Information.SetParameter(SPBackupRestoreObject.SPTypeName, this.GetType());
        self.Information.SetParameter(SPBackupRestoreObject.SPDescription,
        "Description of custom content component");
    
        foreach (ChildContent child in ChildContentCollection)
        {
            IBackupRestore childIBR = child as IBackupRestore;
            childIBR.AddBackupObjects(self);
        }
    }
    
  10. Implémentez la méthode OnAbort. Elle doit toujours retourner true. Dans la plupart des cas, elle ne doit rien faire de plus, mais consultez la rubrique de référence sur OnAbort pour plus d'informations sur les exceptions à cette règle générale.

  11. Implémentez la méthode OnPrepareBackup. Au minimum, vous devez utiliser la méthode SetParameter pour spécifier le nom de l'objet de contenu. Au-delà de ça, quelques généralisations peuvent être effectuées. Voir la rubrique de référence sur OnPrepareBackup pour plus d'informations. L'exemple suivant illustre une implémentation minimale de la méthode, ce qui est souvent suffisant.

    public Boolean OnPrepareBackup(Object sender, SPBackupInformation args)
    {
        if (args == null)
        }
            throw new ArgumentNullException("args");
        }
        args.SetParameter(SPBackupRestoreObject.SPName, this.Name);
        return true;
    }
    
  12. Implémentez la méthode OnBackup. Si votre classe de contenu n'a aucun contenu à l'extérieur des objets enfants IBackupRestore qu'elle peut avoir, votre implémentation doit simplement définir une valeur pour CurrentProgess qui représente approximativement le pourcentage de la durée totale de l'opération de sauvegarde consommé par les méthodes OnBackup et OnPrepareBackup. Elle doit ensuite retourner true comme indiqué dans l'exemple suivant. N'appelez pas la méthode OnBackup d'un objet enfant IBackupRestore.

    public Boolean OnBackup(Object sender, SPBackupInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        args.CurrentProgress = 50;
        return true;
    }
    

    Si votre classe possède du contenu à l'extérieur des objets enfants IBackupRestore qu'elle peut avoir, votre implémentation doit copier ce contenu dans args.Location et retourner false si la copie échoue. Vous devez inclure une logique pour sauvegarder les objets enfants qui n'implémentent pasIBackupRestore, mais vous ne devez pas explicitement sauvegarder les objets enfants qui implémententIBackupRestore. Ils seront sauvegardés par leur propre méthode OnBackup, qui sera appelée à l'exécution. Vous ne devez pas appeler les méthodes OnBackup des objets enfants dans votre propre code. L'exemple suivant montre la structure globale d'une implémentation significative de OnBackup :

    public Boolean OnBackup(Object sender, SPBackupInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        args.CurrentProgress = 50;
        Boolean successSignal = true;
    
        // TODO: Implement copying your content to args.Location
        //       If the copy fails, set successSignal to false.
    
        return successSignal;
    }
    
  13. Implémentez la méthode OnBackupComplete. Au minimum, votre implémentation doit définir CurrentProgess à 100 % et retourner true comme indiqué dans l'exemple suivant. C'est en général tout ce qui est requis. Pour des informations à propos du travail supplémentaire que l'implémentation suscite, voir la rubrique de référence sur OnBackupComplete.

    public Boolean OnBackupComplete(Object sender, SPBackupInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        args.CurrentProgress = 100;
        return true;
    }
    
  14. Implémentez la méthode OnPreRestore. Dans la plupart des situations, une opération de restauration ne requiert aucune préparation et votre implémentation de OnPreRestore doit simplement retourner true. Pour des informations sur le travail supplémentaire que votre implémentation peut susciter, voir la rubrique de référence sur OnPreRestore.

  15. Implémentez la méthode OnRestore.

    • Si votre classe de contenu peut être migrée, votre code doit vérifier quelle est la méthode de restauration et appeler Rename si la méthode est New.

    • Si votre classe de contenu n'a aucun contenu à l'extérieur des objets enfants IBackupRestore qu'elle peut avoir, votre implémentation doit simplement définir une valeur pour CurrentProgess qui représente approximativement le pourcentage de la durée totale de l'opération de sauvegarde consommé par les méthodes OnRestore et OnPreRestore. Elle doit ensuite retourner true comme indiqué dans l'exemple suivant. N'appelez pas la méthode OnRestore d'un objet enfant IBackupRestore.

    public Boolean OnRestore(Object sender, SPRestoreInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        if (args.RestoreMethod == SPRestoreMethodType.New)
        {
            args.Rename();
        }
        args.CurrentProgress = 50;
        return true;
    }
    
    • Si votre classe possède du contenu à l'extérieur des objets enfants IBackupRestore qu'elle peut avoir, votre implémentation doit copier ce contenu vers la destination de restauration. Retournez false si cette copie échoue pour quelque raison que ce soit.

    L'exemple suivant montre la structure globale d'une implémentation significative de OnRestore :

    public Boolean OnRestore(Object sender, SPRestoreInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        if (args.RestoreMethod == SPRestoreMethodType.New)
        {
            args.Rename();
        }
        args.CurrentProgress = 50;
        Boolean successSignal = true;
    
        // TODO: Implement copying your content to the destination.
        //       If the copy fails, set successSignal to false.
    
        return successSignal;
    }
    
  16. Implémentez la méthode OnPostRestore. Au minimum, votre implémentation doit définir CurrentProgess à 100 % et retourner true comme indiqué dans l'exemple suivant. C'est en général tout ce qui est requis. Pour des informations à propos du travail supplémentaire que l'implémentation peut susciter, voir la rubrique de référence sur OnPostRestore.

    public Boolean OnPostRestore(Object sender, SPRestoreInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        args.CurrentProgress = 100;
        return true;
    }
    

Ajouter d'autres membres à votre classe si nécessaire

  1. Ajoutez des champs, des propriétés et des méthodes auxiliaires, si nécessaire, pour compléter votre classe, en gardant à l'esprit les points suivants :

    • Utilisez des champs et des propriétés pour contenir les objets de contenu enfants.

    • Si votre classe dérive de SPPersistedObject, la déclaration des champs que vous souhaitez rendre persistants dans la base de données de configuration doit être précédée par l'attribut [Persisted]. Toutefois, vous ne pouvez marquer de cette façon que les types suivants de champs : types primitifs, tels que chaînes, entiers et GUID, d'autres objets SPPersistedObject ou SPAutoserializingObject ou des collections de l'un des types précédents. Par exemple, la classe ne peut pas avoir un champ FileInfo marqué avec l'attribut [Persisted]. Si vous souhaitez rendre persistantes des données qui ne sont pas d'une classe persistante, utilisez un substitut persistant. L'exemple d'implémentation ci-dessus de la propriété DiskSizeRequired prévoit une classe qui conserve une collection de noms de fichiers et les utilise pour créer une collection temporaire d'objets FileInfo au moment de l'exécution.

    • Si votre classe peut avoir plusieurs enfants du même type, créez une propriété ou un champ d'un type collection ou d'un autre type énumérable pour contenir la collection de tous les enfants d'un type donné. Ceci est particulièrement important si le type d'enfant implémente lui-même IBackupRestore car votre implémentation de la méthode AddBackupObjects doit parcourir ces enfants et appeler la méthode AddBackupObjects de chacun. Reportez-vous à l'étape de la procédure d'implémentation de la méthode AddBackupObjects ci-dessus pour plus d'informations.

  2. Ajoutez les constructeurs à votre classe pour initialiser ses champs et ses propriétés comme nécessaire. Si la classe dérive de SPPersistedObject, il doit y avoir au moins un constructeur qui nomme l'objet et l'assigne à un parent. En règle générale, un tel constructeur accepte au moins les deux arguments suivants :

    • Un argument String qui sera le nom de l'objet de contenu.

    • Un argument SPPersistedObject qui représente le parent de l'objet de contenu.

    Ce constructeur doit appeler le constructeur de base qui prend les mêmes deux arguments. Voici un exemple :

    public MyContentComponent(String componentName, SPPersistedObject parent, SomeTypesomeOtherArgument, ... ) 
                       : base(componentName, parent)
    {
        somePrivateField = someOtherArgument;
        ...
    }
    

    Vous devez passer Microsoft.SharePoint.Administration.SPFarm.Local en tant que parent lorsque l'objet de contenu est le plus élevé dans l'arborescence des objets personnalisés IBackupRestore. Si votre type de composant personnalisé est toujours l'objet le plus élevé, omettez l'argument SPPersistedObject et codez en dur une référence à Microsoft.SharePoint.Administration.SPFarm.Local dans l'appel au constructeur de base. Voici un exemple :

    public MyContentComponent(String componentName, SomeTypesomeOtherArgument, ... ) 
                       : base(componentName, SPFarm.Local)
    {
        somePrivateField = someOtherArgument;
        ...
    }
    

    Si les objets de votre classe ont toujours le même nom, vous pouvez omettre l'argument String et coder en dur le nom dans l'appel au constructeur de base. (Si tous les objets d'un type donné ont le même nom, il ne doit jamais y en avoir plusieurs de ce type pour un parent donné et, par conséquent, pas plus d'un objet de ce type sur la batterie de serveurs entière si l'objet est enfant de la batterie.)

  3. Compilez votre projet de classe.

    Cc264020.warning(fr-fr,office.12).gif Avertissement :

    Vous devez donner un nom fort à l'assembly et placer cet assembly dans le Global Assembly Cache (GAC).

Pour créer un objet de votre classe et le rendre enfant de la batterie

  1. Démarrez un nouveau projet d'application console dans Visual Studio.

  2. Ajoutez au projet une référence à la DLL de votre classe de composant personnalisée.

  3. Ajoutez une instruction using pour Microsoft.SharePoint.Administration.

  4. Ajoutez une instruction using pour l'espace de noms que vous avez utilisé dans votre classe de composant personnalisée (ou utilisez simplement le même espace de noms dans votre application console).

  5. Ajoutez à la méthode Main de votre projet un appel au constructeur de votre classe de composant personnalisée. Si vous avez créé une hiérarchie de types personnalisés, appelez le constructeur de la classe la plus élevée.

  6. Si nécessaire, faites précéder l'appel au constructeur du composant par du code qui crée les paramètres pour le constructeur.

  7. Après l'appel au constructeur de votre composant, votre code doit appeler la méthode Update de l'objet composant. Voici un exemple de ce que vous devez avoir dans la méthode Main :

    MyContentComponent myContentObject = new MyContentComponent("component name", SPFarm.Local);
    myContentObject.Update();
    
  8. Compilez et exécutez l'application.

  9. Dans l'administration centrale, accédez à Opérations | Effectuer une sauvegarde. Votre objet doit apparaître comme enfant de la batterie de serveurs sur la page Effectuer une sauvegarde.

    Remarque Remarque :

    Vous trouverez un exemple d'application console pour créer et supprimer des objets de contenu personnalisés dans la section Exemple ci-dessous.

Conseils pour le développement

Les conseils suivants peuvent s'avérer utiles pour le développement de vos classes de contenu personnalisées. En effet, à plusieurs reprises, vous créerez probablement des objets et les ajouterez à la batterie de serveurs, au fur et à mesure de votre travail.

Points à garder à l'esprit

  1. Si vous devez supprimer votre objet de la base de données de configuration, utilisez Delete.

  2. Une exception est levée si vous appelez obj.Update() et qu'il existe déjà un objet de la même classe que obj avec la même valeur de propriété Name et le même parent dans la base de données de configuration. Il existe une version surchargée de Update qui peut être préférable.

  3. Vous trouverez un exemple d'application console dans la deuxième section Exemple ci-dessous qui peut être utilisé pour ajouter ou supprimer des objets personnalisés dans la base de données de configuration.

  4. Exécutez iisreset à partir de la ligne de commande après chaque recompilation de votre classe IBackupRestore. Vous devrez peut-être aussi redémarrer le serveur.

  5. Les différentes méthodes IBackupRestore.On* prennent soit un paramètre SPBackupInformation, soit un paramètre SPRestoreInformation. Vous pouvez utiliser leurs membres à des fins de débogage. La méthode Log est particulièrement utile.

Exemple

Le code suivant implémente un composant de contenu personnalisé qui représente un fichier Web.config sur un serveur frontal. Remplacez la partie TestSite du chemin d'accès au fichier dans l'implémentation du constructeur par un nom d'annuaire de votre serveur de test. L'assembly compilé doit avoir un nom fort et être installé dans le GAC.

Dans l'exemple suivant l'implémentation de la classe, il y a le code pour une application console simple qui inscrit le composant en tant qu'enfant de la batterie de serveurs ou le supprime de la batterie.

using System;
using System.IO;
using System.Collections.Generic;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Administration.Backup;

namespace MyCompany.SharePoint.Administration
{
    public class CriticalFiles : SPPersistedObject, IBackupRestore
    {

        public CriticalFiles() { }

        public CriticalFiles(String componentName, SPPersistedObject parent) 
                   : base(componentName, parent)
        {
            String pathOfFile = @"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\TestSite\Web.config";
            FrontEndFilePaths.Add(pathOfFile);
        }

        [Persisted]
        private const Int32 NUMBER_OF_FILES_TO_BACK_UP = 1;

        [Persisted]
        private List<String> FrontEndFilePaths = new List<String>(NUMBER_OF_FILES_TO_BACK_UP);

        public Boolean CanSelectForBackup
        {
            get { return true; }
            set { }
        }

        public Boolean CanSelectForRestore
        {
            get { return true; }
            set { }
        }

        public Boolean CanRenameOnRestore
        {
            get { return false; }
        }

        public UInt64 DiskSizeRequired
        {
            get
            {
                UInt64 total = 0;
                List<FileInfo> FrontEndFiles = new List<FileInfo>(NUMBER_OF_FILES_TO_BACK_UP);
                
                foreach (String path in FrontEndFilePaths)
                {
                    FileInfo file = new FileInfo(path);
                    FrontEndFiles.Add(file);
                }
                
                foreach (FileInfo file in FrontEndFiles)
                {
                    total = total + (UInt64)file.Length;
                }
                
                return total;
            }
        }

        public void AddBackupObjects(SPBackupRestoreObject parent)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }

            SPBackupRestoreObject self = parent.AddChild(this);
            self.Information.SetParameter(SPBackupRestoreObject.SPTypeName, this.GetType());
            self.Information.SetParameter(SPBackupRestoreObject.SPDescription, "The critical files on all front end servers.");
        }

        public Boolean OnAbort(Object sender, SPBackupRestoreInformation args)
        {
            return true;
        }

        public Boolean OnPrepareBackup(Object sender, SPBackupInformation args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }
            args.SetParameter(SPBackupRestoreObject.SPName, this.Name);
            return true;
        }

        public Boolean OnBackup(Object sender, SPBackupInformation args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }
            
            Boolean successSignal = true;

            foreach (String path in FrontEndFilePaths)
            {
                FileInfo file = new FileInfo(path);
                try
                {
                    String mappedFileName = args.GenerateFileMapping(file.Name);
                    file.CopyTo(args.Location + @"\" + mappedFileName, true);
                    args.Log(SPBackupRestoreLogSeverity.Verbose, "Backed up " + file.Name + " in (" + mappedFileName + ")");
                }
                catch (Exception e)
                {
                    args.Log(SPBackupRestoreLogSeverity.Verbose, file.Name + " not backed up: " + e.Message);
                    successSignal = false;
                }
            }

            args.CurrentProgress = 50;
            return successSignal;
        }

        public Boolean OnBackupComplete(Object sender, SPBackupInformation args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }
            args.CurrentProgress = 100;
            return true;
        }

        public Boolean OnPreRestore(Object sender, SPRestoreInformation args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }
            return true;
        }

        public Boolean OnRestore(Object sender, SPRestoreInformation args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            // If the CriticalFiles object was deleted from the farm after it was
            // backed up, restore it to the configuration database.
            CriticalFiles cf = SPFarm.Local.GetChild<CriticalFiles>(this.Name);
            if (cf == null)
            {
                this.Update();
                args.Log(SPBackupRestoreLogSeverity.Verbose, this.Name + " added back to configuration database.");
            }

            Boolean successSignal = true;

            // TODO: The following loop restores files to the local server. If there are 
            //       multiple front end servers, your code must iterate through all of 
            //       SPFarm.Local.Servers and restore the same files to every server whose
            //       Role property is SPServerRole.WebFrontEnd

            foreach (String path in FrontEndFilePaths)
            {
                FileInfo backupCopy = new FileInfo(path);
                String mappedFileName = args.ReverseFileMapping(backupCopy.Name);
                FileInfo file = new FileInfo(args.Location + @"\" + mappedFileName);

                try
                {
                    file.CopyTo(path, true);
                    args.Log(SPBackupRestoreLogSeverity.Verbose, "Restored " + backupCopy.Name);
                }
                catch (Exception e)
                {
                    args.Log(SPBackupRestoreLogSeverity.Verbose, file.Name + " not restored: " + e.Message);
                    successSignal = false;
                }
            }
            
            args.CurrentProgress = 50;
            return successSignal;
        }
        
        public Boolean OnPostRestore(Object sender, SPRestoreInformation args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            args.CurrentProgress = 100;
            return true;
        }

    }
}

Voici une application console qui ajoute ou supprime votre objet de contenu dans la base de données de configuration.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Administration.Backup;

namespace MyCompany.SharePoint.Administration
{
    class Program 
    {
        static void Main(string[] args)
        {
            CriticalFiles cf = SPFarm.Local.GetChild<CriticalFiles>("Critical Front End Files");
            if (cf == null)
            {
                Console.WriteLine("There is no CriticalFiles object in the configuration database.");
                Console.Write("Enter 'A' to add it. Press Return to do nothing:");
                String response = Console.ReadLine();
                if (response == "A")
                {
                    CriticalFiles myCriticalFiles = new CriticalFiles("Critical Front End Files", SPFarm.Local);
                    myCriticalFiles.Update();
                }
            }
            else
            {
                Console.WriteLine("There is a CriticalFiles object in the configuration database.");
                Console.Write("Enter 'D' to delete it. Press Return to do nothing:");
                String response = Console.ReadLine();
                if (response == "D")
                {
                    cf.Delete();
                }
            }
        }// end Main
    }// end Program
} 

Voir aussi

Afficher: