private static void DoWork() { Console.WriteLine(); Console.WriteLine("Url: " + url); Console.WriteLine("User Name: " + userName); Console.WriteLine("List Name: " + listName); Console.WriteLine(); try { Console.WriteLine(string.Format("Connecting to {0}", url)); Console.WriteLine(); ClientContext cc = new ClientContext(url); cc.AuthenticationMode = ClientAuthenticationMode.Default; cc.Credentials = new SharePointOnlineCredentials(userName, password); ListCollection lists = cc.Web.Lists; IEnumerable <List> results = cc.LoadQuery <List>(lists.Where(lst => lst.Title == listName)); cc.ExecuteQuery(); List list = results.FirstOrDefault(); if (list == null) { Console.WriteLine("A list named \"{0}\" does not exist. Press any key to exit...", listName); Console.ReadKey(); return; } nextRunTime = DateTime.Now; ChangeQuery cq = new ChangeQuery(false, false); cq.Item = true; cq.DeleteObject = true; cq.Add = true; cq.Update = true; // Initially set the ChangeTokenStart to 2 days ago so we don't go off and grab every item from the list since the day it was created. // The format of the string is semicolon delimited with the following pieces of information in order // Version number // A number indicating the change scope: 0 – Content Database, 1 – site collection, 2 – site, 3 – list. // GUID representing the scope ID of the change token // Time (in UTC) when the change occurred // Number of the change relative to other changes cq.ChangeTokenStart = new ChangeToken(); cq.ChangeTokenStart.StringValue = string.Format("1;3;{0};{1};-1", list.Id.ToString(), DateTime.Now.AddDays(-2).ToUniversalTime().Ticks.ToString()); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(string.Format("Ctrl+c to terminate. Press \"r\" key to force run without waiting {0} seconds.", WaitSeconds)); Console.WriteLine(); Console.ResetColor(); do { do { if (Console.KeyAvailable && Console.ReadKey(true).KeyChar == 'r') { break; } }while (nextRunTime > DateTime.Now); Console.WriteLine(string.Format("Looking for items modified after {0} UTC", GetDateStringFromChangeToken(cq.ChangeTokenStart))); ChangeCollection coll = list.GetChanges(cq); cc.Load(coll); cc.ExecuteQuery(); DisplayChanges(coll, cq.ChangeTokenStart); // if we find any changes to the list take the last change and use the ChangeToken as the start time for our next query. // The ChangeToken will contain the Date/time of the last change to any item in the list. cq.ChangeTokenStart = coll.Count > 0 ? coll.Last().ChangeToken : cq.ChangeTokenStart; nextRunTime = DateTime.Now.AddSeconds(WaitSeconds); } while (true); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } }