The Amazon Kindle: A European perspective
January 28th, 2010
Having told my wife that I definitely did not want an Amazon Kindle E-Reader for Christmas, I found myself with a substantial Amazon.com gift voucher, and decided to splurge.
The immediate result was an infuriated wife, and dark mutterings about how difficult it is to buy me presents. Almost as immediate was the arrival of the Kindle. Although shipped from the US, two days after placing the order my new Kindle arrived.
Perfidy?
There is something about the film Children of Men which captivates me: the tired depiction of a dying world set 10-15 years into the future, where no children are being born is compellingly rendered. It starts with a news report that the world’s youngest person, an 18 year old, had just died.
I decided to make the book upon which the film was based my first purchase. Written by P. D. James, it is a well written, substantial work, and it uses many words that I don’t know (perfidy, viva voce, farrago to name a few). That was where I found the first of the advantages to using the Kindle to read books: it includes a built-in dictionary. Whenever I hit a word with which I was not familiar I moved a highlight in front of the word, and up popped a dictionary definition. I suspect that I’ve ploughed through many a book in the past and simply ignored the words I didn’t know.
When reading I very quickly found that I was unaware of the fact that I was reading from an electronic device. The use of e-ink (which is a display technology that does not strain the eyes) made a big difference. I was totally engrossed in the story, and the fact that I didn’t have a book in front of me made no difference. I was in the story.
I need it now!
Buying books from Amazon when you live in Switzerland is a pain. You pay a fortune in shipping charges, and then have to wait for days for the book to arrive. This is the second advantage to the Kindle: immediate delivery of books. The Kindle has a free wireless (not wifi, but a 3G data link over the mobile telephone network). You don’t have to insert a SIM, it just works. Books you order appear within minutes on the device.
Try before you buy
As useful as the immediate delivery of books is, the third advantage is a killer, you get to download the first chapter or so of any book for free to see if you like it. This is so convenient – I read the first few pages, and if I don’t like it, I delete it, and forget about it. On the other hand if it is really good, a couple of clicks later I’m reading the whole book.
A book wherever you go
The fourth and final advantage is that you can read any of your Kindle books on your PC or iPhone too. They are there too, just like that, using free software from Amazon. So if you are in shopping queue you can pop out your iPhone and continue to read that book you were reading at home on your Kindle. And, wait for it, the pages are synchronized, so that when you go back to the Kindle it will pick up where you left off on the iPhone, and the reverse.
The downside
There are some drawbacks. Although Kindle books cost less than physical books, they cost more to buy in Europe than in the US, and the range is much smaller. Some books are not really good to read on the Kindle, such as a technical book I bought on Microsoft Project, although I find reading on the PC (while running Project to try things out) works well.
Who am I kidding?
We are still in January. So far I am really enjoying reading from the Kindle, and I am reading much more than I do normally, although that is probably because I’m keen to justify to myself that it was a sound investment.
Nevertheless, it is a very compelling device. I’m still going to want physical copies of some books, but for most of the books I read I really don’t care what I read them on, so long as the medium disappears when I get into the story.
One last thing
Oh yes, one last thing, did I mention that the Kindle comes with free access to Wikipedia?
Searching for senior .NET developer to join us at Cargill Geneva
October 23rd, 2009
We are searching for a senior .NET developer with strong business skills to join our team at Cargill Geneva.
We are a small team of experienced developers, working closely with Traders and Analysts to understand their requirements and implement solutions from A-Z. We need people with very good interpersonal skills, that are comfortable dealing directly with demanding business users, and with solid development skills.
We use VS2008, .NET 3.5, linq, etc. No new technology for the sake of it, but if it makes sense then we use it.
If you are looking for a position that makes use of both your development skills and your business/domain knowledge then please apply. We are primarily looking for people from the Geneva area, but if you are elsewhere in Switzerland or in the EU then please apply.
Enter job GEN00575 at http://www.cargill.com/careers/search-apply/experienced-professionals/emea/index.jsp
Did you know there is a way to invoke simple Windows Communication Foundation (WCF) Services from Excel VBA without installing anything other than the .NET Framework on the Excel machine?
There are many different kinds of monikers, but the one that interests us is the Service moniker that can be used to access WCF Services:
Set someObject = GetObject(“service:Binding Information”)
In this blog post I’m going to show how you how to go about using WCF Services from Excel VBA, step by step, from beginning to end, and explain how to debug the rather obtuse messages that Excel displays when you’ve misconfigured something.
The WCF Service
The WCF Interface you expose can not be particularly complex if you want to use the Service Moniker – I’ve found it best to keep top primitive types, and arrays of primitive types. Data Contracts seem to be a no-go.
Start by creating a new WCF Service using File|New|Project and selecting WCF Service Library:
Double-click on IService1.cs in the Solution Explorer, and replace the default contents with this simple interface:
using System; using System.ServiceModel; namespace WcfService1 { [ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); [OperationContract] object[] GetSomeObjects(); } }
Next replace the contents of the service implementation, Service1.cs, with the following:
using System; namespace WcfService1 { public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); } public object[] GetSomeObjects() { return new object[] { "String", 123, 44.55, DateTime.Now }; } } }
Configuring the WCF Service
By default the WCF Service is configured to use HTTP as the transport protocol. I generally switch it to use TCP, because I am operating within a corporate intranet, and HTTP seems like overkill.
You’ll also find that by default your WCF Service exposes two endpoints. The first exposes as you’d expect, the IService1 interface you defined above. The second exposes Metadata about your service, which the Service Moniker uses to know what operations are available on your service. You’ll need both.
Right-click on the App.config file in the Solution Explorer, and select Edit WCF Configuration:
Switch the first endpoint to use TCP:
Also change the second to use mexTcpBinding:
Change the base address that the service will use, to use a TCP address instead of a HTTP Address by selecting the Host node on the left hand tree, and then selecting the base address and clicking on Edit, and changing the text to be net.tcp://localhost:7891/Test/WcfService1/Service1/
Finally, because you are using TCP instead of HTTP, change the MetataData service to not expect to expose the metadata via HTTP, by changing HttpGetEnabled to False under Advanced|Service Behaviours…
Save the changes and exit the WCF Editor. Your App.config should look like this:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <compilation debug="true" /> </system.web> <system.serviceModel> <services> <service behaviorConfiguration="WcfService1.Service1Behavior" name="WcfService1.Service1"> <endpoint address="" binding="netTcpBinding" bindingConfiguration="" contract="WcfService1.IService1"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:7891/Test/WcfService1/Service1/" /> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior name="WcfService1.Service1Behavior"> <serviceMetadata httpGetEnabled="False"/> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
To start running your service you can hit Ctrl-F5 in Visual Studio. This will start a test service host, and a test client. We will ignore the client, but you can check that the service host has started by clicking on the message in the notification area:
Eventually you’ll want to host your service somewhere else, such as a Windows Service.
The Excel VBA Client
Start Excel, and then hit Alt-F11 to enter the VBA Code editor. We’ll invoke the WCF Service whenever someone clicks on a cell in the first sheet. Double-click on Sheet1 on the top left hand side, and then select Worksheet from the drop down of objects:
The Service Moniker needs to know the address of the MetataData Service, the address of the service itself, binding information, and information about the contract.
Dim addr As String addr = "service:mexAddress=""net.tcp://localhost:7891/Test/WcfService1/Service1/Mex""," addr = addr + "address=""net.tcp://localhost:7891/Test/WcfService1/Service1/""," addr = addr + "contract=""IService1"", contractNamespace=""http://tempuri.org/""," addr = addr + "binding=""NetTcpBinding_IService1"", bindingNamespace=""http://tempuri.org/"""
Once you’ve built up the Service Moniker string, you can use GetObject to resolve it, and then invoke a method on it:
Dim service1 As Object Set service1 = GetObject(addr) MsgBox service1.GetData(12)
The VBA Editor should look like this:
I’ve set a breakpoint on the first line of code by clicking where the red circle is above.
If you now click on a cell in your sheet, and let the VBA code run, you should see this:
The VBA code has called through to the WCF Service and invoked a method on it, and the service has returned a string.
Change the code to invoke the second method, and step through in the debugger, and add a Watch on the result:
Whats up with the Tempuri?
You’ll have noticed that the moniker string references a couple of weird Tempuri namespaces. These are the defaults, but you can alter them. This can be useful if you have a single service exposing a couple of interfaces and you only want to work with one of them. For example your service may expose a complex interface for WPF clients, and a simple interface for a Excel client. If you give the simple interface a different namespace than the complex interface, you’ll be able to access it from Excel VBA.
To change the contract namespace, edit your interface code:
using System; using System.ServiceModel; namespace WcfService1 { [ServiceContract(Namespace="http://damianblog.com/")] public interface IService1 { [OperationContract] string GetData(int value); [OperationContract] object[] GetSomeObjects(); } }
Then your service moniker can be changed accordingly:
addr = addr + "contract=""IService1"", contractNamespace=""http://damianblog.com/"","
When it doesn’t work
The Excel message you get when the GetObject doesn’t work properly is not exactly detailed:
There is however a way of getting more detailed information. You can attach your debugger to Excel, and then see the underlying managed .NET exception.
To attach your debugger to Excel in Visual Studio use Debug|Attach to Process and then select Excel, and click Attach:
Next, make sure the debugger stops as soon as an exception occurs by clicking on Debug|Exceptions and check the checkbox to be interrupted when an exception is thrown:
Don’t forget that you have done this. If you leave it checked then later on when debugging unrelated code you may get thoroughly confused to have the debugger break inside framework code that throws and then handles an exception which is normally invisible to you.
You’ll also need to tell the debugger to break when code other than your own code throws an exception. Do this by clicking on Tools|Options and then going to the Debugging section, and uncheck the Enable Just My Code checkbox:
Now run your VBA code as usual, and when you get the error the Visual Studio Debugger will break with more detailed error information. So if I change my moniker string to use an invalid interface name the Excel VBA error is:
Whereas Visual Studio actually tells you what the error is:
The maximum message size quote for incoming messages has been exceeded
You’ll hit this error if your .NET code returns too much data to the Excel client. You might be able to resolve it by setting the MaxRecivedMessageSize property in an Excel.exe.config file in the same folder as Excel.exe. They way I have handled it is to move from using the Service Moniker mechanism, and to create a managed Excel AddIn that sets the maximum message size programmatically.
Summary
The WCF Service Moniker offers an excellent way for you to invoke simple WCF Interfaces, where small quantities of data are exchanged, without installing anything at all on the Excel Client machine.
In the above examples the service moniker created by the VBA code used the “localhost” address for the service, but if your service is running on another machine you can specify that machine’s address: the service can run anywhere.
Got a product idea? Don’t register the domain.
April 26th, 2009
Since I started programming in the early eighties I’ve dreamed of ideas for software tools, utilities and products. I’ve followed through and created some of them, but for many I’ve not, and I think I’ve finally figured out why: it can only be because I registered the domain name before I created the product. Let me explain …
Having an idea for a product or web site can be enormously seductive. We can dream away, and if we never follow through, we can never fail. Even better we can tell others about our fantastic idea, and almost know what it would feel like if it was a success. Almost.
But the killer is that we can research domain names. We can spend hours trying to find exactly the right domain for our product-to-be. The one we haven’t even started creating yet. And finally, when we’ve got that perfect domain, we can pull out our credit card, and register it. Then, we are done. That’s it. No need to do anything else. Dreamed about the success, got the domain name, and then … well, there isn’t really any need to take it any further, is there?
This post isn’t just about the dangers of premature registration, it is also to allow me to put some of my own overly-enthusiastic registrations to rest. So here they are. None of them are real, except in my imagination (and of course in the domain name registration) …
- Asknearme.com : Transient, anonymous conversations. A GPS-enabled mobile-phone location-based service that is an anti-social networking site, where you could anonymously ask questions to anyone who happens to be close to you geographically: where are the closest toilets? Has anyone found a green hat?
- Askmystreet.com : do you know everyone on your street? Anyone? This site was to let you get in touch with people living near you, to help build physical communities out of virtual ones.
- tracejs.com, jsprof.com, jsprofiler.com, javascriptprofiler.com : this product idea used the JavaScript debugger API on windows to continuously break into JavaScript code running in Internet Explorer, and let you see what JavaScript code was executed, and how much time each function took. I got close on this one.
For balance, I have got it right a few times:
- mcefm.com – listen to Last.fm in Windows Media Center. I’ve stopped developing it since Last.fm cracked down on the use of their APIs in some countries.
- beebmc.com – listen to BBC Radio within Windows Media Center. Still exists, and still quite popular.
- j-integra.com (not mine any more) – Java-COM interoperability, initially through my Java implementation of the DCOM wire protocol.
- promptsql.com (not mine any more) – SQL Intellisense within Query Analyzer and SQL Server Management Studio
This post is a little tongue in cheek, although there is a kernel of truth. It is important to follow through on our ideas, and not just live on the dream. Don’t deflate the excitement by working on the incidental. Tackle the core first.
Stop that dreaming, and get coding.
Windows Home Server needs a peer backup system
April 11th, 2009
I’ve just set up a Windows Home Server on my home network, and so far I think it is fantastic. I’ve been able to collect an assortment of hard drives and plug them all into the same machine, and have them seamlessly presented as a single large virtual drive:
Our photos are stored in a shared folder hosted by the Windows Home Server, and by enabling the “Duplication” feature, I know that copies are kept on two physical disks, meaning that in the event of a hard disk failure, I’ll still have a copy on another disk. I’ve also been able to set up all of the computers in the house to be backed up.
There is however, as others have noted, a big flaw in this situation. Although I have all my photos duplicated on two disks, and all my computers backed up , in the event of a fire, or theft, I’m screwed. Someone could walk off with all the physical disks.
What I really need is off-site backup. I’ve been doing this using an excellent service called Mozy, which for US$5 a month offers unlimited backups for a single PC. Unfortunately Windows Home Server is based on Windows Server 2003, and Mozy will not run on Server operating systems.
A modest idea: a peer backup service
What I’d like to have, and what I’m tempted to develop, is a peer backup system, implemented via a Windows Home Server Add-in I’d create, and a web site which serves to hook people’s Windows Home Servers together.
My idea is this: I’d create a web site where people could register (probably automatically via the add-in) their need for an off-site backup, indicating how much space they need to backup. They need to commit to making an equivalent amount of space available on their computer for someone else.
My web site would match people up, and then the people could use each others systems to automatically perform offsite backups. The add-ins could talk to each other, either peer-to-peer, or via my web site. There are issues of course. The backed up data would have to be encrypted, which makes incremental backups problematic.
The next obvious step would be to allow the backups to be stored redundantly across the computers of multiple participants, so that you are not just reliant on one other person. For this to work you’d need to volunteer to make available much more space for other people’s backups than your own backups require - perhaps twice as much.
I’m tempted to develop this service, however I’m not sure how I could cover my costs. Would you pay say US$25 a year for a peer-based secure offsite backup service?
Cycling to work: give it some thought.
March 30th, 2009
I started working for Cargill Energy at the beginning of 2009, and almost immediately decided to cycle the 23 km (14 miles) each way. I live in a small village along lake Geneva in Switzerland, and work in Geneva itself.
The cycle ride takes me along the lake road, through villages that date back to Roman times, and into Geneva itself. A shortcut through the old part of the town gets me to Cargill around 6:40. I take a shower and am at my desk at 7am.
It was tough to start with. It was below freezing, dark, and the cycle paths had big chunks of ice welded to the ground.
After a minute or two of cycling I go into auto-pilot and start thinking about stuff. I usually regain consciousness an hour or so later when I’m at the office, and I find that I’ve generally made decisions. Sometimes tough decisions about what I need to do to advance my career, what I need to propose to the team I’m in to help us work more effectively, but I also gain significant insight into how I could go about designing a piece of software I’m working on,
Two hours a day is a big chunk of time to spend commuting to work, but it really isn’t two hours spent exercising: its two hours spent thinking. And they are almost always the two most valuable hours of my working day.
Screencast: Testing, Mocking and Dependency Injection: more than just buzz-words
February 20th, 2009
This 40 minute screencast covers unit testing, mocking, dependency injection, and inversion of control.
The idea is again that this will be is very much a hands-on, practical screencast. Not technology for its own sake, but reviewing how and why these concepts evolved, and how they can be used in practice.
I’m not a TDD (Test Driven Development) fanatic, I don’t think we should always have 100% code coverage with our tests, but I do think there is a lot of value in testing, and in making our code testable.
The screencast is available here http://damianblog.com/TestingMockingAndDependencyInjection.wmv
Screencast intro to VS 2008 & .NET 3.5
February 16th, 2009
I recently gave a presentation at work introducing some of the new features of VS 2008 and .NET 3.5. No slides, just code. And no pre-prepared chunks of code that are pasted into the editor either - everything written by hand.
In this 40 minute screencast I blast through Automatic Properties, Collection Initializers (Lists & Dictionaries), Implicit Typing, Anonymous Types, Extensions Methods, “Normal” Delegates, Anonymous Delegates, a natural evolution of delegates to Lambda expressions, Linq to objects using method chaining, Linq to objects using the natural Linq syntax, and finally Linq to XML.
Download or watch the screencast here: http://damianblog.com/WhatsNewInVS2008and.NET3.5.wmv
Microsoft fixed my bug
February 14th, 2009
Like a lot of people, when I first began developing on a “proper” Operating System (as opposed to the 8 bit computers I started with), sooner or later I convinced myself I’d found a bug in the operating system.
Of course I’d be wrong, and after suffering the embarrassment of discovering that it was my own stupidity, rather than an OS bug, that was causing the errors, I eventually acquired an automatic reflex to never ever believe that there was a bug in the OS. It had to be a bug in my code. This was a good thing, since I was always right.
Despite this, it seems that I never fully learned this lesson. And so it was that last May I opened a bug report on Microsoft Connect, fully expecting to be gently, but firmly rebuffed, with an explanation of where exactly I’d gone wrong.
The issue that I was facing was in detecting whether a connection to my web application was coming from the local machine (running the web application), or from a remote machine. I was calling the HttpListenerContext.Request.IsLocal method, and it was always returning false, even though the client was definitely local.
A little digging with Reflector showed that the method was implemented using “==” to compare the local address with the remote address, instead of the Equals method. If the “==” operator had been overloaded then it would have worked.
A couple of days ago, I got a message saying that this was indeed a bug, and that it was fixed in version 4.0 of the .NET framework. So it looks like I have finally actually discovered an honest-to-goodness bug.
Or perhaps they are just being kind to me.
Small utility to generate summary of your Media Center recorded movies
December 21st, 2008
I’ve created a small simple utility to create an HTML summary document listing all the movies I’ve recorded using Vista Media Center.
I did this to get a compact record which I can browse without firing up Media Center, and which I can print out to give to visitors that are not familiar with Media Center.
This is what the output looks like:
The links you can see are links to IMDB.
When you run the utility you can choose the directories it should look in, and the name of the output file:
The first checkbox lets you tell the utility to only output films that it has found duplicated — I added this so that I could easily find films that I’d recorded twice by accident. The second checkbox tells it to also output the locations of the media files so that you can see where they are.
This tool is free, unsupported, and is to be used entirely at your own risk. You can download it here.
You might also want to check out this other utility which you can use to download image files for your films so that the images appear in generated html and also in Windows Media Center.

