Damian's Blog .NET from Geneva, Switzerland

18Jul/100

Tilt to turn pages in Kindle Android: Nope!

I bought an HTC Desire Android mobile phone a couple of months ago.

When I first got it, there were two applications that were missing that I really really wanted: Audible and Kindle.

image

Both were recently released, and despite this, my life is in fact not now complete.  There must be some other app for that.

I’ve been thinking about what I could develop.

As I read using the Kindle app the screen becomes smudged with my tapping the screen to change the page, and I thought it would be nice if I could change pages by tilting the phone to the right in a quick nudge.

I defied the temptation to start coding, and did some research.  It looks like it isn’t possible to do what I want using the public SDK, and to save myself the pain of rediscovering why in six months, when I have forgotten, here are some notes.

For this to work I’d need three things: A background process (called a service on Android), a way for it to detect when the phone has been tilted, and a way for it to tell the Kindle App to change the page, when it is running.

Creating a background process is pretty straightforward, and there is a sensor API that can be used to detect when the phone has been tilted.

Telling Kindle to change the page isn’t so easy.  I thought I’d found it when I discovered the IWindowManager.injectPointerEvent method, but I quickly found that this was not part of the documented Android API, and using it would be very very bad.

I was left with trying to find out whether the Kindle App itself had any way for other apps to tell it to change page.  The standard way of doing this would be to expose an Intent which other apps could invoke.

Unfortunately by dumping the Kindle App’s manifest from its installation (APK) file, it looks as though the only intents exposed are the standard MAIN, LAUNCHER, VIEW, DEFAULT and BROWSABLE intents.

Game over, unless I’m willing to go beyond the public API, which I’m not, right now at least.  Unless anyone else has any ideas?

18May/102

Ploze 0.7.6 released (Windows Mobile Evernote Client)

You can now:

  • Limit the synchronization size (in terms of note size, or last modification)
  • Choose which notebooks to display
  • Choose to download notes whose contents were not synchronized
  • Sort notes by Title, Size, Last Update, Creation date
  • Choose into which notebook new notes are placed

Also:

  • A bug where strangely named attachments caused ploze to not synchronize has been fixed.
  • Fixed bug causing large notes not to display properly
  • You can now select the notebook to display on the main note list (notes from all notebooks are displayed by default)
  • Added GPS support when creating a new note, which can be enabled under "Options"

I've also shared some thoughts on what might come next (think an Andoid version):  http://www.ploze.com/forums/ look for "Plans and purpose for Ploze ..."

More at http://ploze.com/

Filed under: Ploze 2 Comments
17Apr/101

Closed down MceFM

Click here to take survey to help me decide whether to create a new release of MceFM.

A couple of years ago I created a Windows Media Center addin called MceFM which let you listen to Last.fm within Media Center.

However Last.fm have changed their Application Programming Interface (API), and charge for access from Switzerland – leaving it unviable for me to continue…

Mcefm.com now redirects to this page.

Do check out BeebMC which lets you listen to BBC radio within Media Center.

Filed under: Media Center 1 Comment
12Apr/102

Just released Ploze: An Windows Mobile Evernote client

With what I think is stunning timing, just as Microsoft announced they are taking their mobile development in a different direction with Windows Phone 7, I’ve just released a new Windows Mobile product I’ve created called Ploze, which works with an existing service called Evernote .

Evernote is a fantastic notes service, with killer features, such recognizing text in image notes, meaning that those notes are found when you search for words in the image text.

There are plenty of Evernote clients offered by Evernote , including clients for Mac, Windows, iPhone, Android, and Windows Mobile.

The official Evernote provided Windows Mobile client comes with some restrictions – it works by connecting to the online Evernote service – it doesn’t store notes locally and let you work offline.

Necessity being the mother of invention, I decided to create a client that works as I would like it to, and yesterday I released it.

Available at http://ploze.com/

Filed under: Ploze 2 Comments
28Jan/100

The Amazon Kindle: A European perspective

Kindle Wireless Reading Device (6Having 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?

Filed under: Fluff No Comments
23Oct/090

Searching for senior .NET developer to join us at Cargill Geneva

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

5Jul/0916

Calling WCF Services from Excel VBA clients using the WCF Service Moniker

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:

image

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:

image

Switch the first endpoint to use TCP:

image

Also change the second to use mexTcpBinding:

image

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/

image

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…

image

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:

image

image

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:

image

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:

image

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:

image

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:

image

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:

image

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:

image

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:

image

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:

image

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:

image

Whereas Visual Studio actually tells you what the error is:

image

The maximum message size quote for incoming messages has been exceeded

image

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.

Filed under: WCF 16 Comments
26Apr/090

Got a product idea? Don’t register the domain.

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.

11Apr/0912

Windows Home Server needs a peer backup system

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:

image

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?

Filed under: Product-Ideas 12 Comments
30Mar/093

Cycling to work: give it some thought.

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.

Filed under: Fluff 3 Comments