Thursday, March 20, 2008

Changing registration information in Windows Vista

I recently aquired a new HP laptop which I am fairly happy with. One thing that has been annoying me is the registered organization is for some reason set to HP. This is a minor annoyance but it has been nagging at me for over a month. So I set out to find where this is stored.

This setting is stored in the registry at the following key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion





The value is stored in the RegisteredOwner & RegisteredOrganization settings (See the screenshot above). You can double click on these to edit the information.

Enjoy!

Josh

Tuesday, March 11, 2008

Using the SerializationBinder for versioning

Normally when building an application I am a strong advocate for storing long term persistent data in a relational database such as SQL Server; however, with all things there always exceptions.

I am currently working on an application, that has at its core a complex object graph, with several levels of inheritance, and all sorts of references between the internal objects. At some point in the future I will be storing this object in normalized tables inside SQL server; however, because this project started out as a prototype which was loosely defined, and due to the wide variety of references within this object (And the undefined requirements of what it contains and how it works). I opted to store the object as a blob in the database.

This has been a huge win from a productivity standpoint since we can add all sorts of things to the object without worrying about the persistence tier. The negative of this comes when we want to change something. The .net framework has several hooks in place that help you modify an object which you using binary serialization with. One of these hooks is the SerializationBinder.

The SerializationBinder provides a means for you to do type replacement. Say for example you are building version 1 of an application. You spend hours designing testing and implementing it, and you ship the application, and your customers love the application and start asking for version 2. Unless you are superman you will probably not have designed everything ideally to support the features in version 2 (And if you did drop me a line, I have a job for you!).

I found myself in a similar situation, where I defined an object called MyCompany.Domain.Note. During our version 2 implementation, I realized that this shouldn't be a MyCompany.Domain.Note but instead needs to be a MyCompany.Domain.Widget.Note. So I change the class around, and run the application. This will result in all sorts of SerilizationExceptions since the Serializer is looking for MyCompany.Domain.Note which no longer exists.

This where the SerializationBindercomes into play. The SerializationBinder is an abstract class so you need to define a new class.


using System.Runtime.Serialization;
public class WidgetSerialzationBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
}
}


Implementing this class is very simple. In our case we want to make sure anytime we see MyCompany.Domain.Note we replace it with MyCompany.Domain.Widget.Note. Place this code in the BindToType method.


if (typeName.Contains("MyCompany.Domain.Note"))
{
typeName = typeName.Replace("MyCompany.Domain.Note", "MyCompany.Domain.Widget.Note");
}
return Type.GetType(String.Format("{0}, {1}",typeName, assemblyName));


The reason we are using contains/replace on the typeName is that we might know for sure what the typeName should be. For example if you have a List<mycompany.domain.note> you will need to change it to List<mycompany.domain.widget.note>. The actual type name in this case is: System.Collections.Generic.List`1[[MyCompany.Domain.Widget.Note, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

To use the binder you will need to set the Binder property on your BinaryFormatter. For example:


 public static object Deserialize(byte[] data,SerializationBinder binder)
{
object obj;


MemoryStream streamMemory = new MemoryStream(data);
BinaryFormatter formatter = new BinaryFormatter();

formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
formatter.Binder = binder;
obj = formatter.Deserialize(streamMemory);
return obj;
}


Enjoy!

Thursday, February 28, 2008

Fragmentation Analysis Report in Vista

For those who have been using windows for a while, are probally use to the old defragmentation tool which provided feedback about the current fragmentation of your drives via a graphical UI, and via a report which provided a gauge as to how fragmented your system is.

Microsoft made some good improvements to the disk defragmenter in Vista. First they have setup a schedule by default for the disk defragmentation to run. This weekly defragmentation is a huge step in keeping our disks nice and tidy.

Because it is now automated by defaulted, they also gutted the interface making it very simple. Gone are the color graphs and if you really want those graphs I suggest finding a third party tool which might have them. They also removed the option to get the fragmentation analysis report.

Not trusting Microsoft to properly implement something, I went looking for the analysis report to see how effective they have been defraging my drives (particulary since I am using a laptop which I usually power off).

What I found was that the command line tool defrag was still around and can provide the analysis report. In order to get it run the following command from a command prompt:
defrag c: -a -v


This will spit out a simillar analysis report. The only difference seems to be it doesn't list the most fragmented files.

From what I can tell Microsoft got this feature right. Without me doing anything my disk is has a 1% file fragmentation which considering my disks back on XP would sit around 9% after defraging the drive is a preety good thing.

Happy Defraging!

Josh

Wednesday, February 27, 2008

Fixing send to compressed zip in Vista

Today I was being my usual foolish self, and I went to the properties of the Send to Compressed folder FYI in Vista this is stored in:
C:\Users\<User>\AppData\Roaming\Microsoft\Windows\SendTo


I then changed the default program that is used, which essentially destroyed my ability to send right a compressed folder. I found it interesting that the command dropped off of my send to menu.

After digging around google and not finding anything to help me, I decided to scour the registry myself. I assume you know how to edit the registry otherwise you shouldn't be messing with the registry.

In the HKEY_CURRENT_USER hive is a section which stores the file associations that a user has made. The Send to Compressed file is stored as .ZFSendToTarget and is located here:
HKCU/Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.ZFSendToTargets


There are a couple keys here which are important:

  • OpenWithList - This drives the Open With menu you see when you right click a file. The values it contains are all the options in the Open With menu.

  • OpenWithProgIds - I am not positive on the role of this, but it contains a CLSID which points to the zipFldr.dll Search the registry for the key here and you will see what I mean. Based on how modifying the keys affected my system this looks like a default as long as the next key has not been created

  • UserChoice - This contains ProgId for the application I choose to use for this file type



  • Resolving this issue was very simple. Delete the UserChoice key and your Send to Compressed File option will again work.

    Hopefully your not as foolish as I was and change this in the first place, but in case you do this is a really easy fix.

    Josh

    Friday, February 22, 2008

    Replacing mailSettings with Web Deployment Projects

    Up until this morning, I've been able to avoid deciding how to handle environment specific settings for a new application I am working on. By using the hosts file, I was able to create a logical name for my SQL server for example which I could replicate accross my environments. This worked fine until this morning when I added email sending capabilities into the web application.

    I decided to go and implement web deployment projects which provide a way to replace portions of the configuration files. I set everything up and then following along with this article from Microsoft.

    I click build and I get the following error: Error 106 web.config(1): error WDP00002: missing section system.net/mailSettings.

    It turns out WDP's configuration replacement tool cannot replace SectionGroups. It can only replace sections. Both System.Net and mailSettings are SectionGroups and thus cannot be replaced out.

    If you want to replace the mailSettings you will need to target the smtp node so you'll want to use the following settings:
    system.net/mailSettings/smtp=<your config file>