Cottleston Pie

Fernando Felman’s thoughts on software development

Archive for February, 2008

Visual Studio extensions for Windows SharePoint Services v1.1

Posted by Fernando Felman on February 12, 2008

Funny, just as I publish the how to install VSeWSS on a workstation, the good guys from Redmond announced the new version. Main changes that I’m keen to investigate: bug fixes and features support. You can download the new version from here which now also comes with a user guide. Just like the previous version, you should install this new extensions on a local SharePoint machine. That is, unless you feel like hacking it. 🙂

And while we’re on the subject of MOSS, check out Javed Sikander’s video on OBA Composition Reference Toolkit on Channel 9. I’d really like to see where this thing is going to be in, say, another 2-3 months. I think it really has the potential of bringing forward the biggest advantage of MOSS which, in opinion, is a rich platform for custom collaboration solutions. This toolkit is a huge step towards implementing the concepts I’m used to see from the patterns & practices group to match the SharePoint development world. Very cool.

Posted in Moss, VS2005 | Leave a Comment »

How to install the SharePoint 2007 VS 2005 Extensions on a Workstation

Posted by Fernando Felman on February 11, 2008

SharePoint 2007, or MOSS, is a server product and as such it can only be installed on the Windows Server family platform. I can understand that, it makes sense. What I can’t understand and doesn’t make any sense at all is that I’m not allowed to install the development tools on my new shiny Vista.

The recommendation for MOSS development was always to get a VM to run W2k3 with MOSS and Visual Studio. That’s all fine when you’ve to develop and do cycles of compile-deploy-debug, but what if you want to load an existing web part project with the visual studio installed on your workstation?

If you try to install the Visual Studio 2005 Extensions for Windows SharePoint Services 3.0 Tools (VSeWSS) on a workstation you’d probably fail and get the following error: “This product can only be installed if Windows SharePoint Services 3.0 has been installed first”. So the only thing we’ve to do is to hack the installer into thinking MOSS is installed. How difficult can it be, right?

Before continuing into opening the Regedit tool, be aware that mocking around with the Windows registry is not supported, not recommended and generally considered bad manners.

Now open the regedit and create the following keys and the string value:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0]

"Sharepoint"="Installed"

That’s it! You have fooled the installer into running on a workstation. Easy. I also recommend adding the core SharePoint assemblies into the CAG using gacutil. Those assemblies can be found by default in any ShaerPoint machine under the folder: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI.

If you’re feeling adventurous enough and want to get the full remote debugging experience, try out this excellent Martin Vollmer’s post.

Posted in .Net v2, Moss, VS2005 | 33 Comments »

HOW TO: Check the Type of a COM Object (System.__ComObject) with Visual C# .NET

Posted by Fernando Felman on February 5, 2008

This one is a favourite of mine since I tried to resolve it in the past with no success.

The problem at hand is that we have a COM object o returned from Excel interop and we have to figure out what underlying interface it implements. If you try to use GetType() you’ll get a __ComObject which does not provide any helpful information as to what underlying types are implemented by the object.

The following KB article sheds some light: http://support.microsoft.com/kb/320523. The suggested way in the article is to manually cast the object to any known type using the as directive and if a valid object is returned – that type is implemented by the object. This solution will work, but it’s utterly ugly and requires vast amounts of typing in order to support all the possible types. I needed to implement something similar without using manual casting, essentially I needed a method that receives a COM object (of the type __ComObject, assuming it was created by the Excel interop) and returns the underlying interface supported by that object.

First I thought to somehow ask the object to provide me with a list of implemented interfaces. Something like the System.Type.GetInterfaces method. The problem is that the type of the object does not expose any useful information and the object itself has no typed class, so that proved to be futile.

Then I thought that instead of getting the implemented types from the object, I can query all the existing types one by one. Sure, it’s not as pretty as the previous path but that’s actually how COM works by design. Every COM class implements the IUknown interface which supports the QueryInterface method used to get a pointer to where an interface is implemented in the class. The idea is that all the information about what methods are supported by the interfaces and what interfaces are implemented by a type should be acquired in advance and coded into the caller (IDL, TLB and h files comes in mind). There was no true run-time reflection in the old COM days.

.NET supports COM by means of interoperability proxies. I won’t get into too many details, but basically you get .NET objects typed as __ComObject mapping COM instances and .NET interfaces with some unique attributes mapping COM interfaces. More to the point, you get the System.Runtime.InteropServices.Marshal class to handle all bunch of COM and interop operations such as calling the QueryInterface method on a .NET object mapped to a COM instance.

So now we know that we can query interop interfaces against the object. Sweet. But in order to do that we need the Interface ID, or iid, which is the GUID identifying an interface in COM. Oh, and we need that for each end every COM interface implemented by the Excel interop. Not sweet. OK, but we’re in .NET world now (thanks to the System.Runtime.InteropServices namespace) which has great support for runtime reflection. How difficult would it be to enumerate all the COM interfaces implemented by the Excel interop? Not too difficult really, we can use the System.Reflection.Assembly class to get a handler to the Excel interop assembly and from there it’s relatively easy going.

So let’s conclude what we need:

  1. Get all the COM interface types exposed by the Excel interop assembly.
  2. Fetch the Interface ID of each type and use it on QueryInterface to test whether an interface is implemented by the object (if a valid pointer is returned, the interface is implemented by the object).

This doesn’t sound too complicated. Obviously there are some syntax and plumbing issues to address, but the concept is rather simple. Good, let’s implement it:

GetExcelTypeForComObject method

Namespaces:
using Excel = Microsoft.Office.Interop.Excel;
using interop = System.Runtime.InteropServices;

Note that in many cases a wrapped COM object implements many interfaces, so breaking after the first implemented interface is found might not do it for you…

Posted in .Net v2, Samples, vs2003, VS2005 | 20 Comments »