A Dutch software developer living in Chile
# Monday, May 10, 2010
Office 2010 – It’s here

I’ve been using Office 2010 lately, and I must say… I’m impressed. The new look & feel is nice, the ribbon in Outlook and Visio are easy to use, and Outlook’s performance has increased on some aspects considerably.

One thing new is the 64-bit version of Office, which is nice for power-users of Excel… But if you are the ordinary Office user like I am, there is no need for a 64-bit version of Office. If you use add-ins in Office, (or any program that integrates with Office in some way) I’d recommend you stick with the 32-bit version. These add-ins need to be 64-bit to be able to work in 64-bit Office. Also, you can’t upgrade Office 2007 to Office 2010 x64. If you use Excel worksheets of 2GB or bigger, then Office 2010 x64 is the way to go.

For upgrading Office 2007, I chose to take the simple approach (an in-place upgrade). Everything worked out fine. This was literally an installation of “Next, next, next, Finish”

If you want to know more about Office, take a look here: http://www.zdnet.com/blog/bott/office-2010-a-deeper-dive/2042


Monday, May 10, 2010 1:23:03 PM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  

# Thursday, April 29, 2010
“This resolution’s gonna end in revolution just like any other goverance that doesn’t accept evolution” – Dan Bull

Copyrights and Intellectual Property – The motivators for a new piece of legislation in the UK.

The UK government has passed The Digital Economy Act 2010. A law that essentially violates human rights as far as I’m concerned. Once the government suspects that you do something illegal online in the UK, you will be “temporarily” disconnected. Note that there’s nowhere defined how long the term is. No trial, nothing. Want to appeal? Start your own procedure at your own expense.

Website owners can be banned when they serve content that infringes with IP. This can literally put a business out of business. Again, no trial, no warning, want to appeal? Start your own procedure at your own expense.

What happened with normal legal procedures? Copyright protection? Digital Rights Management? And then the biggest question, how do they get this information that you’re doing something wrong? The answer is that communication firms are already monitoring internet connections and need to provide information to the justice department whenever that’s requested. Generic detection and protocol use is a logical next step. Visit a site with a name that comes from those old ship robbers could get you disconnected in no-time.

So having said that, how long before our complete internet behavior is analyzed, automatically reported, and so on? If the government gets what they want, it will not be long…

Until that time, this little piece of creativity is luckily available to everyone: 


Thursday, April 29, 2010 7:16:11 PM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  

# Monday, December 21, 2009
Calling with Skype

It’s been a while since I blogged, so here I’m back again.

I’m using a lot of Skype these days. We’ve got a business account with them, having a Dutch phone number which can be used to call me here in Chile. It’s customer friendly and cheap for us. When calling to NL, I also use Skype to get in touch with my customers, friends & family and this all works fine. Problem is though that sometimes call echo screws up the conversation.

When taking a look at the pages on Skype, they say that I should use a headset (which I do), and have a good quality Internet connection, which I do. A fast PC might help, which I got, so there’s nothing more I can do on my side of the line to make things better. When I wasn’t using Skype, long distance calls using regular phone lines also were having echo problems. (And when I say “Long distance”, I’m talking 10.000 miles intercontinental phone calls.) So this isn’t related to Skype specifically, but more to those long distances that need to be covered (probably most of which goes over the Internet.)

Even though there’s sometimes echo, the call quality is good, sometimes even excellent. And when you remind people that they are talking with the other side of the planet, that also helps. Still, there’s room for improvement and I hope that new technologies will catch up and improve the overall experience in long distance communication.

Time to make another call… ;)


Monday, December 21, 2009 3:33:23 PM (Pacific SA Daylight Time, UTC-03:00)  #    Comments [0]  

# Saturday, November 14, 2009
21-12-2012 the end? Get real...

Some people think that December 21st, 2012 will be some kind of doomsday...

I'll post a folow-up on christmas 2012, which I'm sure will be a good laugh :)


Saturday, November 14, 2009 7:51:54 PM (Pacific SA Daylight Time, UTC-03:00)  #    Comments [0]  Opinions

# Friday, October 23, 2009
It ‘lives’ again…

It’s been some time since I last used my notebook. I’ve made a back-up, wiped it clean and installed Windows 7 on it. Office 2007 and Visual Studio 2010 (Beta 2) make it complete.

The screen of that notebook is broken, but my associate has ordered a new one. Once I’ll have it in NL, we’ll install a new screen and I’m (hopefully) good to go for another few years.

Since Visual Studio 2010 Beta 2 comes with a go-live license, I’ll be making the change soon…

image

Microsoft always does a good job on those splash screens, don’t they :)


Friday, October 23, 2009 8:27:22 PM (Pacific SA Daylight Time, UTC-03:00)  #    Comments [0]  

# Thursday, September 17, 2009
We’re on Windows 7

We started here to migrate our workstations to Windows 7 RTM since the day the images were available via MSDN. Now I’ve done the last one, the notebook of my wife, and we’re having all our computers on RTM right now.

I’ve worked with Windows 7 since the Beta, and now I have my system configured with it, I must say I’m very happy with it. My computer is fast, responsive, even with all the (almost) 7 million pixels I’m looking at every day. I’ve made some adjustments to the defaults, which makes Windows 7 even better to work with (for me at least.)

image

This is a typical snapshot of my taskbar, and as you can see, it’s height is a bit different. I did this by creating a folder, which holds the shortcuts in the upper row, and only the programs I use most frequently are pinned to the taskbar itself. This way I can easily start an application that I don’t have pinned and I still can use the jump lists for the software that provides this feature.

My biggest disappointment of Windows 7 is Aero Snap, so I’ve disabled this. On the multi-monitor area there’s still a lot of room for improvement in the Windows operating system. Windows Virtual PC for Windows 7 is nice, just too bad that seamless apps on multimon has (very) limited support.

The installation works fine, driver problems seem to be getting slowly a thing of the past and compatibility with Vista Apps & Drivers is also perfect. Also the other (somewhat less powerful) PCs and even my wife’s Aspire One, have no problem with Windows 7.

My advice: Move to Windows 7 as soon as you can, there’s no need to wait for SP1.


Thursday, September 17, 2009 9:34:42 PM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  

Moving TFS Historic builds to a new location

If you have a bunch of TFS builds that get a new home, it is always nice to let TFS know those files have been moved. But sadly, in the documentation there’s not much to find about this, nor is there any UI interface that lets you make this kind of change.

So I asked a question on the build forums, and Hongye Sun of Microsoft told me the best way to go at this, is use the Team Build APIs.

I’ve created a simple MoveBuild command line tool that allows you to move all the known builds from an old drop location to a new one, across all TFS projects.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;

namespace MoveBuild
{
  class Program
  {
    static void Main(string[] args)
    {
      if (args.Length < 3)
      {
        ShowUsage();
        return;
      }

      try
      {
        string tfsServer = args[0];
        string sourceDir = args[1];
        string targetDir = args[2];

        bool commit = args.Length == 4 && String.Equals(args[3], "/Commit", StringComparison.InvariantCultureIgnoreCase);

        TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(tfsServer);
        ICommonStructureService css = (ICommonStructureService)tfs.GetService(typeof(ICommonStructureService));
        foreach (ProjectInfo item in css.ListAllProjects())
        {
          MoveBuilds(tfs, item.Name, sourceDir, targetDir, commit);
        }

      }
      catch (Exception ex)
      {
        if (!Debugger.IsAttached)
          Console.WriteLine(ex.ToString());
        else
          throw;
      }

    }

    private static void MoveBuilds(TeamFoundationServer server, string teamProject, string sourceDir, string targetDir, bool commit)
    {

      int recordCount = 0;
      IBuildServer buildServer = (IBuildServer)server.GetService(typeof(IBuildServer));
      foreach (IBuildDetail item in buildServer.QueryBuilds(teamProject))
      {
        bool isMatch = item.DropLocation.StartsWith(sourceDir, StringComparison.InvariantCultureIgnoreCase);
        if (!isMatch)
          continue;
        recordCount++;
        //Console.ForegroundColor = isMatch ? ConsoleColor.Green: ConsoleColor.Red;
        //if (!isMatch)
        //  Console.Write("SKIPPED: ");
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine(item.BuildNumber);
        
        Console.ForegroundColor = ConsoleColor.Gray;
        StringBuilder newDropLocation = new StringBuilder();
        newDropLocation.Append(targetDir);
        if (item.DropLocation.Length > sourceDir.Length)
          newDropLocation.Append(item.DropLocation.Substring(sourceDir.Length));

        StringBuilder newLogLocation = new StringBuilder();
        newLogLocation.Append(targetDir);
        if (item.LogLocation.Length > sourceDir.Length)
          newLogLocation.Append(item.LogLocation.Substring(sourceDir.Length));

        Console.WriteLine("Old location: {0}", item.DropLocation);
        Console.WriteLine("New Location: {0}", newDropLocation);
        Console.WriteLine("Old log location: {0}", item.LogLocation);
        Console.WriteLine("New log location: {0}", newLogLocation);

        if (commit)
        {
          item.LogLocation = newLogLocation.ToString();
          item.DropLocation = newDropLocation.ToString();
          item.Save();
        }

      }
      Console.ForegroundColor = ConsoleColor.Gray;
    }

    private static void ShowUsage()
    {
      Console.WriteLine("MoveBuild - Usage");
      Console.WriteLine("MoveBuild <TFS URL> <SourceFolderPattern> <DestinationFolder> [/Commit]");
      Console.WriteLine();
      Console.WriteLine(@"Example: MoveBuild http://mytfsserver:port \\OldServer\OldShare \\NewServer\NewShare");
      Console.WriteLine(@"This will move all builds which have a drop location starting with \\OldServer\OldShare to \\NewServer\NewShare");
      Console.WriteLine();
      Console.WriteLine("If you specify /Commit the changes will be made to the database, if not, you only see a list of builds that would have been changed by this program");
    }

  }

}

To get this to build you need to:

  • Add a refference to the following Microsoft.TeamFoundation libraries (which are in %ProgramFiles%\Microsoft Visual Studio 9.0\Common\IDE\PrivateAssemblies
    • Microsoft.TeamFoundation.dll
    • Microsoft.TeamFoundation.Build.dll
    • Microsoft.TeamFoundation.Build.Common.dll
    • Microsoft.TeamFoundation.Build.Client.dll
    • Microsoft.TeamFoundation.Client.dll
    • Microsoft.TeamFoundation.Common.dll
  • Set your project’s properties to build for platform x86 if you’re developing on a x64 platform, otherwise you get a BadImageFormatException when loading these references.

Thursday, September 17, 2009 4:44:49 PM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  

Some cool hidden feature in IIS7

If you need to configure a site to only allow SSL connections, that’s easy. But if you want to redirect URLs to the SSL url when they are entering with a normal URL typed in the browser, or linked to, that’s not an option you’ll find in the management tools… or is it?

As posted here: http://tech.mikeal.com/blog1.php?blog=1&title=ssl-redirects-in-iis7-using-403-4-error--302&disp=single&more=1&c=1&tb=1&pb=1 it is possible to redirect those requests to a specific URL, using the “error pages” feature. The status code to redirect is “403.4” and the rest is easy.


Thursday, September 17, 2009 1:28:30 PM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  

# Sunday, August 09, 2009
New MoBo installed

Because some things went wrong here in the household, like TL tubes blowing out and other electrical problems, I didn’t have much time to do some real work on my PC. But, this weekend that was different, because now everything is working like usual again. I replaced 3 TL lamps in it’s entirely (not just the tube), and the electrical problems are solved.

So, it was time to get to work on my nice PC. I have a quad core AMD Black Edition 3 Ghz processor, 8 GB memory, a 1000W PSU and 2 nice video cards (ATI Radeon HD 4870), but I could only install one of these cards because the SATA cables were in the way. The ECS board therefore didn’t fulfill my requirements and needed to be replaced. Since this is all still an AM2 Chipset, I needed to be quick. AM3 comes out and before you know it, you can’t get it anywhere anymore.

So here we are: One DFI LanParty board

image

As you can see on the picture, this board has the advantage that the SATA cables can be plugged into the side, so that does not conflict with large video cards, like this one:

image

Now you may ask: why 2 of these beasts? I got 3 big 26” HD monitors here on my desk. (Each having a resolution of 1920 * 1200) This alone is very cool to work with.

Putting it all together

The task was a hefty one. Each video card needed 2 PCI-E Power connectors attached, so those were 4 cables. Then came the motherboard, with the standard power connector (the big one), and 3 aux connectors. (2 via the good’ol FDD connectors.) The audio connector for the front part is a bit in a strange place, that’s between the 2 PCE-slots where the gap is. Now came a nasty one, I had to get the proc out of the motherboard. Once I carefully lifted up the heat sink, which didn’t go really easy, I noticed the processor was attached to it. That stuff of AMD that they use on their heat sinks is way to adhesive! I got the processor loose using the hairdryer trick. You warm up the heatsink with a hairdryer, once this is warm you can slowly but surely move the processor off.

The rest was all simple, and once the box was closed, it was time to put it back in place.

Let’s run again

This was the first time I used the 2 video cards together, and I must say: "I’m impressed, big time!” Video performance is funtastic, the motherboard does also a very good job. Since this is an overclocker’s board, the BIOS is not something for the faint hearted. Do your homework or don’t fiddle with it too much.

All together this is now a rig that will almost do anything you throw at it. The only thing I’m missing is water cooling ;-)

If you want to build something like this, make sure you get a good PSU. For 2 of these video cards, a 1000W Modular PSU is highly recommended.


Sunday, August 09, 2009 10:00:10 PM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  

# Monday, August 03, 2009
How to get a SHA1 hash from a file in C#.Net

A simple way to get a hash code from a file:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Sha1
{
  class Program
  {
    static void Main(string[] args)
    {
      if (args.Length != 1)
      {
        Console.WriteLine("Usage: SHA1 <filename>");
        return;
      }

      string fileName = args[0];
      if (!File.Exists(fileName))
      {
        Console.WriteLine("File not found: {0}", fileName);
        return;
      }

      using (Stream s = File.OpenRead(fileName))
      {
        SHA1Managed sha = new SHA1Managed();
        byte[] result = sha.ComputeHash(s);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < result.Length; i++)
        {
          sb.AppendFormat("{0:x2}", result[i]);
        }
        Console.WriteLine("SHA1 Hash: {0}", sb);
      }

    }
  }
}


Monday, August 03, 2009 9:22:14 AM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  

# Monday, July 27, 2009
A very simple GZip command line tool

During some testing, I needed a tool that could simply compress a file to GZip format and back again. I decided that other people might have a similar need, so here’s the code to make it work.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Compression;
using System.IO;

namespace GZip
{
  class Program
  {
    static void Main(string[] args)
    {
      CompressionMode mode = CompressionMode.Compress;

      if (args.Length != 3)
      {
        ShowUsage();
        return;
      }

      string command = args[0].ToLower();
      switch (command)
      {
        case "compress":
          mode = CompressionMode.Compress;
          break;
        case "decompress":
          mode = CompressionMode.Decompress;
          break;
        default:
          ShowUsage();
          return;
      }

      Stream sourceStream = File.OpenRead(args[1]);
      Stream targetStream = File.OpenWrite(args[2]);

      switch (mode)
      {
        case CompressionMode.Compress:
          using (GZipStream gZip = new GZipStream(targetStream, CompressionMode.Compress))
          {
            Pump(sourceStream, gZip);
          }

          break;
        case CompressionMode.Decompress:
          using (GZipStream gZip = new GZipStream(sourceStream, CompressionMode.Decompress))
          {
            Pump(gZip, targetStream);
          }
          break;
      }
      sourceStream.Close();
      targetStream.Close();

    }

    private static void Pump(Stream source, Stream target)
    {
      byte[] buffer = new byte[65536];
      int count;
      while ((count = source.Read(buffer, 0, buffer.Length)) > 0)
      {
        target.Write(buffer, 0, count);
      }

    }

    private static void ShowUsage()
    {
      Console.WriteLine("Usage: GZip compress | decompress   sourceFileName targetFileName");
    }
  }
}


Monday, July 27, 2009 3:02:34 PM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  Programming

World’s smallest web server

It’s always fun to play with .Net, the HTTP Listener class in .Net 2.0 makes it really easy. With this little block of code you can setup a very simple (multithreaded) web server…

private static System.Threading.AutoResetEvent listenForNextRequest = new System.Threading.AutoResetEvent(false);

protected Server() 
{
  _httpListener = new HttpListener();
}

private HttpListener _httpListener;

public string Prefix { get; set; }
public void Start()
{
  if (String.IsNullOrEmpty(Prefix))
    throw new InvalidOperationException("No prefix has been specified");
  _httpListener.Prefixes.Clear();
  _httpListener.Prefixes.Add(Prefix);
  _httpListener.Start();
  System.Threading.ThreadPool.QueueUserWorkItem(Listen);

}

internal void Stop()
{
  _httpListener.Stop();
  IsRunning = false;
}

public bool IsRunning { get; private set; }

private void ListenerCallback(IAsyncResult result)
{
  HttpListener listener = result.AsyncState as HttpListener;
  HttpListenerContext context = null;

  if (listener == null)
    // Nevermind
    return;

  try
  {
    context = listener.EndGetContext(result);
  }
  catch (Exception ex)
  {
    System.Diagnostics.Debug.WriteLine(ex.ToString());
    return;
  }
  finally
  {
    listenForNextRequest.Set();
  }
  if (context == null)
    return;
  ProcessRequest(context);
}

// Loop here to begin processing of new requests.
private void Listen(object state)
{
  while (_httpListener.IsListening)
  {
    _httpListener.BeginGetContext(new AsyncCallback(ListenerCallback), _httpListener);
    listenForNextRequest.WaitOne();
  }
}

protected abstract void ProcessRequest(HttpListenerContext context);

Always nice to have ;)


Monday, July 27, 2009 1:21:45 PM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  Programming