Subscribe to News feed

Automatically mirror / sync a SharePoint folder structure using the Workflow Power Pack

Posted at: 9:05 AM on 23 December 2009 by Muhimbi

Mirror Quite a few of our customers use a SharePoint Designer workflow to automatically create PDF files whenever a document is created or modified in a SharePoint Document Library. Some of these customers want to use the same directory structure for the source files as well as the converted files.

The problem that we’ll address in this posting is how to automatically synchronise the two directory structures using the Muhimbi Workflow Power Pack and a small script.

A quick introduction for those not familiar with the product: The Muhimbi Workflow Power Pack for SharePoint allows custom C# or VB.NET code to be embedded in SharePoint Designer Workflows without the need to resort to complex Visual Studio based workflows, the development of bespoke Workflow Activities or long development cycles.

The script we’ll develop is executed every time a file is created anywhere in a document library. The file’s path will be extracted and replicated in the destination Document Library. Ideally we would only like to trigger this workflow whenever a new folder is created, but using SharePoint designer it is not possible to trigger workflows for folders.

At the end of the custom activity the destination path is returned to the workflow, from where it can be used for further processing.

Create the workflow as follows:

  1. Download and install the Muhimbi Workflow Power Pack for SharePoint.
     
  2. Make sure you have the appropriate privileges to create workflows on a site collection.
     
  3. Create a source and destination Document Library. Alternatively use the same Document Library for the source and the destination, just create a new folder in the root to mirror the folder structure to.
     
  4. Create a new workflow using SharePoint Designer.
     
  5. On the Workflow definition screen associate the workflow with the Source Document Library  and tick the box next to “Automatically start this workflow when a new item is created” and proceed to the next screen.
     
  6. Click the Actions button and insert the Execute Custom Code action.
     
  7. Click this variable and create a new Workflow Variable named destinationPath using string as the type.
     
  8. Insert the following C# based code by clicking this code.
     
    SPList sourceList = MyWorkflow.List;
     
    // ** The destination Document Library (optionally point it to a different site collection)
    SPList destinationList = MyWorkflow.Web.Lists["Some Destination DocLib"];
     
    // ** If the destination directory structure should not start in the root directory, enter
    // ** the folder path to the root destination folder here
    string rootFolderName = "";
    string destinationListURL = destinationList.RootFolder.ServerRelativeUrl + rootFolderName;
     
    // ** Generate a list of folders for the current item
    SPListItem sourceFile = MyWorkflow.Item;
    Stack<string> folders = new Stack<string>();
    SPFolder folder = sourceFile.File.ParentFolder;
    while (folder.Name != string.Empty)
    {
        folders.Push(folder.Name);
        folder = folder.ParentFolder;
    }
     
    // ** discard the first as it is the name of the Doc lib itself
    folders.Pop();
     
    // ** Iterate through the list of folders in reverse
    while(folders.Count != 0)
    {
        string folderToCreate = folders.Pop();
        // ** Check if the folder already exists, in which case no action is required
        folder = destinationList.ParentWeb.GetFolder(destinationListURL + "/" + folderToCreate);
        if (folder.Exists == false)
        {
            // ** Create the new folder
            SPListItem newFolder = destinationList.Items.Add(destinationListURL, 
                                                SPFileSystemObjectType.Folder, folderToCreate);
            newFolder.Update();
        }
        destinationListURL += "/" + folderToCreate;
    }
     
    MyWorkflow.ReturnValue = destinationListURL;
       
  9. Update the destinationList and rootFolderName variables to match your situation.
     
  10. Click the Actions button, select Log to History List, click this message, set the Source to Workflow Data and the Field to destinationPath.
     
  11. Close the Workflow Designer and add an item somewhere in a nested folder in the source Document Library to trigger the workflow.
     
  12. Once the workflow has finished, click the Completed link to see which path the new folder has been created in. Check that the destination folder(s) have been created by navigating to the Destination Library.
     

mirrorFolders

 

In case you want to use this in combination with Muhimbi’s PDF Converter for SharePoint then you can use the path returned in the destinationPath variable and use it as the destination URL in the Convert To PDF workflow activity. If you want to use it in combination with something else, then use it as you see fit.

Note that a small change may be required to the script, or perhaps as a Custom Code Condition, if the source and destination Document Libraries are the same and files will be written to the location specified in rootFolderName. Otherwise the folder structure inside the destination folder will be mirrored in the destination folder, just at a deeper level.

.






Labels: , , , , ,

2 Comments:

  • Hello,

    I would like to know what is the code to create a simple folder in a Document Library ??

    Thanks in advance !! :-)

    By Anonymous Anonymous, At 04 January, 2010 13:21  

  • Creating a folder in a document library can be done using the code outlined below. It expects the path to create the folder in in Parameter 1 (use / for the root directory) and the new folder name in Parameter 2.

    If the folder already exists the request will be ignored:

    SPList destinationList = MyWorkflow.List;

    string folderPath = MyWorkflow.Parameter1 as string;
    string newFolderName = MyWorkflow.Parameter2 as string;

    folderPath = folderPath.Trim(@"\/".ToCharArray());

    if(folderPath != string.Empty)
    folderPath = "/" + folderPath;

    string destinationListURL = destinationList.RootFolder.ServerRelativeUrl + folderPath;

    SPFolder folder = destinationList.ParentWeb.GetFolder(destinationListURL + "/" + newFolderName);
    if (folder.Exists == false)
    {
    SPListItem newFolder = destinationList.Items.Add(destinationListURL, SPFileSystemObjectType.Folder, newFolderName);
    newFolder.Update();
    }

    By Blogger Muhimbi, At 04 January, 2010 14:02  

Post a Comment

Subscribe to Post Comments [Atom]

Links to this post:

Create a Link