Omicron Llama

Coding all day, every day.

SPSite, FileNotFoundException and the Server Object Model in Console Applications and PowerShell Scripts

For a beginner SharePoint developer, there can be a fair amount of confusion around the seemingly trivial task of building a C# Console Application to connect to a SharePoint site and to learn the object model. You merely include a reference to the Microsoft.SharePoint.dll assembly, instantiate an object, passing in your site URL and you’re off. Right? Well, hopefully, but you might also get the oft-thrown ‘FileNotFoundException’ when trying this out for the first time (or even, the first time in a while if you’ve been somewhat absent from doing this, or have been rolling around in the delights of PowerShell too long).

First of all you need to ensure your Visual Studio Console Application project is set to build to x64 (or AnyCPU) – this is because your application must be able to load the 64-bit Microsoft.SharePoint.dll assembly (this is the first, legit reason for a FileNotFoundException, it literally can’t find a (64 bit version of a) file.

(Hint: On CodePlex is there’s an amazing toolkit known as CKS Dev (Community Kit for SharePoint) which includes, amongst many other very productive features, a ‘SharePoint Console App’ project template, which streamlines most of this project setup process for you. Definitely something to install if you do a lot of SharePoint Development of any kind). As of time of writing, the Project Templates have yet to be imported in the Visual Studio 2012 but still work grand in the Visual Studio 2010 version).

Next the problem usually is permissions – the security context of your console application (literally, the account you’re logged in as) must have access to the SharePoint environment, and more specifically, the configuration database of your environment.

Lastly, the SharePoint site you’re trying to connect to MUST be local to the server on which you’re running the console application. And it does not matter which Alternate Access Mapping URL you try to connect to.

And this last reason is the main reason for my article. Why must the site be local?

The reason is fairly simple. If you have followed other articles on the web to create Console (or Windows Forms, or Web Services, or anything .NET that’s not a SharePoint project) applications that use the Microsoft.SharePoint.dll, you’re using what’s known as the Server Object Model. You probably already know this, or have read that you’re doing this. You probably are also at least somewhat aware that there is also a Client Object Model out there. And a JavaScript Object Model.

So what’s with this Server Object Model, and why must code that uses it run solely on the server that hosts SharePoint? Also, when you do use this, have you noticed a significant delay when you first open that SPSite connection?

The answer lies in the SPSite object. It has many constructors (6 in total, currently as of SharePoint 2013), but they all essentially do the same thing. Internally, your request to ‘open’ a SharePoint site is passed right down to SharePoint’s internal data connection layer (a native DLL with the obscure name ‘owssvr.dll’), which knows some very specific information about the system that is running your console application. This file can only be found on environments which have had SharePoint installed on them (another reason for the famous FileNotFoundException? Perhaps, but there is also a COMException that can be raised for when this dll can’t be found)

Whichever constructor you choose to use, the SharePoint internal code ‘asks’ the local server where the configuration database is. It needs to do this because it has to ask it in which content database the SharePoint Site Collection with URL http://xyz or with Guid abcdef-… exists.

Therefore, if you try to write a simple console application, and pass in the the URL to a SharePoint site that it NOT on your development server, you are basically asking SharePoint to find a Site that is registered on your local server.

This story is exactly the same if you try to run a PowerShell script against a SharePoint Site URL that is not a part of the server’s SharePoint Farm (there is an exception to this, namely for Office 365 hosted SharePoint Online).

If you do actually intend to run your application on another server, then make sure the site collection URL is a parameter for your application somehow.

If you need to interact with SharePoint and run a program that will NOT be running on the SharePoint server itself, then you will need to learn either the Managed Client Object Model, or one of the many Web Services that are now available (Classic (asmx) Web Services reference, ListData.svc REST endpoint,  SharePoint 2013 REST _api [awesome, check this one out]).

Notice that I didn’t mention the JavaScript Object Model in that list. There is a reason for this also. I might go into this in detail in another article, for now it’s similar to the Server Object Model problem – the SharePoint JavaScript Libraries are loaded only from SharePoint Sites, and can only run within pages that are hosted in the SharePoint site, as they make calls to internal web services that exist on the same SharePoint Site that is serving the page the code is running on. Confusing? I’ll try to explain in another article by showing you what happens when you try to include SP.js outside of SharePoint sometime.

But for now,  I hope that clears a few things up for new developers.

5 thoughts on “SPSite, FileNotFoundException and the Server Object Model in Console Applications and PowerShell Scripts

  • Reading over your last paragraph, I was reminded of this article:

    http://allthatjs.com/2012/04/03/using-sharepoint-csom-in-html5-apps/

    That seems to have solved the riddle of using CSOM/JSOM in a page that isn’t hosted in SharePoint. Have you seen this article before?

    Cheers,
    Matthew

  • James Love says:

    I’ve not no, that’s pretty cool. But the page still needs to be hosted in SharePoint, although it’s not using the full SharePoint chrome. You can’t have a page hosted on another site that uses the JavaScript Object model, as the libraries it needs are protected within SharePoint, and the internal web service calls are relative to the page the JavaScript is loaded on.

  • Nandini says:

    Hi , This is a very good article. Do you mean to say you “cannot” to a remote sharepoint 2010 url from a concole/windows app when you are using SharePoint2010 server Object model.?
    My Scenario is I have a windows app doing some admin opertion (backup /restore) so I need to use sharepoint server object model.
    Now if I try to access a site which is a different server but same network I get error in spsite() call.

    Any suggestion would be really helpful

    • Jimmywim says:

      Hi Nandini,

      This is correct. You cannot connect to a SharePoint URL that is not installed on the system that is running the code, when using the server object model. The server object model will always assume that SharePoint is running on the server that is running the code (that’s calling the server object model).

      There is no current out of the box way to perform a backup of a site collection remotely in SharePoint. There may be a commercial tool that can do this but I’m not currently aware of one (and I’m not sure what API set it’d use either). Feel free to ask a question on SharePoint Stack Exchange, there may be others who’ve had a similar requirement.

      • Nandini says:

        Thanks Jimmywim.
        I was under the assumption since both the servers are in same network and domain , SPSite will be able to connect to remote URL from other server.And also since the url was browasble from IE.
        Thanks for the reply!

Leave a Reply

Your email address will not be published. Required fields are marked *