如何:创建可以备份和还原的内容类

上次修改时间: 2010年5月6日

适用范围: SharePoint Foundation 2010

如果您有一个自定义内容组件要包含在 Microsoft SharePoint Foundation 备份和还原中,则必须使用一个实现 IBackupRestore 接口的类来表示该组件。本主题介绍如何实现这一目的。在操作步骤的后面提供了完整示例。(如果您的组件是一个实现 服务应用程序框架 的 Web 服务,还还有一种替代方法来实现 IBackupRestore。有关详细信息,请参阅 在服务应用程序框架中备份和还原。)

备注

如果您的组件是一个承载于 Microsoft SQL Server 的企业版或开发人员版中的数据库,并且您希望能够通过 SharePoint Foundation UI 或对象模型从一个快照来还原该数据库,则您的类必须也实现 IDatabaseSnapshotRestore 接口。有关如何实现该接口的信息,请参阅如何:创建可从快照还原的数据库类

如果您的组件包含配置信息,而且服务器场管理员应该可以在仅限配置的备份和还原中选择将其包括在内,请查看主题如何:创建包含在仅配置备份和还原中的类,并执行其中的过程(如果合适)。

类不一定要从 SPPersistedObject 派生,但如果您的内容是数据库,则建议您从 SPDatabaseSPContentDatabase 派生类。后面这两个类派生自 SPPersistedObject,并且它们都可以实现 IBackupRestore。因此,您将具有 IBackupRestore 的成员的默认实现,可以在适当的时候使用这些实现。

可以创建任意多种类型的 IBackupRestore 类,如果需要,还可以将它们嵌套为组件类的树。但这种树中最高级别的类必须 派生(直接或间接)自 SPPersistedObject 对象,并且必须SPFarm 的子级。如果您的内容类不是任何其他自定义内容类的子级,则它必须 派生(直接或间接)自 SPPersistedObject 对象,并且必须SPFarm 的子级。

如果您的类派生自已实现 IBackupRestore 对象(无论它是否派生自 SPPersistedObject)的类,并且您想要替换 IBackupRestore 成员的继承实现,则类声明应明确引用 IBackupRestore,如下所示:

[GUID("9573FAD9-ED89-45E8-BD8B-6A5034E03895")]
public class MyClass : SPPersistedObject, IBackupRestore
<System.Runtime.InteropServices.Guid("9573FAD9-ED89-45E8-BD8B-6A5034E03895")>
Public Class [MyClass]
    Inherits SPPersistedObject
    Implements IBackupRestore

End Class

备注

任何直接或间接从 SPPersistedObject 继承的自定义类都必须具有应用于其声明的 GuidAttribute

任何 IBackupRestore 成员的"替代"都应在成员名称中明确包括"IBackupRestore",并且不应包含 public 关键字。例如:

UInt64 IBackupRestore.DiskSizeRequired { ... }
Public ReadOnly Property DiskSizeRequired As UInt64 Implements IBackupRestore.DiskSizeRequired
    Get
        ... 
    End Get
End Property

此外,如果父类中的成员的实现使用了 virtual 或 override 关键字,则可以在实现中使用如下所示的 override 关键字:

public override UInt64 DiskSizeRequired { ... }
Public Overrides ReadOnly Property DiskSizeRequired() As UInt64
    Get
        ...
    End Get
End Property
警告注释警告

不要 通过重新声明带或不带 new 关键字的成员 ([new] public UInt64 DiskSizeRequired { ... }) 来隐藏继承成员实现。在以下步骤中,将写入成员签名,方式与为不是派生自已实现 IBackupRestore 的类的类的成员写入签名一样。如果您的类确实派生自这样的一个父级,请务必将成员签名更改为所需的模式。

如果您的类派生自 SPPersistedObject,请让该类的 SPPersistedObject.IdSPPersistedObject.Name 属性作为 IBackupRestore.IdIBackupRestore.Name 属性的实现。可以重写属性,但不要创建其中任何一个属性的另一个实现。您的类只能有一个 Name 和一个 Id 属性。

实现 IBackupRestore 的成员

  1. 开始在 Visual Studio 中创建一个新的类项目。

  2. 将对 Microsoft.SharePoint 的引用添加到 Visual Studio 项目中,并将 Microsoft.SharePoint.Administration 和 Microsoft.SharePoint.Administration.Backup 命名空间的 using 语句添加到类文件中。

  3. 如果您的类不是派生自 SPPersistedObject,请实现 Name 属性。该属性将在 stsadm.exe 用户界面、管理中心应用程序以及任何自定义备份和还原应用程序的用户界面中充当内容组件的名称。大多数情况下,可以通过为名称值创建一个私有字段来实现该属性,并作为字段的包装来实现公共属性。有关可能的不同实现方式的信息,请参阅该属性的参考主题。

    private String name;
    public String Name
    {
    get {return name;}
    set {name = value;}
    }
    
     Private _name As String
    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property
    
  4. 如果您的类不是派生自 SPPersistedObject,请实现 Id 属性。大多数情况下,可以通过为名称值创建一个私有字段来实现该属性,并作为字段的包装来实现公共属性。有关可能的不同实现方式的信息,请参阅该属性的参考主题。

    private Guid id;
    public Guid Id
    {
    get {return id;}
    set {id = value;}
    }
    
    Private _Id As Guid
    Public Property Id() As Guid
        Get
            Return _Id 
        End Get
        Set(ByVal value As Guid)
            _Id = value
        End Set
    End Property
    
  5. 实现 DiskSizeRequired 属性。如果您的类只是某些 IBackupRestore 子类的容器,则属性应返回 0。否则,该属性应计算内容的大小。(包括任何非 IBackupRestore 子对象的大小,但不包括任何子 IBackupRestore 对象的大小。它们每个都有自己的 DiskSizeRequired 属性,SharePoint Foundation 会自动将这些值相加)。下面的示例对其路径包含在名为 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;
        }
    } 
    
    Public ReadOnly Property DiskSizeRequired() As UInt64 Implements IBackupRestore.DiskSizeRequired
        Get
            Dim total As UInt64 = 0
            Dim FrontEndFiles As New List(Of FileInfo)(NUMBER_OF_FILES_TO_BACK_UP)
    
            For Each path As String In FrontEndFilePaths
                Dim file As New FileInfo(path)
                FrontEndFiles.Add(file)
            Next path
    
            For Each file As FileInfo In FrontEndFiles
                total = total + CULng(file.Length)
            Next file
    
            Return total
        End Get
    End Property
    
  6. 实现 CanSelectForBackup 属性。如果用户始终无法 独立于父对象的备份来备份您的类的对象,则 get 取值函数应返回 false。如果用户始终能够选择您的类的任何 对象进行独立备份,则 get 取值函数应返回 true。无论是哪种情况,set 取值函数应都应该是一对空的大括号"{ }"。如果您的类中某些对象可以独立于其父级进行备份,但有些不能,则应将该属性作为私有 Boolean 字段的包装实现。

  7. 实现 CanSelectForRestore 属性。如果用户始终无法独立于父对象的还原来还原您的自定义组件类的对象,则 get 取值函数应返回 false。如果用户应始终能够选择您的类的任何对象进行独立还原,则 get 取值函数应返回 true。无论是哪种情况,set 取值函数应都应该是一对空的大括号"{ }"。如果您的类中某些对象可以独立于其父级进行还原,但有些不能,则应将该属性作为私有 Boolean 字段的包装实现。

  8. 实现 CanRenameOnRestore 属性。如果用户始终无法将您的自定义组件类的对象还原到新位置,则 get 取值函数应返回 false。如果用户能够迁移您的类的任何对象,则 get 取值函数应返回 true。如果您的类的对象有时可以迁移,但并非总是如此,则应将该属性作为私有 Boolean 字段的包装实现。

  9. 实现 AddBackupObjects(SPBackupRestoreObject) 方法。

    1. 如果没有可向其添加组件的有效父级,则您的实现代码应从引发异常开始。

    2. 使用 AddChild 方法将您的组件添加到备份或还原操作将处理的对象树。

    3. 使用 SetParameter(String, Object) 方法可以指定可供备份/还原应用程序的用户界面使用的组件的类型名称和说明。

    4. 如果组件具有 IBackupRestore 子对象,则您的实现应循环访问这些子对象,并以递归方式调用每个子级的 AddBackupObjects(SPBackupRestoreObject) 方法。

    5. 有关 AddBackupObjects(SPBackupRestoreObject) 方法的实现的详细信息,请参阅该方法的参考主题。

    下面的示例代码假定您的内容类有 IBackupRestore 子对象的 ChildContentCollection。如果您的类具有多种类型的子组件,则可以为每种类型使用单独的集合并循环访问每个集合。

    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);
        }
    }
    
    Public Sub AddBackupObjects(ByVal parent As SPBackupRestoreObject) Implements IBackupRestore.AddBackupObjects
        If parent Is Nothing Then
            Throw New ArgumentNullException("parent")
        End If
    
        Dim self As SPBackupRestoreObject = parent.AddChild(Me)
        self.Information.SetParameter(SPBackupRestoreObject.SPTypeName, Me.GetType())
        self.Information.SetParameter(SPBackupRestoreObject.SPDescription, "Description of custom content component")
    
        For Each child As ChildContent In ChildContentCollection
            Dim childIBR As IBackupRestore = TryCast(child, IBackupRestore)
            childIBR.AddBackupObjects(self)
        Next child
    End Sub
    
  10. 实现 OnAbort(Object, SPBackupRestoreInformation) 方法。它应始终返回 true。大多数情况下,它不应执行任何其他操作,但可以参阅 OnAbort(Object, SPBackupRestoreInformation) 的参考主题以获取有关此一般规则的例外情况的信息。

  11. 实现 OnPrepareBackup(Object, SPBackupInformation) 方法。您至少应使用 SetParameter(String, Object) 方法为内容对象指定一个名称。另外,还可以进行一些归纳。有关详细信息,请参阅 OnPrepareBackup(Object, SPBackupInformation) 的参考主题。下面的示例演示该方法的最少实现,它通常是所需的全部内容。

    public Boolean OnPrepareBackup(Object sender, SPBackupInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        args.SetParameter(SPBackupRestoreObject.SPName, this.Name);
        return true;
    }
    
    Public Function OnPrepareBackup(ByVal sender As Object, ByVal args As SPBackupInformation) As Boolean implements IBackupRestore.OnPrepareBackup 
        If args Is Nothing Then
            Throw New ArgumentNullException("args")
        End If
        args.SetParameter(SPBackupRestoreObject.SPName, Me.Name)
        Return True
    End Function
    
  12. 实现 OnBackup(Object, SPBackupInformation) 方法。如果您的内容类在它可能具有的任何 IBackupRestore 子对象之外没有内容,则您的实现只需将 CurrentProgress 设置为一个值,该值大概表示由 OnBackup(Object, SPBackupInformation)OnPrepareBackup(Object, SPBackupInformation) 方法占用的总备份操作时间的百分比。然后它应返回 true,如下面的示例所示。不要 调用任何 IBackupRestore 子对象的 OnBackup 方法。

    public Boolean OnBackup(Object sender, SPBackupInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        args.CurrentProgress = 50;
        return true;
    }
    
    Public Function OnBackup(ByVal sender As Object, ByVal args As SPBackupInformation) As Boolean implements IBackupRestore.OnBackup 
        If args Is Nothing Then
            Throw New ArgumentNullException("args")
        End If
        args.CurrentProgress = 50
        Return True
    End Function
    

    如果您的类在它可能具有的任何 IBackupRestore 子对象之外仍然有 内容,则您的实现必须将此内容复制到 args.Location,如果复制失败,则将返回 false。应包含逻辑以备份所有 实现 IBackupRestore 的子对象,但不应明确备份所有实现IBackupRestore 的子对象。这些子对象将由它们自己的 OnBackup(Object, SPBackupInformation) 方法备份,运行库会调用该方法。您不应在自己的代码中调用子对象的 OnBackup(Object, SPBackupInformation) 方法。下面的示例演示 OnBackup(Object, SPBackupInformation) 的独立实现的总体结构:

    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;
    }
    
    Public Function OnBackup(ByVal sender As Object, ByVal args As SPBackupInformation) As Boolean implements IBackupRestore.OnBackup 
        If args Is Nothing Then
            Throw New ArgumentNullException("args")
        End If
        args.CurrentProgress = 50
        Dim successSignal As Boolean = True
    
        ' TODO: Implement copying your content to args.Location
        '       If the copy fails, set successSignal to false.
    
        Return successSignal
    End Function
    
  13. 实现 OnBackupComplete(Object, SPBackupInformation) 方法。如下面的示例中所示,您的实现至少应将 CurrentProgress 设置为 100% 并返回 true。这通常是必须满足的全部要求。有关您的实现可能需要执行的其他任务的信息,请参阅 OnBackupComplete 的参考主题。

    public Boolean OnBackupComplete(Object sender, SPBackupInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        args.CurrentProgress = 100;
        return true;
    }
    
    Public Function OnBackupComplete(ByVal sender As Object, ByVal args As SPBackupInformation) As Boolean implements IBackupRestore.OnBackupComplete 
        If args Is Nothing Then
            Throw New ArgumentNullException("args")
        End If
        args.CurrentProgress = 100
        Return True
    End Function
    
  14. 实现 OnPreRestore 方法。大多数情况下,还原操作不需要准备工作,并且您的 OnPreRestore 实现应仅返回 true。有关您的实现可能需要执行的其他任务的信息,请参阅 OnPreRestore 的参考主题。

  15. 实现 OnRestore 方法。

    • 如果您的内容类可以迁移,则您的代码应检查所用的还原方法,并调用 Rename()(如果还原方法是 New)。

    • 如果您的内容类在它可能具有的任何 IBackupRestore 子对象之外没有内容,则您的实现只需将 CurrentProgress 设置为一个值,该值大概表示由 OnRestoreOnPreRestore 方法占用的总还原操作时间的百分比。然后它应返回 true,如下面的示例所示。不要 调用任何 IBackupRestore 子对象的 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;
        return true;
    }
    
    Public Function OnRestore(ByVal sender As Object, ByVal args As SPRestoreInformation) As Boolean implements IBackupRestore.OnRestore 
        If args Is Nothing Then
            Throw New ArgumentNullException("args")
        End If
        If args.RestoreMethod = SPRestoreMethodType.New Then
            args.Rename()
        End If
        args.CurrentProgress = 50
        Return True
    End Function
    
    • 如果您的类在它可能具有的任何 IBackupRestore 子对象之外仍然有 内容,则您的实现必须将此内容复制到还原目标位置。如果由于任何原因导致内容复制失败,则将返回 false。

    下面的示例演示 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;
    }
    
    Public Function OnRestore(ByVal sender As Object, ByVal args As SPRestoreInformation) As Boolean implements IBackupRestore.OnRestore 
        If args Is Nothing Then
            Throw New ArgumentNullException("args")
        End If
        If args.RestoreMethod = SPRestoreMethodType.New Then
            args.Rename()
        End If
        args.CurrentProgress = 50
        Dim successSignal As Boolean = True
    
        ' TODO: Implement copying your content to the destination.
        '       If the copy fails, set successSignal to false.
    
        Return successSignal
    End Function
    
  16. 实现 OnPostRestore 方法。如下面的示例中所示,您的实现至少应将 CurrentProgress 设置为 100% 并返回 true。这通常是必须满足的全部要求。有关您的实现可能需要执行的其他任务的信息,请参阅 OnPostRestore 的参考主题。

    public Boolean OnPostRestore(Object sender, SPRestoreInformation args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }
        args.CurrentProgress = 100;
        return true;
    }
    
    Public Function OnPostRestore(ByVal sender As Object, ByVal args As SPRestoreInformation) As Boolean implements IBackupRestore.OnPostRestore 
        If args Is Nothing Then
            Throw New ArgumentNullException("args")
        End If
        args.CurrentProgress = 100
        Return True
    End Function
    

根据需要将其他成员添加到类中

  1. 根据需要添加字段、属性和帮助程序方法以完成您的类。在操作时,请记住以下几点:

    • 使用字段和属性来存储子内容对象。

    • 如果类派生自 SPPersistedObject,则要在配置数据库中保留的字段的声明前面必须有 [Persisted] 属性。但是,只能通过这种方式标记以下类型的字段:基元类型(如字符串、整型和 GUID);其他 SPPersistedObject 对象或 SPAutoserializingObject 对象;或者上述任意项的集合。例如,该类不能有使用 [Persisted] 属性标记的 FileInfo 字段。如果要保留的数据不属于持久性类,请使用持久性替代类。DiskSizeRequired 属性的上述示例实现假定存在这样一个类,该类会保留文件名的集合,并在运行时使用这些文件名来创建 FileInfo 对象的临时集合。

    • 如果您的类可以有多个相同类型的子级,请创建一个集合类型或其他可枚举类型的属性或字段,来存储给定类型的所有子级的集合。如果该子类型本身可实现 IBackupRestore,则这一点则尤其重要,因为 AddBackupObjects(SPBackupRestoreObject) 方法的实现应循环访问此类子级,并调用每个子级的 AddBackupObjects(SPBackupRestoreObject) 方法。有关详细信息,请参阅实现上述 AddBackupObjects(SPBackupRestoreObject) 方法的步骤。

  2. 根据需要将构造函数添加到您的类中,以初始化其字段和属性。如果类派生自 SPPersistedObject,则必须至少有一个构造函数来指定该对象并将其分配给父级。通常,此类构造函数会采用至少两个参数:

    该构造函数必须调用采用两个相同参数的基构造函数。例如:

    public MyContentComponent(String componentName, SPPersistedObject parent, SomeTypesomeOtherArgument, ... ) 
                       : base(componentName, parent)
    {
        somePrivateField = someOtherArgument;
        ...
    }
    
    Public Sub New(ByVal componentName As String, ByVal parent As SPPersistedObject, ByVal someOtherArgument As SomeType, . ByVal .. As )
        MyBase.New(componentName, parent)
        somePrivateField = someOtherArgument
       ...
    End Sub
    

    当内容对象是自定义 IBackupRestore 对象的树中的最顶级对象时,必须将 SPFarm.Local 作为父级传递。如果自定义组件类型始终 是最顶级对象,则可以省略 SPPersistedObject 参数,并在对基构造函数的调用中硬编码对 SPFarm.Local 的引用。例如:

    public MyContentComponent(String componentName, SomeTypesomeOtherArgument, ... ) 
                       : base(componentName, SPFarm.Local)
    {
        somePrivateField = someOtherArgument;
        ...
    }
    
    Public Sub New(ByVal componentName As String, ByVal someOtherArgument As SomeType, . ByVal .. As )
        MyBase.New(componentName, SPFarm.Local)
        somePrivateField = someOtherArgument
       ...
    End Sub
    

    如果您的类的对象始终具有相同的名称,则可以省略 String 参数,并在对基构造函数的调用中对该名称进行硬编码。(如果给定类型的所有对象都具有相同的名称,那么对于给定的父级,最多只能有一个该类型的子级;因此,如果对象是服务器场的子级,则整个服务器场中最多只能有一个该类型的对象。)

  3. 编译类项目。

    警告注释警告

    必须为程序集指定一个强名称并将该程序集放在全局程序集缓存 (GAC) 中。

创建类的对象并使其成为服务器场的子级

  1. 在 Visual Studio 中启动一个新的控制台应用程序项目。

  2. 为项目添加对您的自定义组件类的 DLL 的引用。

  3. 为 Microsoft.SharePoint.Administration 添加 using 语句。

  4. 为您的自定义组件类中使用的命名空间添加 using 语句(或使用控制台应用程序中的同一命名空间)。

  5. 将对自定义组件类的构造函数的调用添加到项目的 Main 方法中。如果创建了自定义类型的层次结构,请调用最顶级类的构造函数。

  6. 如果需要,请在该组件的构造函数调用之前放置一些为该构造函数创建参数的代码。

  7. 在调用组件的构造函数之后,您的代码应调用组件对象的 Update 方法。下面是应在 Main 方法中包含的内容的示例:

    MyContentComponent myContentObject = new MyContentComponent("component name", SPFarm.Local);
    myContentObject.Update();
    
    Dim myContentObject As New MyContentComponent("component name", SPFarm.Local)
    myContentObject.Update()
    
  8. 编译并运行该应用程序。

  9. 在管理中心应用程序中,导航到"操作"|"执行备份"。您的对象应显示为"执行备份"页上的服务器场的子级。

    备注

    下面的示例部分中有一个用于创建和删除自定义内容对象的示例控制台应用程序。

开发建议

在开发自定义内容类时,以下提示可能会有所帮助,这是因为您可能会在工作时创建对象并多次将它们添加到服务器场。

需要记住的几点

  1. 如果您需要从配置数据库中删除对象,请使用 Delete()

  2. 如果调用 obj.Update(),并且配置数据库中已经存在具有相同的 Name 属性值和相同的父级,以及与 obj 属于同一类的对象,则会引发异常。Update 有一个重载版本,该版本可能更好。

  3. 下面的第二个示例部分中有一个示例控制台应用程序,该应用程序可用于在配置数据库中添加或删除自定义对象。

  4. 每次重新编译您的 iisreset 类之后,在命令行运行 IBackupRestore。您可能还需要重新启动服务器。

  5. 不同的 IBackupRestore.On* 方法采用 SPBackupInformation 参数或 SPRestoreInformation 参数。您可以使用它们的成员进行调试。日志 Log 方法尤其有用。

示例

下面的代码实现表示前端服务器上的单个 Web.config 文件的自定义内容组件。请将构造函数实现的文件路径中的 TestSite 部分替换为测试服务器上的目录名称。已编译的程序集必须具有强名称并且安装在 GAC 中。

在类实现后面的示例中,有简单控制台应用程序的代码,该应用程序将组件注册为服务器场的子级或从服务器场中删除该组件。

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

    }
}
Imports System
Imports System.IO
Imports System.Collections.Generic
Imports Microsoft.SharePoint.Administration
Imports Microsoft.SharePoint.Administration.Backup


Namespace MyCompany.SharePoint.Administration
    Public Class CriticalFiles
        Inherits SPPersistedObject
        Implements IBackupRestore

        Public Sub New()
        End Sub

        Public Sub New(ByVal componentName As String, ByVal parent As SPPersistedObject)
            MyBase.New(componentName, parent)
            Dim pathOfFile As String = "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\TestSite\Web.config"
            FrontEndFilePaths.Add(pathOfFile)
        End Sub

        <Persisted()>
        Private Const NUMBER_OF_FILES_TO_BACK_UP As Int32 = 1

        <Persisted()>
        Private FrontEndFilePaths As New List(Of String)(NUMBER_OF_FILES_TO_BACK_UP)

        Public Property CanSelectForBackup() As Boolean Implements IBackupRestore.CanSelectForBackup
            Get
                Return True
            End Get
            Set(ByVal value As Boolean)
            End Set
        End Property

        Public Property CanSelectForRestore() As Boolean Implements IBackupRestore.CanSelectForRestore
            Get
                Return True
            End Get
            Set(ByVal value As Boolean)
            End Set
        End Property

        Public ReadOnly Property CanRenameOnRestore() As Boolean Implements IBackupRestore.CanRenameOnRestore
            Get
                Return False
            End Get
        End Property

        Public ReadOnly Property DiskSizeRequired() As UInt64 Implements IBackupRestore.DiskSizeRequired
            Get
                Dim total As UInt64 = 0
                Dim FrontEndFiles As New List(Of FileInfo)(NUMBER_OF_FILES_TO_BACK_UP)

                For Each path As String In FrontEndFilePaths
                    Dim file As New FileInfo(path)
                    FrontEndFiles.Add(file)
                Next path

                For Each file As FileInfo In FrontEndFiles
                    total = total + CULng(file.Length)
                Next file

                Return total
            End Get
        End Property

        Public Sub AddBackupObjects(ByVal parent As SPBackupRestoreObject) Implements IBackupRestore.AddBackupObjects
            If parent Is Nothing Then
                Throw New ArgumentNullException("parent")
            End If

            Dim self As SPBackupRestoreObject = parent.AddChild(Me)
            self.Information.SetParameter(SPBackupRestoreObject.SPTypeName, Me.GetType())
            self.Information.SetParameter(SPBackupRestoreObject.SPDescription, "The critical files on all front end servers.")
        End Sub

        Public Function OnAbort(ByVal sender As Object, ByVal args As SPBackupRestoreInformation) As Boolean Implements IBackupRestore.OnAbort
            Return True
        End Function

        Public Function OnPrepareBackup(ByVal sender As Object, ByVal args As SPBackupInformation) As Boolean Implements IBackupRestore.OnPrepareBackup
            If args Is Nothing Then
                Throw New ArgumentNullException("args")
            End If
            args.SetParameter(SPBackupRestoreObject.SPName, Me.Name)
            Return True
        End Function

        Public Function OnBackup(ByVal sender As Object, ByVal args As SPBackupInformation) As Boolean Implements IBackupRestore.OnBackup
            If args Is Nothing Then
                Throw New ArgumentNullException("args")
            End If

            Dim successSignal As Boolean = True

            For Each path As String In FrontEndFilePaths
                Dim file As New FileInfo(path)
                Try
                    Dim mappedFileName As String = args.GenerateFileMapping(file.Name)
                    file.CopyTo(args.Location & "\" & mappedFileName, True)
                    args.Log(SPBackupRestoreLogSeverity.Verbose, "Backed up " & file.Name & " in (" & mappedFileName & ")")
                Catch e As Exception
                    args.Log(SPBackupRestoreLogSeverity.Verbose, file.Name & " not backed up: " & e.Message)
                    successSignal = False
                End Try
            Next path

            args.CurrentProgress = 50
            Return successSignal
        End Function

        Public Function OnBackupComplete(ByVal sender As Object, ByVal args As SPBackupInformation) As Boolean Implements IBackupRestore.OnBackupComplete
            If args Is Nothing Then
                Throw New ArgumentNullException("args")
            End If
            args.CurrentProgress = 100
            Return True
        End Function

        Public Function OnPreRestore(ByVal sender As Object, ByVal args As SPRestoreInformation) As Boolean
            If args Is Nothing Then
                Throw New ArgumentNullException("args")
            End If
            Return True
        End Function

        Public Function OnRestore(ByVal sender As Object, ByVal args As SPRestoreInformation) As Boolean Implements IBackupRestore.OnRestore
            If args Is Nothing Then
                Throw New ArgumentNullException("args")
            End If

            ' If the CriticalFiles object was deleted from the farm after it was
            ' backed up, restore it to the configuration database.
            Dim cf As CriticalFiles = SPFarm.Local.GetChild(Of CriticalFiles)(Me.Name)
            If cf Is Nothing Then
                Me.Update()
                args.Log(SPBackupRestoreLogSeverity.Verbose, Me.Name & " added back to configuration database.")
            End If

            Dim successSignal As Boolean = 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

            For Each path As String In FrontEndFilePaths
                Dim backupCopy As New FileInfo(path)
                Dim mappedFileName As String = args.ReverseFileMapping(backupCopy.Name)
                Dim file As New FileInfo(args.Location & "\" & mappedFileName)

                Try
                    file.CopyTo(path, True)
                    args.Log(SPBackupRestoreLogSeverity.Verbose, "Restored " & backupCopy.Name)
                Catch e As Exception
                    args.Log(SPBackupRestoreLogSeverity.Verbose, file.Name & " not restored: " & e.Message)
                    successSignal = False
                End Try
            Next path

            args.CurrentProgress = 50
            Return successSignal
        End Function

        Public Function OnPostRestore(ByVal sender As Object, ByVal args As SPRestoreInformation) As Boolean Implements IBackupRestore.OnPostRestore
            If args Is Nothing Then
                Throw New ArgumentNullException("args")
            End If

            args.CurrentProgress = 100
            Return True
        End Function

    End Class
End Namespace

下面是一个控制台应用程序,该应用程序将在配置数据库中添加或删除内容对象。

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
} 
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports Microsoft.SharePoint.Administration
Imports Microsoft.SharePoint.Administration.Backup

Namespace MyCompany.SharePoint.Administration
    Module Program
        Sub Main(ByVal args() As String)
            Dim cf As CriticalFiles = SPFarm.Local.GetChild(Of CriticalFiles)("Critical Front End Files")
            If cf Is Nothing Then
                Console.WriteLine("There is no CriticalFiles object in the configuration database.")
                Console.Write("Enter 'A' to add it. Press Return to do nothing:")
                Dim response As String = Console.ReadLine()
                If response = "A" Then
                    Dim myCriticalFiles As New CriticalFiles("Critical Front End Files", SPFarm.Local)
                    myCriticalFiles.Update()
                End If
            Else
                Console.WriteLine("There is a CriticalFiles object in the configuration database.")
                Console.Write("Enter 'D' to delete it. Press Return to do nothing:")
                Dim response As String = Console.ReadLine()
                If response = "D" Then
                    cf.Delete()
                End If
            End If
        End Sub ' end Main
    End Module  ' end Program
End Namespace

请参阅

任务

如何:以编程方式备份内容

如何:以编程方式还原内容

如何:以编程方式备份和还原单个网站集

如何:创建可从快照还原的数据库类

如何:创建包含在仅配置备份和还原中的类

引用

Microsoft.SharePoint.Administration.Backup

Backup

Restore

概念

使用 SharePoint Foundation 备份/还原对象模型进行编程