如何:按更改类型筛选更改日志

上次修改时间: 2009年7月29日

适用范围: SharePoint Foundation 2010

该示例是一个在内容数据库范围内查询更改日志的控制台应用程序。该查询查找对 SPUserSPGroup 对象所做的更改,其中涉及添加、更新或删除任一类型的对象;还查找会修改组成员资格的更改。

请注意,该示例尝试证明可独立于系统对象的安全性管理更改日志的安全性。当您编译并运行该示例时,您的特权可能允许您读取更改日志,并发现哪些类型的对象发生了更改以及对这些对象进行了哪些类型的更改,但可能不允许您访问对象本身。因此,代码可能会输出有关 SPUser 对象在特定日期被添加到网站集的信息,还可能会输出所添加对象的 GUID。但当它尝试检索该对象时,可能仍会引发 UnauthorizedAccessException。拥有访问更改日志的权限并不等于拥有访问所更改对象的权限。

示例

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace Test
{
    class Program
    {
        static SPUserCollection m_users;
        static SPGroupCollection m_groups;

        static void Main(string[] args)
        {
            using (SPSite currentSite = new SPSite("https://localhost"))
            {
                SPTimeZone tz = currentSite.RootWeb.RegionalSettings.TimeZone;
                SPContentDatabase db = currentSite.ContentDatabase;
                m_users = currentSite.RootWeb.AllUsers;
                m_groups = currentSite.RootWeb.Groups;

                // Construct a query.
                SPChangeQuery query = new SPChangeQuery(false,  // Specify object types
                                                        false   // Specify change types
                                                        );
                // Specify object types. 
                query.User = true;
                query.Group = true;

                // Specify change types. 
                query.Add = true;
                query.Delete = true;
                query.Update = true;
                query.GroupMembershipAdd = true;
                query.GroupMembershipDelete = true;

                long total = 0;
                while (true)
                {
                    SPChangeCollection changes = db.GetChanges(query);

                    total += changes.Count;

                    foreach (SPChange change in changes)
                    {
                        // Print the date of the change.
                        Console.WriteLine("\nDate: {0}",
                                          tz.UTCToLocalTime(change.Time).ToString());

                        // Get the url, user collection, and group collection
                        // of the site where the change took place.
                        foreach (SPSite site in db.Sites)
                        {
                            if (site.ID == change.SiteId)
                            {
                                Console.WriteLine("Site Url: {0}", site.Url);
                                try
                                {
                                    m_users = site.RootWeb.AllUsers;
                                    m_groups = site.RootWeb.Groups;
                                }
                                catch (UnauthorizedAccessException)
                                {
                                    // Do nothing. The failure is handled elsewhere in the code.
                                }
                                finally
                                {
                                    site.Dispose();
                                }
                                break;
                            }
                            site.Dispose();
                        }

                        // Print the nature of the change.
                        Console.WriteLine("Type of object: {0}", change.GetType().ToString());
                        Console.WriteLine("Type of change: {0}", change.ChangeType.ToString());

                        // Get information about a user change.
                        if (change is SPChangeUser)
                        {
                            SPChangeUser userChange = (SPChangeUser)change;
                            // Print the user name.
                            string userName = GetPrincipalName(userChange.Id, true);
                            Console.WriteLine("User name: {0}", userName);
                        }

                        // Get information about a group change.
                        if (change is SPChangeGroup)
                        {
                            SPChangeGroup groupChange = (SPChangeGroup)change;
                            // Print the group name.
                            string groupName = GetPrincipalName(groupChange.Id, false);
                            Console.WriteLine("Group name: {0}", groupName);

                            if (groupChange.ChangeType == SPChangeType.MemberAdd ||
                                groupChange.ChangeType == SPChangeType.MemberDelete)
                            {
                                string userName = GetPrincipalName(groupChange.UserId, true);
                                Console.WriteLine("User name: {0}", userName);
                            }
                        }
                    }
                    if (changes.Count < query.FetchLimit)
                        break;
                    query.ChangeTokenStart = changes.LastChangeToken;
                }
                Console.WriteLine("\nTotal changes = {0:#,#}", total);
            }
            Console.Write("\nPress ENTER to continue...");
            Console.Read();
        }

        static string GetPrincipalName(int id, bool isUser)
        { 
            string name = string.Empty;
            try
            {
                if (isUser)
                {
                    SPUser user = m_users.GetByID(id);
                    name = user.LoginName;
                }
                else
                {
                    SPGroup group = m_groups.GetByID(id);
                    name = group.Name;
                }
            }
            catch (UnauthorizedAccessException)
            {
                name = "unknown (access not authorized)";
            }
            catch (SPException)
            {
                name = "unknown (not found)";
            }
            return name;
        }
    }
}
Imports System
Imports Microsoft.SharePoint
Imports Microsoft.SharePoint.Administration

Module ConsoleApp

   Dim m_users As SPUserCollection
   Dim m_groups As SPGroupCollection

   Sub Main()
      Using currentSite As SPSite = New SPSite("https://localhost")

         Dim tz As SPTimeZone = currentSite.RootWeb.RegionalSettings.TimeZone
         Dim db As SPContentDatabase = currentSite.ContentDatabase
         m_users = currentSite.RootWeb.Users
         m_groups = currentSite.RootWeb.Groups

         ' Construct a query.
         Dim query As SPChangeQuery = New SPChangeQuery(False, False)

         ' Specify object types.
         query.User = True
         query.Group = True

         ' Specify change types. 
         query.Add = True
         query.Delete = True
         query.Update = True
         query.GroupMembershipAdd = True
         query.GroupMembershipDelete = True

         Dim total As Long = 0
         While True
            Dim changes As SPChangeCollection = db.GetChanges(query)
            total += changes.Count

            Dim change As SPChange
            For Each change In changes
               ' Print the date of the change.
               Console.WriteLine(vbCrLf + "Date: {0}", _
                                    tz.UTCToLocalTime(change.Time).ToString())

               ' Get the url, user collection, and group collection
               ' of the site where the change took place.
               Dim site As SPSite
               For Each site In db.Sites
                  If site.ID = change.SiteId Then
                     Console.WriteLine("Site Url: {0}", site.Url)

                     Try
                        m_users = site.RootWeb.AllUsers
                        m_groups = site.RootWeb.Groups
                     Catch
                        ' Do nothing. The failure is handled elsewhere in the code.
                     Finally
                        site.Dispose()
                     End Try

                     Exit For
                  End If
                  site.Dispose()
               Next

               ' Print the nature of the change.
               Console.WriteLine("Type of object: {0}", change.GetType().ToString())
               Console.WriteLine("Type of change: {0}", change.ChangeType.ToString())

               ' Get information about a user change.
               If TypeOf change Is SPChangeUser Then
                  Dim userChange As SPChangeUser = CType(change, SPChangeUser)
                  ' Print the user name.
                  Dim userName As String = GetPrincipalName(userChange.Id, True)
                  Console.WriteLine("User name: {0}", userName)
               End If

               ' Get information about a group change.
               If TypeOf change Is SPChangeGroup Then
                  Dim groupChange As SPChangeGroup = CType(change, SPChangeGroup)
                  ' Print the group name.
                  Dim groupName As String = GetPrincipalName(groupChange.Id, False)
                  Console.WriteLine("Group name: {0}", groupName)

                  If (groupChange.ChangeType = SPChangeType.MemberAdd) Or _
                     (groupChange.ChangeType = SPChangeType.MemberDelete) Then
                     Dim userName As String = GetPrincipalName(groupChange.UserId, True)
                     Console.WriteLine("User name: {0}", userName)
                  End If
               End If

            Next

            If changes.Count < changes.FetchLimit Then
               Exit While
            End If

            query.ChangeTokenStart = changes.LastChangeToken
            changes = db.GetChanges(query)

         End While
         Console.WriteLine(vbCrLf + "Total changes: {0}", total)
      End Using

      Console.Write(vbCrLf + "Press ENTER to continue...")
      Console.Read()
   End Sub

   Function GetPrincipalName(ByVal id As Integer, ByVal isUser As Boolean) As String
      Dim name As String = String.Empty
      Try
         If isUser Then
            Dim user As SPUser = m_users.GetByID(id)
            name = user.LoginName
         Else
            Dim group As SPGroup = m_groups.GetByID(id)
            name = group.Name
         End If
      Catch secex As UnauthorizedAccessException
         name = "unknown (access not authorized)"
      Catch spex As SPException
         name = "unknown (not found)"
      End Try
      Return name
   End Function

End Module

请参阅

任务

如何:按对象类型筛选更改日志

概念

查询更改日志以获取特定更改