Saturday, December 26, 2009

Changing Your Domain Password When Your PC is not on the Domain

Recently, I had to change my domain password from a desktop wasn't on the domain. The solution I found was to terminal service into a server with my domain account and use Ctrl+Alt+End to bring up the Windows Security menu and select Change Password.

This took me way longer to figure out than I'd like to admit.

Saturday, December 19, 2009

?? Operator Precedence in C#

I've been stung by this a few times in the last month.

The ?? (Null coalescing operator) has a really low precedence in C#. It's well below the arithmetic operators. In fact, it's second from the bottom according to MSDN. For some reason, I expected it to be quite high.

Take this code as an example.

    int? x = 10;
    int? y = 10;

    Console.WriteLine(x ?? y + 1);
Previously, I'd expect this to print 11. It actually prints 10 (since x ?? y + 1 is equivalent to x ?? (y + 1)).

Tuesday, December 15, 2009

Easy Backups with rsync: Part 3 of 3

In this part we'll write a back up script and finish up.

Boot up off your USB flash drive. Now you need to figure out which drives you want to back up and what they are called in /dev. In puppy this is a piece of cake. An icon for each device is displayed at the bottom of the desktop. Clicking on the icon mounts the device as /mnt/<device name> and opens a file explorer on that drive. All you need to do is click through the devices until you find the ones you want.

Now you need to write the rsync script. Here is mine:

backup.sh
---------
rsync -rltDvP /mnt/sda1/Users/Henri/ /mnt/sde1/backups/windows/
rsync -rltDvP /mnt/sdc3/henri/ /mnt/sde1/backups/ubuntu/

I use this to backup the home directories on my Windows and Ubuntu partitions. Before I run this, I ensure that both sda1 and sdc3 are mounted and my backup drive is mounted at sde1.

Note that the trailing slashes on the paths are important. Otherwise the source folder will copied into the destination.

The switches were chosen to make a copy of the source directory recursively(-r), with symlinks copied as symlinks (-l) and modification times preserved(-t). The verbose messages (-v) and progress indicators (-P) are turned on. This is equivalent to the archive (-a) option but without preserving permissions, ownership and file groups. Because I'm backing up onto a NTFS drive, those options don't work correctly. (Ultimately I'll add the --delete flag to delete files in the destination not present in the source.)

Now save the script and you're ready. Once a week follow the steps given the Part 1 and your backups are sorted.

Monday, December 07, 2009

Easy Backups with rsync: Part 2 of 3

In this part I'll give pointer on how to install some version of Linux onto a USB flash drive.

The idea is to be able to boot off the drive and run the backups from there. The set up must have "persistence" i.e. you need to be able to save files to the drive. Not every set up of Linux supports this - some of the Live USB versions are read-only. I use PuppyLinux because it's easy to set up and has quite a pleasant UI. There are many alternatives but most require quite a bit of effort to get working.

Get a smallish USB stick and follow the installation instructions over here.

In the next part, I'll detail how to write the backup script.

Sunday, November 29, 2009

Easy Backups with rsync: Part 1 of 3

The most important thing about a home backup strategy is to make sure that the back ups actually get done. You're more likely to get this right if your process is simple and easy and if you make it part of your routine.

My strategy is to maintain mirrors of my home directories on an external hard drive. The process uses only free software but takes some effort to get set up.

The process has 4 steps.

  1. Shutdown
  2. Boot up Linux off a flash drive
  3. Plug in an external drive
  4. Run a backup script

The backup script mounts the target drives and uses rsync to mirror the home directories on them onto the external drive.

To set this up you need to:

  1. Have an external drive with sufficient capacity
  2. Have bootable flash drive with some flavor of Linux on it
  3. Write a backup script

In the next post I'll detail how to get Linux on a bootable flash drive.

Tuesday, November 03, 2009

Book Review: The Mythical Man-Month

I finished reading the Mythical Man Month last week. I bought the 20th Anniversary Edition which includes the famous 'No Silver Bullet' essay and some updated content. This must be the oldest coding-related book I have ever bought - even that anniversary edition was published more than 10 years ago!

The Mythical Man-Month has stood the test of time. In spite of it's age, it's still read and quoted today. If you've been a programmer for a decent length of time you will have come across discussions and references to it. This is the book that introduced Brooks' Law, Second-System Syndrome and made the much debated recommendation to 'plan to throw one away'. It's also the second book on the Coding Horror recommended reading list. Baring in mind how fast technology changes, it is arguably a classic book in the true sense of the word.

That said, I have mixed feelings about MM-M. The book contains some timeless insights but, unfortunately, whole chapters are completely irrelevant to today's coders. The information is just too dated and obsolete. For example, there is a whole chapter about managing paper based documentation systems including tips about microfiche and page numbering.

Buy MM-M if you're looking for a historical perspective on the craft. If you're purely looking for a practical book on programming practices, try Code Complete instead.

Sunday, November 01, 2009

Dude, Where's My Powershell 2.0?

Yesterday, I installed PowerShell 2.0 but encountered some issues that had me scratching my head. After I installed it, I couldn't find it.

I grabbed the latest installer listed on download page and ran it. It completed and then... nothing. I checked under my start menu and I couldn't see any new items. I found the PowerShell 1.0 directory (C:\WINDOWS\system32\windowspowershell\v1.0) but I couldn't find a 2.0 directory. It looked as if the installer didn't install 2.0 at all!

After reading the release notes and some fussing, I found out that 2.0 was, in fact, installed. The short cuts are placed unders 'All Programs' > 'Accessories' and the new files are installed in the 1.0 directory over the previous version.

I wonder if anyone else was confused by this.

Sunday, October 18, 2009

Live Expressions With Obtics

I'm busy working on a WPF app that's replacing a Excel spreadsheet solution. It involves lots of summary stats (sums, averages etc.) against a set of items. As the items are editted the changes need to be detected and the stats have to be updated so that the user can see the affects of his changes.

The normal way of doing this is to make the items implement INotifyPropertyChanged and then listen to changed in the properties that the stats are dependent on. As the stats get more complicated this gets more and more complicated and error prone.

Obtics is a library that makes this much easier.

Take the following example:

public class Portfolio
{
  public Portfolio()
  {
    Holdings = new ObservableCollection<Holding>();
  }

  public ObservableCollection<Holding> Holdings { get; private set; }
}

public sealed class Holding : INotifyPropertyChanged
{
  private int quantity;
  private Stock stock;

  public int Quantity
  {
    get 
    {
      return quantity;
    }
    set
    {
      if (quantity == value) 
      {
        return;
      }
      quantity = value;
      OnPropertyChanged("Quantity");
    }
  }

  public Stock Stock
  {
    get
    {
      return stock;
    }
    set
    {
      if (stock == value) 
      {
        return;
      }
      stock = value;
      OnPropertyChanged("Stock");
    }
  }  

  private void OnPropertyChanged(string propertyName)
  {
    var handler = PropertyChanged;
    if (handler != null) 
    {
      handler(this, new PropertyChangedEventArgs(propertyName));
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;
}

public sealed class Stock : INotifyPropertyChanged
{
  private decimal price;

  public decimal Price
  {
    get
    {
      return price;
    }
    set
    {
      if (price == value) 
      {
        return;
      }
      price = value;
      OnPropertyChanged("Price");
    }
  }  

  private void OnPropertyChanged(string propertyName)
  {
    var handler = PropertyChanged;
    if (handler != null) 
    {
      handler(this, new PropertyChangedEventArgs(propertyName));
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;
}

If I want the value of the portfolio I can write this:

var portfolioValue = Obtics.Values.ExpressionObserver.Execute(() => porfolio.Holdings.Sum( x => x.Quantity * x.Stock.Price));

portfolioValue is of the type IValueProvider and portfolioValue.Value will give the current value of expression. The real magic is that Obtics analyzes the expression and automatically refreshes the value when the inputs change. In this example, adding and removing holdings, changing the holding quantities and even the stock prices will cause the value to update. If you did that by listening to the PropertyChanged events, it would take 10 times the amounts of code.

portfolioValue can also be cast to INotifyPropertyChanged, so porfolioValue.Value can be bound in WPF.

Sunday, October 11, 2009

Deleting a Column's Default Constraints

At work I recently had the problem where I needed to drop some columns that had default constraints which had generated names. Here is the set up:
CREATE TABLE ExampleTable ( 
    ExampleColumn int NOT NULL DEFAULT 0,
    OtherColumn int NULL)
GO

ALTER TABLE ExampleTable
    DROP COLUMN ExampleColumn
GO

Msg 5074, Level 16, State 1, Server HENRI-XP\SQLEXPRESS, Line 1
The object 'DF__ExampleTa__Examp__7E6CC920' is dependent on column 'ExampleColumn'.
Msg 4922, Level 16, State 9, Server HENRI-XP\SQLEXPRESS, Line 1
ALTER TABLE DROP COLUMN ExampleColumn failed because one or more objects access this column.
At this point I could have just dropped the constraint using the name in the error message, however I had to apply the same change to multiple databases with the same schema. Of course, the generated name was different for each database.

I ended up writing a procedure that would look up the default constraint given a table name and column name in the sys views and drop it. It's pretty simple here is the code:
CREATE PROC dbo.DropDefaultConstraint
    @TableName sysname,
    @ColumnName sysname
AS
    DECLARE @defaultConstraintName sysname;

    SELECT @defaultConstraintName = OBJECT_NAME(default_object_id)
    FROM sys.columns
    WHERE object_id = OBJECT_ID(@TableName) and name = @ColumnName

    IF(@defaultConstraintName IS NOT NULL)
    BEGIN
        EXEC ('ALTER TABLE ' + @TableName + ' DROP CONSTRAINT ' + @defaultConstraintName);
    END;
GO
Of course, this isn't the kind of procedure you'd actually deploy to a production server, but it's handy anyway.

Wednesday, September 30, 2009

SharpDevelop Rocks

I'm starting a little OSS project and was thinking about writing it with a free IDE. C# Express was my first thought but I decided to try out SharpDev.

I last looked at SharpDev out a couple of years ago and wasn't too impressed. It seemed a quite unpolished and a little incomplete. Things have changed - alot! The latest version, 3.1, was released just last month and it's brilliant. It can do WPF apps. It has an integrated debugger. It supports IronPython. It even has a profiler!

I'm definitely using this thing.

Sunday, September 06, 2009

Installing Easy_Install and setuptools on Windows 7 64-bit/Python 2.6

This procedure worked for me.

  1. Download ez_setup.py from the PEAK site. (I found it here: http://peak.telecommunity.com/dist/ez_setup.py.)
  2. Run it!

Sunday, April 05, 2009

Left Joins for 1 to 0..1 relationships in Linq

Here is an example of doing a ‘left join’ between two classes with a 1 to 0..1 relationship between them.

We have an Employee class.

public class Employee
{
    public Employee(int id, int? bossId)
    {
         Id = id;
         BossId = bossId;
    }

    public int Id { get; set; }
    public int? BossId { get; set; }
}

And a collection of employees.

var employees = new[] {
    new Employee(1, null),
    new Employee(2, 1),
    new Employee(3, 2),
    new Employee(4, 2)
};

Each employee has 0 or 1 bosses.

Now to get a list of each employee and his boss, we can use the following linq query. (We want employee 1 to be in the list with a null boss.)

var result =
from employee in employees
join boss in employees
on employee.BossId equals boss.Id
into employeeBosses
select new {
    Employee = employee,
    Boss = employeeBosses.SingleOrDefault()
};

The trick is to perform a group join on the employee and his bosses and then use SingleOrDefault to collapse employeeBosses to a single item or null.