Monday, August 12, 2013

Solving Office 365 SkyDrive Pro Sync Problem (error 0x80040208)

SkyDrive Pro eases the process of uploading lots of files into a SharePoint document library - but can stop working if a file added to the SkyDrive Pro folder has a name that is longer than 64 characters.

When a file with a long file name is dragged into the SkyDrive Pro folder, you may find that anyone with a folder mapped to the associated SharePoint document library start seeing messages about syncing problems. The SkyDrive Pro folder icon will also show an error in Windows Explorer.

One way to see if long filenames could be causing these problems is to search for all files in a library with long file names. To find all such files for a client, I created the following JavaScript that uses a CSOM (Client Side Object Model) query to get all files in a library (even if the files are located in folders in the library) and to display a list of all the problematic file names.

To use this code, add a new page to your site, edit the page and add "embedded script" into that page. Edit the source of that script, and paste the following HTML into the page - be sure to adjust the value in hostweburl to match the URL of your Office 365 site, and the value in documentLibraryTitle to match the display title of the document library you wish to test.

For more notes on the code, see my article at on this subject on my site

This code could be extended with a little work to offer all the document libraries in a site in a dropdown - if you have any ideas for extensions, or want help with the code, please leave a comment
<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
    var hostweburl; //Web URL
 var ctx; // Client context
 var documentLibraryTitle = 'Documents'; //The title of the document library in which to seek long filenames

    $(document).ready(function () {
  //Full URL to the Office 365 site collection root web
        hostweburl = 'https://yoursite.sharepoint.com';
        // The js files are in a URL in the form: web_url/_layouts/15/resource_file
        var scriptbase = hostweburl + "/_layouts/15/";
        // Load the js files and continue to the execOperation function.
        $.getScript(scriptbase + "SP.Runtime.js",
            function () {
                $.getScript(scriptbase + "SP.js", execOperation);
            }
        );
 });

 //Main process, runs once the SP.Runtime.js and SP.js files have dynamically loaded
    function execOperation() {
  ctx = new SP.ClientContext();
  retrieveItems();
    }

 function retrieveItems() {
  var clientContext = new SP.ClientContext();
  
  this.oList = clientContext.get_web().get_lists().getByTitle(documentLibraryTitle);
   
  //Could use the following to create the query text "<View Scope='RecursiveAll'><Query></Query></View>
  //var camlQuery = SP.CamlQuery.createAllItemsQuery();
  //BUT this does not sort, and we need to sort by folder here
  
  var camlQuery = new SP.CamlQuery();
  //Get all documents from all folders
  var query = '<View Scope="RecursiveAll"><Query><OrderBy><FieldRef Name="FileDirRef" /></OrderBy></Query></View>';
  camlQuery.set_viewXml(query);
  
  this.collListItem = oList.getItems(camlQuery);

  //Only get the title and path information in order to reduse size of returned data
  clientContext.load(collListItem, 'Include(Title,FileDirRef,FileLeafRef)');

  clientContext.executeQueryAsync(
   Function.createDelegate(this, this.onListItemsQuerySucceeded), 
   Function.createDelegate(this, this.onListItemsQueryFailed)
  );
 }

 function onListItemsQuerySucceeded() {
  var titles = '';
  var listEnumerator = this.collListItem.getEnumerator();
  var loopCount = 1;
  var prevFolder = 'zzz';
  while (listEnumerator.moveNext()) {
   var oItem = listEnumerator.get_current();
   var fileName = oItem.get_item('FileLeafRef');
   var folderUrl = oItem.get_item('FileDirRef');
   //If the filename is longer than 63 characters, display a message
   if (fileName.length > 63) {
    if (prevFolder != folderUrl)
    { titles += '<div style="font-weight:bold;"><a href="' + hostweburl + folderUrl + '" target="_blank">' + folderUrl + '</a></div>'; }
    titles += '<div style="padding-left:10px;">' + fileName + '(length: ' + fileName.length + ')</div>';
    prevFolder = folderUrl;
   }
   loopCount++;
  }
  AddMessage(titles);
 }

 function onListItemsQueryFailed(sender, args) {
  alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
 } 
</script>

<div id="results"></div>

No comments: