This week I’ve been creating some integration code between our web product (an ASP.Net web forms app) and LDAP – or more specifically, Active Directory. This involves loading principals (groups and users) and OU’s from AD into our custom database and updating them on a schedule. In the past I have used System.DirectoryServices to do any work with AD, and this has been, to say the least, not one of my favorite things in life to do. It seems like the people who invented LDAP have brains that don’t work the same way as ‘normal’ geeks – at least, not the same way as me. So, I was very pleased to discover System.DirectoryServices.AccountManagent. This provides a higher level of abstraction over LDAP’s and makes the simple tasks much simpler. Firstly, you create a context. I have some properties and a helper method for this: private ContextType ContextType { get; set; }private string OU { get; set; }private string DomainOrMachineName { get; set; }private string UserDName { get; set; }private string Password { get; set; } private PrincipalContext CreateContext() { if (this.UserDName != null && this.Password != null) { return new PrincipalContext(this.ContextType, this.DomainOrMachineName, this.OU, ContextOptions.SimpleBind, this.UserDName, this.Password); } else { return new PrincipalContext(this.ContextType, this.DomainOrMachineName, this.OU); } }
ContextType is an enum of Machine, Domain or ApplicationDirectory. For a simple domain AD you want Domain. ApplicationDirectory is for AD LDS (what was once called ADAM).
The OU is the root OU you want to work with.
UserDName is a user account’s distinguished name, eg: CN=Administrator,DC=domain,DC=com.
The helper method will use the UserDName and Password if specified, otherwise it will do a normal binding – using Negotiated credentials if available. If you are talking to a remote AD not in your local domain then you will probably need to use the SimpleBind method – I found this the easiest.
To get a list of groups from a domain via this context is now trivial: using (var pc = this.CreateContext())
{
var gp = new GroupPrincipal(pc, "*");
var ps = new PrincipalSearcher(gp);
foreach (GroupPrincipal g in ps.FindAll())
{
Console.WriteLine(g.Name);
}
}
This little snippet will output the names of the groups under the specified OU. However, it will only list the top level groups – not groups within groups. To do that, we need to get recursive.
using (var pc = this.CreateContext()) { var gp = new GroupPrincipal(pc, "*"); var ps = new PrincipalSearcher(gp); foreach (GroupPrincipal g in ps.FindAll()) { Console.WriteLine(g.Name); listNestedGroups(g, "-"); } } void listNestedGroups(GroupPrincipal gp, string indent) { foreach(var p in gp.members) { if(p is GroupPrincipal) // could also be a user { var g = p as GroupPrincipal; Console.WriteLine(indent + g.Name); listNestedGroups(g, indent + "-"); } } }
You can use the same objects to create and manipulate LDAP entities similarly easily.
Like all good things though, there’s a couple of issues. When dealing with users, I needed the middle name (Initials in AD). The UserPrincipal includes a property for this, but it comes through empty. Luckily, it’s easy enough to fall back to the old way of getting the extra properties. The GetUnderlyingObject() method returns the DirectoryEntry instance:
var de = userPrincipal.GetUnderlyingObject() as DirectoryEntry; if (de != null) { var lastChangeDates = de.Properties["whenChanged"]; if (lastChangeDates != null && lastChangeDates.Count == 1) { var lastChangeDate = (DateTime)lastChangeDates[0]; var initials = u.MiddleName; if (initials == null) { var initialProps = de.Properties["initials"]; if (initialProps != null && initialProps.Count == 1) { initials = (string)initialProps[0]; } } } }
There’s a bunch of documentation on MSDN for this but I also found some code snippets on StackOverflow.
Another useful tip, get the SysInternals AD Explorer. It shows you a lot more information that the User and Group tool in AD.
Enjoy!
A month on from starting my new job I have noticed a few changes in my attitudes and practices. Working for an exclusively Microsoft shop in the past hadn’t given me a completely closed minded attitude but it did remove opportunities to work with other things. What I have found since joining ARANZ is the that other options tend to work quite well. In particular, we use SVN for source control, Fogbugz for issue tracking and work items and CruiseControl.Net for build automation. This combination works well enough for a small team and since the setup was already done a long time ago, I’ve only had to tweak a few things in CCnet and learn how to use SVN. In my previous mind-set as a Microsoft zealot I would have said that complete integration was the logical solution and TFS was the best product for dev teams. I still believe TFS is a great product but for the sort of work we do here and many other larger teams, it’s really not necessary. In fact, I heard at a local user group meeting last night that TradeMe use the same combination of SVN and Fogbugz. I guess what I’m trying to say is that I’m much more relaxed about using ‘lesser’ products and making do with a lower level of integration. TFS is quite a heavy product. It provides some great benefits but at the cost of freedom and flexibility. Sure you can customize till the cows come home but the old adage of less is more applies I think. Monolithic, heavy weight beasts like TFS take time to learn and understand. Lightweight systems are much easier to understand and tweak – you just have to do a little more of the lifting work yourself. I’ve also come to notice a few things where Microsoft have dropped the ball. Actually, that’s being kind. With Windows CE/Mobile/Embedded/whatevertheycallitthesedays they have screwed up completely. This is probably old news to most people but I was blissfully unaware how shitty the situation is with mobile development. There is no tooling beyond Visual Studio 2008 unless you want to switch to Phone 7 and it’s useless for many business apps. There is also no easy upgrade path – it’s a complete rewrite for much of an application. I have my money on Phone 7 being a dead duck within 2 years due to the growth of Andriod as a platform and Microsoft’s lack of haste and clarity. Android works on many types of devices, it’s development tools are fine and free and it’s already the most popular for mobile devices. Google also seems to have more of an emotional investment in this area and I don’t get that feeling from Microsoft. Thanks must go to Apples for coming up with a UX that works on phones. Everyone else that has copied this has done well. Microsoft’s attempt to do something different will leave developers out on a limb with Steve Ballmer holding a saw at the trunk.
When you work for a company that makes it’s own hardware, you get little surprises sometimes. I found this in our office refrigerator this morning:  It’s a camera undergoing a coldness test I guess.
The long awaited upgrade to the OpenXMLDeveloper site is finally live. I’m not a huge OpemXML developer myself but I do/did have an interest in this site This is a huge improvement over the previous site and hopefully it will be more valuable.
Having a single unified version number across all assemblies in a product has always been an issue for me and I suspect many others. For some reason, this has been a lot harder to achieve than it should. I suspect the reason has been more to do with me than the tools… Anywho, this morning I managed to solve the problem for our product and the new WIX based installer. Here’s the steps I used. Create AssemblyInfo files for the Company and Version. I created a CompanyAsseblyInfo.cs file that looks like this: using System.Reflection; using System.Runtime.InteropServices; [assembly: AssemblyCompany("ARANZ Medical Limited")] [assembly: AssemblyCopyright("Copyright © 2007")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] And a VersionAssemblyInfo.cs file that looks like this: using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [assembly: AssemblyVersion("3.0.*")] #if PocketPC || WindowsCE #else [assembly: AssemblyFileVersion("3.0")] #endif
I added these to a solution folder. In each published project in the solution I add these files as a link:  Then I removed the duplicated entries from the project’s default AssemblyInfo.cs file. Now I have a single file containing the version number and company information. WIX doesn’t used these files of course, but that’s not a problem thanks to a nifty WIX Extension I found on CodePlex. Simply reference this dll in your WIX project and update your Product.wxs file like this:  Now whenever I do a build – either locally or on our build server – all the assemblies and the installer will have the same internal version number. No need to futz around with MSBuild or CruiseControl tasks. Of course, I still need to manage the version number manually for major upgrades but our daily builds in a sprint or iteration will be automatically incremented. Enjoy! Update: So it turns out the Visual Studio and MSBuild too I guess, do not do a very good job of incrementing the build and revision numbers automatically. Some of the assemblies in the solution were being generated with a version number of 3.0.0.0 despite the AssemblyVersionNumber being 3.0.*. To get around this required some work in CruiseControl. Firstly, I created a VersionNumber.proj file in the solution that looks like this:  This uses the MSBuild Community Tasks for it’s Version and FileUpdate tasks. Next, I updated the CruiseControl config to use MSBuild to execute this script prior to building the solution:  Lastly, I installed MSBuild Community tasks to the build server and restarted CruiseControl. For some reason it was not able to find the .targets file in the MSBuild directory to I copied this to the working folder also. This is such a drag, but at least it now works and I still have a single place to update the version number.
I rely heavily on the WIX tutorial site when ever I need to create an installer. It’s not something I do every day of the week so the tutorial site is essential to me. Over the last week I’ve been using it a lot but there’s been a few problems with the site and the server (500 errors etc). This morning, to my surprise, the site has been updated and moved to a new server. It has a new look, it seems quicker and best of all, there are no more errors . To all the people that contribute to this site and it’s content – which is totally advertisement free! – I thank you for saving my life many times over the years. Keep it up!
I don’t often use log4net – at least, I use it on just about every project but I only set it up once every few months – so remembering the schema for the configuration is a drag. Thankfully, a generous geek has created a schema for the config. You can get it here. After you download it, copy it to your Visual Studio Schemas folder. For VS 08 this is C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas. For 2010, it’s probably C:\Program Files\Microsoft Visual Studio 10.0\Xml\Schemas. Then with your web.config/app.config open in VS, view the properties and set the schema to include this.  No need to restart VS, it will automatically detect the new schema in the folder. Intellisense will then tell you all you need to know.
I’ve had one full week with my new employer, ARANZ Medical. So far so good. Compared to many 1st week’s I’ve had (and there have been a few of them!) it went surprising smoothly and I felt useful from day 1. My orientation lasted about 2 hours then I was into finding my way around the development environment and code base, then some bug fixes. A bit of ASP.Net web forms, some Silverlight and some Windows Mobile. By Friday I was creating new features and I’m in the process of reimplementation of an installer using WIX. I’ve also had a week to compare the differences between a service company and a product company. Firstly the advantages. - No time tracking. Accounting for every 6 minutes of the day becomes second nature after a while and I hope to retain some of my internal prioritisation that this gave me, but I believe it is unrealistic to impose constant pressure on developers and expect quality code. There has to be some leeway for experimentation and time for a brain to work.
- Second chances. The chance to upgrade a product means you get an opportunity to improve things. The constant merry go round of projects in a services company seldom allows for version 2 and many customers have the unrealistic expectation that we could deliver the perfect solution on the first attempt. This situation was often initiated by sales people and left to the developers and project managers to refactor fantasy into reality.
- Creativity encouraged. Finding new an interesting applications for a technology and product creates opportunities and opens new markets. The focus with a service company is on delivering exactly what the custom is paying for an not a gram more. NO GOLD PLATING! With a product you want shiny stuff, but of course, there is still a budget to worry about – it just takes the form of a backlog rather than a sum of money.
There are a couple of specific advantages in my particular situation: - No SharePoint. I’ve said it before but now I can say it without worrying about upsetting sales people. SharePoint is a shit development environment. It’s a great platform as long as you keep things simple. I’ve been guilty of over complicating things from time to time, but with SharePoint you have no choice – it’s too complicated for the small things and too large to be simple.
- My own desk. I don’t want to ruffle feathers but someone has to say something. It was a stupid idea to start with. Putting all your developers together on long benches does not improve communication and productivity. Everyone I spoke to hates the idea and the feedback from other offices is the same. Justification for this stupidity can only be financial because it makes no sense any other way.
There are of course disadvantages to a product company when compared to a services company: - Same same. The product is what we work on. One product at a time. For months or years. In a service company you get to work on many projects a year – sometimes you like ‘em, sometimes you hate ‘em. The variety keeps you going but it also wears you out.
- Less opportunity? Yes and no. Not sure yet but I’m assuming that people stay around longer so there is less movement. In my particular case, I’m happy with this. I’ve reached the stage in my career (life?) where I’m happy to do what I do best. I’d like to do more but I really don’t want the extra stress that often goes with extra responsibility.
That is my impression after one week. It will be interesting to see what else pops up after a few more.
If I was a vegetarian I would be insulted. As a carnivore I feel embarrassed. Either way, this is classic. 
Today I spent a little time trying to setup an Intranet at home. Using the Web Platform installer it’s a snap to select, download and install a veritable plethora of CMS and other tools and platforms. I decided to have a go with Orchard. Why? Because it’s new and cool and uses MVC 3. Of course, I would expect some issues and challenges but it’s been around for a few months and reached version 1.1 so, what could possibly go wrong? Well, I was working my way through adding a few modules and trying to understand how layers, content types, content parts etc fitted together to make a web site. Then bam! Object reference not set errors. I had installed a module that was less than stable. So much for that. I couldn’t uninstall. All I could do was scratch it and start again. Second attempt, lets try something a bit more mature, Umbraco 4.7. The download and install is very slick, 5 steps, select a starter kit, wait for it to download and install. BAM! Timeout. Hmm, try refreshing the page and it seemed to carry on ok. Double BAM!! Table not found! Crap. Delete folder, try again. This time, no timeout, but BAM! Table not found! For F’s sake! Taking a look around the forums I find that yes, using the Personal or Business starter kits with SQL CE there is a bug in the SQL code. This is very lame! 4.7 has been out for a while. This is supposed to be a professional OS product. So, back to plan A. I think I’ll create an intranet myself using Visual Studio and MVC 3. At least then I wont have to rely on others… I can make my own mistakes and fix them straight away.
I’ve started work on a personal project and I’ve decided to use Entity Framework 4 – 4.1 actually – despite a lot of pain in a recent project. Previously I used the Entity Designer Data Generation Pack. This is an extension you install from the VS 2010 Extension Manager. It gives you a much nicer experience when generating the database schema. You have a few more choices about how the database tables are structured. In particular, you can choose table per type or table per hierarchy. I quite like the table per hierarchy template especially when using inheritance. Without this, you can get some silly empty tables. Anyways, since SP1 and EF 4.1, the Entity Designer Data Generation Pack does not work. There’s a bit of discussion on the gallery site and a fix is coming soon. I also found a link from here to project Juneau. This looks really exciting and offers some very nice features such as automatic database generation and synchronisation between database projects and entity models. However! I cant help thinking that this and the EF are very elegant tools that solve a problem we shouldn’t be having. That is, object persistence. In the ideal world I would like to create an application that is composed of objects and have these persisted for me in some magic way that is efficient, scalable and reliable. I don’t want to know anything about SQL Server or even entity models for that matter. What’s wrong with having simple classes with a few attributes to indicate some persistence? Of course, we don’t live in a perfect world. This is why there will always be a place for SQL Server, SharePoint and Lawyers. Juneau does remove a few nasty steps and offers some nice features. You should checkout the video.
I’m deploying a Telligent Community site from our development staging VM to a properly setup UAT site in preparation for go-live. The dev VM was running on my Dell Desktop and shows up in the Computer Properties thusly: On the official platform is shows up like this: I installed the site as per the instructions from Telligent which basically involves copy and paste and manual creation of a App Pool and Site in IIS. When I run the site on the official platform, I get the following error: HTTP Error 500.0 - Internal Server Error Calling LoadLibraryEx on ISAPI filter "c:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_filter.dll" failed Right so, this is where confusion sets in. The app pool is configured for .Net 2 so why is this error referring to a .Net 4 assebly? The event log has the following: ISAPI Filter 'c:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_filter.dll' could not be loaded due to a configuration problem. The current configuration only supports loading images built for a AMD64 processor architecture. blah blah… Ok, now this is clearly silly as it works fine on my machine and I didn’t build the assemblies so there ain’t much I can do about it. Poking around in the App Pool settings I noticed this: It’s turned off on both machines but I figured, what the heck, lets give it a try. Sure enough, setting Enable 32-bit applications to True fixes the problem on the UAT server. I can only think this is a platform error – either it’s the different CPU or it could be the edition of Windows Server. Either way, it’s fixed and I’m filing this nugget of wisdom for future reference.
It’s been a fun packed few years (5 to be precise) at Intergen but the time has come for a change. In a weeks time I will be starting with ARANZ Medical. In the last five years I have worked on many exciting and fulfilling projects for a great range of customers. I can safely say, with hand on heart, that ALL of the work was interesting & rewarding and most of it was challenging and & fun. Before I started at Intergen I had not done many web site projects (I can probably count them on 2 fingers) but since then I’ve worked on dozens (if you count SharePoint as just a web site). I’ve worked on projects for small and very large companies in NZ and elsewhere. I spent 6 months in Sydney. I’ve been to a couple of TechEd’s in Auckland and a PDC in LA. But most importantly, I’ve worked with some extremely talented and fun people whom I will miss greatly. All good things must come to an end though, and hopefully something equally as good comes along to replace it. ARANZ Medical promises to be such a place. I’m not entirely sure what is in store for me but I’m excited about working for a company with a product focus. Its something I have always wanted to do and it’s great to get the opportunity to do this for a company with such an interesting product line. It will also be nice to downsize a little to a company where I can possibly make a difference. It’s interesting to see how companies work and change over time and as they grow. When I started at Intergen Christchurch I was the 12th employee I believe. They are now thrice this size and growing rapidly. They have also moved offices three times in the five years – only one of which was caused by a natural disaster! When I started, bespoke web site work was the norm for small-ish businesses and small budgets. This has been replaced with much larger budgets, bigger customers and enterprise scale projects spanning months rather than weeks. All the best for the future Intergen. I will remember you fondly 
I’m working on some security cruff for WCF and SharePoint at present and I stumbled across this gem: MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10; Just rolls off the tongue don't it? Gotta love those Microsoft devs 
Here's my story of yesterdays earthquake here in Christchurch, before I forget and to add some more personal detail to the limited news available via the media. When the quake struck I did the usual thing - I backed away from the desk and started to consider weather I should get under it or not. Unlike other shocks, it was immediately apparent that I should hit the deck, which I did. About a second later my window shattered and covered my desk with large chucks of glass. The initial hit didn't seem to last more than maybe 10 seconds and I guess the rolling and tremors continued for a while afterwards, but I was too busy gathering my wallet, glasses, keys etc. to notice. A quick glance around the my colleagues confirmed there were no injuries so while others were debating weather to stay or go I was gallantly descending the fire escape as high speed. Out on the street the extent of the quake became immediately apparent. There was one person lying in the middle of the road, with a police man and others in attendance. A scaffold erected on the roof of a hotel (189 Hereford street) had collapsed and was hanging precariously over the edge of the building threating to fall to the street. Many windows were broken and there was glass on the road. A few more decent shocks hit while we were gathering on the street and once we had confirmed everyone had got out ok, we decided to head for Latimer Square, which was the closest open space. My youngest daughter Deanna attends Unlimited school which is in the centre of the city, less than a block from my work. I had seen her about 20 minutes before the quake and I knew she was returning to school so instead of heading to Latimer Square I walked around the block to see if I could find her. Mobile communication by this stage was useless. I did managed to get a 'U Ok?' text out to her, but had no reply. My wife Trish and our older kids, Michelle and Robert were out of town thankfully but communication with them was worse as they were in a rural area with no cell phone services. Walking down Hereford and Manchester street I could see several piles of rubble. Some from previously damaged building but also some from buildings that had re-opened from the September and Boxing day quakes. Passing the Grand Chancellor Hotel building in Cashel street, I could see several people standing at a broken window and I initially wondered by they weren't getting out. I then looked below then I could see several large cracks in the support structures of the Hotel and looking further there was an obvious lean on the whole building. Clearly the escape exits were blocked and these people were trapped. Turning around I checked the Westpac bank building which was heavily damaged in September. This looked ok. In the Cashel and High Street mall I found a large crowd, mostly of children from the school. There was a lot of emotion coming from the kids but also a constant noise of breaking and falling glass. The whole area was particularly unsafe. I then notices the Link Centre arcade, which is the normal route I would take between Hereford and High street. This seemed have been badly damaged. People were being carried and dragged from the entrance, once of which was clearly unconscious with blood around his mouth. His rescuers were calling frantically for someone who new CPR. At this point in time, the situation got the better of me and I decided to do my bit by calling out to everyone to get out of the city. I acted like some crazed fool for about 30 seconds. Not my proudest moment but it passed when I realised no-one was listening. However, people did start to head out of the area shortly after and head for Latimer Square. I still had not found Deanna but had received a text from asking if I was ok, but without any details about where she was. I followed along with the school kids hoping she would turn up. We soon reached the corner of Madras and Cashel streets to discover the collapsed CTV building. This was maybe 15 minutes after the quake and it had collapsed. There were a few policeman and other scrambling over the 10 meter high pile of rubble that was earlier a seven story building. Flames had started to rise from one corner of this.
We could not pass the CTV building on Madras street so instead walked up to Barbados Street then back down Hereford to the square. Amongst the many hundreds of people gathered her managed to find some work makes but could still not find Deanna. One of the teachers from the school said that some kids had remained in the school and Deanna was most likely one of these. Communication via mobile phone was next to impossible although some people seemed to be getting through. I tried many times to text and call anyone in my favourites list but the combination of hundreds of people in one park doing the same, a crappy iPhone and even crappier service from Vodafone meant that it was highly unlikely I could get a message out. So, after milling around for about thirty minutes I decided to try to return to the school to see if I could find Deanna. This proved futile as the police had blocked the area due to leaking gas and falling buildings. I couldn’t get closer than two or three blocks from the school. My only other option was to check the car, hoping that she had made her way there, but that also proved futile. Walking back to Latimer Square, I finally managed to get a text from Deanna to say they had been evacuated to the CPIT car park on Moorehouse Avenue. Another long walk but finally I found her, 2 hours after the quake. We gathered up two more kids who needed transport and headed back to the car and home. Driving north through the city, the traffic was very heavy and there was some major damage to roads and bridges, but nothing impassable. The trip was slow until we reach the suburbs but otherwise uneventful. Reaching home we found no immediately obvious damage but the cats are noticeably unsettled. Power had been out but was restored. Water is ok also. Amongst the turmoil and emotion of the time, it is reassuring to see so many people leap into action. People appeared instantly to leap into damaged buildings, perform CPR, direct traffic, move people around and generally start to make some order from chaos. While most people do there best to get out of trouble, others are possessed with a level of heroism that the rest of us envy and admire. In particular, one of Deanna's school friends, a seventeen year, mature beyond his age, spent most of the afternoon pulling bodies from damaged buildings. As for the future – it remains indeterminate for a while. I don’t see the City being accessible for a week or two. Power is out so I cant access any servers at work. Schools are closed for at least this week but as Deanna’s school is in the city I’m not hopeful she will be back there for at least a month – one of there older buildings was badly damaged. Challenging times.
If you’ve been using VS 2010 for anything more than a few minutes you have probably had the clipboard issue – ie, copy and paste randomly breaks. This is documented on MS connect here and probably elsewhere. The current recommendation is to install VS 2010 SP1 beta which I did this morning. Unfortunately this doesn't work for me. I still get random errors, albeit slightly different. Now when I paste, the cursor moves back to what I had selected and nothing is pasted. Happy days !
Don’t use Join-Path in PowerShell if you are trying to compose paths for remote machines. I did this for creating SQL database file paths. These must be relative to the SQL server, which in my case, was remote. So, something like this fails miserably: This is a bit silly really but I guess it’s useful sometimes. Instead, use [System.IO.Path]::Combine: HTH
I’ve been working on a sample app for SharePoint 2010 that demonstrates the Sync Framework, Custom Service Applications and a Custom Timer. There’s a few good articles on MSDN and elsewhere that document the process of creating a custom timer job pretty well. This hasn’t changed much in 2010 – if at all – from what I can see. However, the samples don’t show you how to create a Service/Server level job definition, so here’s my small addendum to show how to do this. Creating a Service Job When you construct a new job definition – custom or otherwise – there are two constructors you use: protected SPJobDefinition(string name, SPWebApplication webApplication, SPServer server, SPJobLockType lockType); protected SPJobDefinition(string name, SPService service, SPServer server, SPJobLockType lockType); You can override the constructors in your custom job. For a service timer you should use the 2nd constructor. In this case, the lockType can only be Job or None. Persisted Configuration If you take a look at the definition of SPJobDefinition you will notice that it inherits SPPersistedObject. The MSDN sample talks about creating a separate persisted object for the job configuration data. This is not necessary. Instead, you can add your [Persisted] public fields directly to your custom job definition. Errors When you run a timer job that is created for a service, the service must be running – yes, strangely :) If it’s not the job will fail silently and you have to look in the logs to see the error. There doesn’t seem to be any way to catch this exception. Weirdness I managed to waste about 3 hours trying to track down why timer execution of my service method was failing when calling it directly would work. There is no special logic in the timer. The bug I was seeing was something that I had fixed previously so I was baffled why it was failing for the timer and not for my web page. Overnight, and after a few IISResets, redeployments and reboots, it came right and now works correctly. I also made sure the GAC was cleared out between deployments. It seems to me like there was an old version of the service application dll that the timer was using and the rest of the site wasn’t. I cant prove this but that’s certainly how it appeared. Debugging As Andrew Connell points out in his articles, you need to fire an Assert() to get the debugger to stop in the job Execute() method. #if DEBUG System.Diagnostics.Trace.Assert(false); #endif Attaching to OWTIMER.exe is not enough. However, for me, this Assert does not popup a message – you need to attached to OWTIMER first. This maybe a SP or VS 2010 thing. Enjoy :)
I’ve been enjoying the stability and extra performance of a 64 bit OS for about 2 years now so I am surprise and somewhat disappointed that the latest round of goodness from Microsoft – i.e. SharePoint 2010, Office 2010 and Visual Studio 2010 have some annoying incompatibilities in this mode.
Datasheet View of a SharePoint list with a 64 bit version of Office does not work, you just get this annoying dialog: Apparently this is because the ActiveX control is not available for 64 bit OS’s. I have only tested on 2008 R2 server – Windows 7 64 bit may be ok. Also, Intellitrace in Visual Studio – aka Historical Debugging - does not support SharePoint (or any 64 bit app?). I’m sure Microsoft are aware of these limitations and will offer solutions in due course – but really, 64 bit has been coming for a while and I think we can expect not to see this sort of incompatibility, especially for Office. For me this has tarnished my experience only a tad, but overall, 64 bit everywhere is better than 32 bit in the same way that cake is better than two week old bagels.
|