Question

In a SharePoint site, as you checkout/modify/checkin a master page, previous versions of the master page are retained in SharePoint and you can see a list of previous versions in the master page gallery. It seems to me that the only way to view the contents of a previous version, is to do a restore of that version - this however will create an additional entry in the version history, which isn't really a new version but simply an artefact of viewing a previous version.

I eventually found a rather brute force method of viewing previous versions by using the stsadm utility:

stsadm -o export -url http://site -fileneme export.cab -versions 4

then looking in the manifest.xml file in the cab to then find a pointer to the relevant .dat file in the cab to view the required previous version. Now this 'solution' is obviously problematic for large sites, as the export operation exports the entire site content.

So here's my question ... If stsadm -o export can extract previous versions of files, I'm guessing that there is some way to do this programmatically through the SharePoint API. Does anybody know if/how this is possible.

Was it helpful?

Solution 2

The SPFileVersion class was indeed the way forward. Here's a snippet of code that will export previous versions of the default.master page out to the file system. One thing to note though is that exporting versions[0] doesn't work - it produces an exception when trying calling ver.OpenBinary. I suspect that this has something to do with the whole ghosted/unghosted issue in SharePoint, that the original version of the file is stored differently to subsequent versions. Running this code for other files that were added to the master page gallery, works when retrieving versions[0]. This seems to be an issue only for files that were in the original uncustomised SharePoint site.

    SPFile file;
    SPFileVersionCollection versions;
    SPFileVersion ver;
    byte[] content;
    FileStream fs;
    SPSite site = new SPSite("http://localhost:6000");


    file = site.RootWeb.GetFile("_catalogs/masterpage/default.master");
    Console.WriteLine(file.Url + ", " + file.Length);
    versions = file.Versions;
    Console.WriteLine(versions.Count);

    for (int i = 1; i < versions.Count; i++)
    {
        ver = versions[i];
        Console.WriteLine(ver.VersionLabel + ", " + ver.Size);
        content = ver.OpenBinary();
        fs = new FileStream("c:\\temp\\" + ver.VersionLabel + "-default.master",FileMode.Create);
        fs.Write(content, 0, content.Length);
        fs.Close();
    }

OTHER TIPS

Perhaps you are after the SPFileVersion class. From the versions property of the SPFile object.

See also the SPListItemVersion class.

You should be able to get the masterpage gallery the same as you would any other list.

SPList masterPageGal = myWeb.Site.RootWeb.Lists["Master Page Gallery"];

Here is a powershell version of the code above if anyone is interested:

function ExportVersions([string] $webUrl, [string]$spfilepath, [string]$filePath)
{
  $web = $null
  try
  {
    $web = get-spweb $webUrl
    $file = $web.GetFile($spfilepath)
    Write-host "Url: " $file.Url 
    Write-host "length: " $file.Length
    Write-host "Number of versions: " $file.Versions.Count
    Write-host
    foreach ($version in $file.Versions)
    {
        Write-Host "Version: " $version.VersionLabel
        Write-Host "Size: " $version.Size
        $content = $version.OpenBinary()
        $spFileName = [System.IO.Path]::GetFileName($spfilepath)
        $outFileName = $filePath + $version.VersionLabel + "-$spFileName"
        $fs = new-object System.IO.FileStream($outFileName,[System.IO.FileMode]::Create)
        $fs.Write($content,0,$content.Length)
        $fs.Close()
    }

    $out = "Finished exporting versions for: " + $spfilepath
    Write-Host $out
    Write-Host

  }
  catch
  {
    throw $_
  }
  finally
  {
    # Clean up
    $web.Close()
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top