Programming in C#, Java, and god knows what not

Help Me

Illustration

Good

After all those years of having help content in proprietary form, there is some change on sight. If you go into C:\ProgramData\Microsoft\Help3\content\Microsoft\store directory there you will find files with extension .mshc. There is no program registered for handling it but you can open it with WinRAR (or any other smarter archiver – it is actually a zip file). Snoop inside a little and you will notice that these are actually XHTML and image files. For some reason, while text has html extension, pictures have no extension whatsoever (those I saw were in PNG format).

You might wonder why I consider this to be such a big change. For one, formatting content to be in same form as Microsoft’s own documentation just got much easier. I am sure that at least some developers of components for .NET Framework will integrate their help into Visual Studio 2008. Having help for all your components in same format with cross-references between such independent component and .NET Framework itself cannot be bad.

I still remember old days when MSDN Library was highly useful even without Internet connection. Last few years formed such a huge gap between what was in local version of MSDN and what was in Internet version of it. I hope that if formats that are used on their Internet site are used also internally, there would be more frequent updates and gap would not be that big.

Bad

Help viewer is now same application you use for browsing Internet. It can be Internet Explorer, Firefox, Chrome or whatever your preferred browser is these days. Bad thing is that every browser has own issues with XHTML (less) and CSS (more) code used for display.

Internet Explorer does not align menu correctly on 120 dpi systems and that results in all code being below menu - not something that looks or works nicely (lot of scrolling involved). In other browsers, menu and content alignment is correct but there are issues with not quite getting window width settings just right.

Also there is no setting to limit browsing to only some subset of data – e.g. C# and .NET Framework 2.0. This way it is just too often that you can find a function you need only to see that it is not supported with framework that you need. With Visual Studio 2008 we got framework targeting. Maybe with Visual Studio 2010 we can get same support in help.

I cannot help but to count on .NET community to come up with much better help system than one in Visual Studio 2010. Just small application with local search and browser windows (with tab support!) will do. :)

Ugly

Startup time is awful. It is faster to load your favorite browser, go to online MSDN and find what you need there. And you can do it faster than local help can load first window. Maybe because Visual Studio 2010 is so fast that slowness of help system annoys me so. I cannot but to wonder what efforts were involved to make it that slow.

Conclusion

Maybe it will be a little unfair from my side (since Visual Studio 2010 is only beta) but if this is how help will look like, we may as well be without one. Only situation when it is semi-useful is when there is no Internet connection available.

Team Foundation Server Does Not Like Encryption

Illustration

I got my laptop from repairs and I got puzzled with Team Foundation Server not working. At once I saw one reason - SQL Server would not read from database files. Tracing back my steps before repair, I just decrypted files and everything was fine once more.

However, although I could see my collection in Team Foundation Server Administration Console I could not connect to it neither through Visual Studio 2008 neither through Visual Studio 2010. I just received message “Unable to connect to remote server”.

After confirming that indeed my server was down, I tried to start it back up from IIS Management Console. That failed with message that two additional services are stopped too - Windows Process Activation Service (incorrectly refereed to as Windows Activation Service) and World Wide Web Publishing Service.

Working on a hunch, I decrypted inetpub directory. After that was done, both services could be started once more. With that my Team Foundation Server went back among living.

Lesson of a day: be careful what you encrypt.

Structure Alignment

Let’s begin with example:

struct Test {
    Int16 A;
    Int32 B;
}

Since Int16 has length of two bytes and Int32 has length of 4 bytes one would expect total length of 6 bytes. However, upon check (with Marshal.SizeOf) we will discover that total length is 8 bytes. This difference is expected and allocated length is due to alignment of data structures.

When 32-bit processor reads data, it will do that in chunks of 4 bytes. If we want whole value to be read in one pass, it needs to be placed on alignment boundaries. If we want to read 4 bytes, we need those bytes to be at offset 0, 4, 8… or any other multiple of 4. This also explains length of first structure. First two bytes belong to variable A, then there are two padding bytes and final four bytes are variable B. Only function of those two bytes of padding is to ensure proper offset for variable B. Exact values of padding bytes are not of interest to us.

Alignment is almost always done on natural boundary of data type. 8-bit data types (e.g. Byte) will be aligned on 1-byte boundary, 16-bit data types (e.g. Int16) will be aligned on 2-byte boundary, 32-bit data types (e.g. Int32, Single, Boolean) will be aligned on 4-byte boundary and 64-bit data (e.g. Int64, Double) will be aligned on 8-byte boundary. All data types larger than that will be also aligned on 8-byte boundary.

To show it with example:

struct Test {
    Int16 A;
    Int16 B;
    Int16 C;
}

Length of this structure will be 6. This is because every variable is on natural boundary and there is no padding needed. If we decide that B needs to be Int32, length will jump to 12. This is because byte boundary needs to be aligned on 4-byte values and we will have padding after both A and C. This also shows how important careful ordering can be. If we make C Int32, total length will be 8 - no padding.

Calculating everything by hand can be sometimes quite annoying. This is why I made this function:

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
static void DebugStructureAlignment(object structure) {
    var t = structure.GetType();
    if (t.IsValueType) {
        Debug.WriteLine("Offset  Length  Field");
        int realTotal = 0;
        foreach (var iField in t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
            Debug.Write(Marshal.OffsetOf(t, iField.Name).ToString().PadLeft(6));
            Debug.Write("  ");
            int size = Marshal.SizeOf(iField.GetValue(structure));
            realTotal += size;
            Debug.Write(size.ToString().PadLeft(6));
            Debug.Write("  ");
            Debug.WriteLine(iField.Name);
        }
        Debug.WriteLine("        " + Marshal.SizeOf(structure).ToString().PadLeft(6) + " bytes total");
        Debug.WriteLine("        " + realTotal.ToString().PadLeft(6) + " bytes total (data without padding)");
    }
}

Just give it instance of structure as parameter and you will get offsets and lengths of all fields inside of it. While this function is not perfect and I would not be surprised that there are some errors inside, mostly it will just work. In case you are playing with Windows API a lot, chances are that you have something like this already written.

Visual Studio 2008 and Team Foundation Server 2010

Illustration

Team Foundation Server 2010 works great when combined with Visual Studio 2010. However, if you wish to combine it with Visual Studio 2008, some additional setup is required.

First thing that you need to install is Team Explorer 2008. If you already used source control, you may have it. Easiest way to check is to go into Tools > Options and select Source Control. If there is “Visual Studio Team Foundation Server” in plug-in list, you can skip this download.

Another thing I installed was Visual Studio Team System 2008 Service Pack 1 Forward Compatibility Update for Team Foundation Server 2010. I do not think that this long-named update is really “must” but I decided to install it anyhow - just in case.

Once you install everything, you can try adding Team Foundation Server 2010 as destination, but you will be greeted with error “TF31002: Unable to connect to this Team Foundation Server …”. Reason behind this is that old Team Explorer 2008 does not know anything about collections.

Solution would be to add it as full path (e.g “http://server:8080/tfs/collection”). I could not do it because every time I entered full path, I also got error “TF30335: The server name cannot contain characters ‘/’ or ‘:’ …”. Since official way would not work it was time to come up with alternative.

In order to add TFS 2010 server, you will need to exit Visual Studio 2008 and go into Registry editor. Find key “HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\TeamFoundation\Servers” and at this location just add string value. Name of this value will be what Team Explorer 2008 will use for display. It’s value is full address of your server. It should be something like “http://server:8080/tfs/collection”.

Now you can go into Visual Studio 2008 and Team Explorer will have new entry. As you work with it, you will notice that not everything is “bump-free” (e.g. tasks). However, source control it self will work perfectly and that was enough for me.

Adding References in Visual Studio 2010

Illustration

One of things that I noticed during work in new Visual Studio 2010 is speed of Add Reference dialog. This dialog now appears immediately while in old Visual Studio (2008, 2005…) this would take ages. I was quite stunned until I compared those two. There were two improvements that made this possible.

Loading of .NET and and COM references is done in separate thread. This means that while loading is in progress everything stays responsive.

Another improvement is that dialog opens with Projects tab as default one. Quite often this is exactly what you need - to add project reference. And even if you wish to add .NET reference, by the time your (non-threaded) hand switches to .NET tab, everything is already filled there (since loading is done asynchronously).

Worst case scenario is using COM objects and that will take awful amount of time for loading all references. But nobody uses those anyhow… :)

IntelliTrace May Not Be Your Friend

Illustration

Visual Studio 2010 has one great feature. I works like this (I simplified a little): you turn on debugging, wait for program to crash, load debugging log and you can walk through state of each variable in program, go back and forward in time - almost like working on live machine.

Microsoft used to call this Historical debugger, but now (with beta 2) same feature can be found under IntelliTrace branding.

Of course, this is only available in most expensive version of Visual Studio - Ultimate. Buyers of all other version can just drool. I know I will.

Failed To Create Mapping

Illustration

I tested Team Foundation Server 2010 a lot. Testing included creating project collections, adding solutions, removing everything, restoring from backup and doing this all over again.

Out of blue, I started getting “Failed To Create Mapping” error. Worst thing was that those messages referenced project collection that I already deleted.

I restored project from state before even adding it to source control and result was stubborn “Failed To Create Mapping”.

However, there is solution. There is configuration file at

%LOCALAPPDATA%\Microsoft\Team Foundation\3.0\Cache\VersionControl.config

Every Team Foundation Server connection gets stored there. Once I deleted ServerInfo for non-existing connection, everything was good again.

Visual Studio 2010 (Beta 2)

Illustration

Visual Studio 2010 beta 2 is available to all MSDN subscribers. Public release will follow on October 21st.

First thing that I noticed is bunch of editions (Ultimate, Premium, Professional and Express). This is probably how things will look once final version is out. While I am not sure what differences are among them, I am sure that Ultimate will be wet dream of all programmers. And do notice that you are allowed to go live with this beta.

Installation was quite slow, it required one restart and it did gave some bogus warnings (like trying to run PowerShell 1.0 on Windows 7), but I cannot blame it too much. This was on system where beta 1 was previously installed and I cannot say that some issues weren’t actually from uninstalling it. However, one hit on Retry button solved every problem I had. I must confess that this is quite sturdy installation.

I will stop with praises here since I am yet to test it in real-life. However, it does look nice.

P.S. Still no support for Windows Mobile. I guess they are saving that for final release…

To Have and to Lose

Illustration

Visual Studio 2008 had one great feature - guidelines. While this may seem as irrelevant feature to casual observer, it is indispensable if you are used to editing text document in RFC style. It was useful even in code files as a signal that line is getting too long and you need to consider continuing your code in next line.

Visual Studio 2010 (beta 1) gave us brave new editor with lots of features but, as you may guess it, without this one. For all people who loved this feature, it is quite sad that it will be omitted from final version also. While I can understand that it was never official feature to start with, I cannot get over it.

However, life goes on. There is great extensibility support in new Visual Studio so someone may even write this. Who knows, if time allows, maybe even I will do that.

[2010-04-06: Paul Harrington did it. Guidelines are back.]

Null-coalescing Operator

In my code there is lot of checks like this:

...
if (text == null) {
    text = "Some default value";
}

With C# this line can be written as:

...
text = text ?? "Some default value";

This will definitely make code shorter and while I use strings here, it is not limited to them. Any object will do.

Most of time I find this syntax less readable than first example. Part is probably because I am not used to it and part is definitely because of those question marks (??). Somehow they make me uneasy.

However, it is great help in your database layer when you need to get some value out of nullable type:

int count = dbCount ?? 0;

Once you need to set ten fields to defaults if their value is null, you learn to appreciate it.