Microsoft

TFS Made To Suck Less!

I suppose I should come clean about something. I recently installed the Team Foundation Server PowerTools and have been using them successfully for a while. They have one or two very handy features that make TFS suck less. Get them direct from the TFS PowerTools page at MSDN.

Online Mode

Using the tfpt.exe command line, the 'online' mode will search your repository for changed files, added files and removed files and check out, add or remove the files as necessary. It also has a simple preview mode. This means that, with only one extra step, you can fix all the missing icons or forgotten checkouts or whatever. It would be nice not to have to do this step at all, but at least it's not entirely manual now.

Annotation

The PowerTools add a new feature to the Source Control Explorer: Annotation! Now you can actually see, line by line, who changed what, why and when. Jolly good.

Recursive Diff

Probably the biggest, most important change is the ability to diff entire directory trees. This will show you a nice window with all the missing files, all the changes, all the things that have not been checked out but should have, and everything else all in one lovely window. This alone is worth installing the PowerTools for.

Unchanged File Undo

A problem that arises from the 'check out required' nature of TFS is that sometimes Visual Studio checks things out automatically that are then never edited. When you check in, the files haven't changed so are not included in the changeset. This means you have a bunch of unchanged files marked as checked out. Very annoying.

Enter the tfpt.exe command line tool, with its 'uu' command. I assume that 'uu' stands for 'undo unchanged' or something. It basically performs an 'undo' on any checked out files that haven't actually changed since being checked out.

News just in: Team Foundation Server sucks. More at 11.

One of the banes of my current working life is the heaping mound of crud known as Team Foundation Server. I know I've ranted about it before, and I'm sure I'll rant again. Such is the heinous evil that is TFS.

This time, I'm going to list 4 things that TFS does (or doesn't) that means it's completely unsuited to modern development practice. I'll be comparing the functionality with that of Subversion, currently a very popular open source VCS that I like a great deal.

So, on with the rant ...

VBA Unicode done right, redux

Some time ago I wrote a short article on forcing VBA to use some form of unicode to allow simple insertion of non-latin1 text into VBA modules. It sort of worked, for the most part, kind of. Well, it didn't. The problem is down to the VBA editor being locked to the local encoding of the machine it is running on. You can only type characters from BIG5 in China, Shift-JIS in Japan, and so on. If you have a need to make a VBA module that uses strings suitable for all locales ... you're pretty much stuffed.

Except you're not. If you do it properly, you can have any unicode character displayed in any VBA locale. So how do you do it properly? Well, you're supposed to use ChrW$() to generate unicode characters individually. Yes. Really.

VBA Unicode done right

IMPORTANT UPDATE: It seems that this is one of the most popular posts on this site, so VBA's useless unicode support is obviously a big issue. Seeing as it's so commonly searched for, and seeing as many people don't know the first thing about Perl, I've knocked up a small Windows tool that does the job. You can find it at the updated version of this post. Everything below this line is obsolete!


Some time ago I wrote a short article on forcing VBA to use some form of unicode to allow simple insertion of non-latin1 text into VBA modules. It sort of worked, for the most part, kind of. Well, not really.

The problem, you see, is that the VBA editor is extremely stupid so won't display non-latin1 characters unless that's your machine's native codepage. Couple that with the compiler, which is also pretty stupid, that actually breaks encoding rules if you have the audacity to sign your modules with a proper certificate. It basically forces a revert to the native codepage making non-latin1 text look ... well, ridiculous.

Source Control done badly, badly wrong

Some people are lucky enough to work with technology that does its job well. So well that you barely notice it. So well that, if you were asked what the root cause of any problem you've had was, you'd have to say "erm, it was my fault.".

Not so Team Foundation Server. Microsoft's replacement for SourceSafe is possibly the worst version control system ever devised. Not only is it entirely unreliable, not only does it still use paradigms that died with exclusive file locks, but it also loses work.

So I develop a substantial set of changes to a project, across three different sub-projects stored within TFS. I commit. I move on with my life. A couple of weeks later, after several calls to get latest, I discover that my changes have, quite simply, disappeared.

There is no sign of the commit, there is no sign of the new files I added, and every single file I modified is pristine, as if I'd never edited it. This also means that, with the exception of the new files, the copy of my hard drive is essentially gone.

So what went wrong? Well, I know that TFS has a habit of 'forgetting' to tell you when a commit failed. Or telling you, but making the error so innocuous that you'd be forgiven for not even noticing it. It also has a habit of trying to pick the files to commit out of the modified files in your project without your assistance, and getting it very, very wrong.

This all stems from one major oversight right from the start. Although it is like CVS and Subversion in that it can merge two changes into one file, thus allowing concurrent development, it still relies on the user to 'check out' the file. Once the user has 'checked out' the file, it will know to include it in the commit. Unfortunately, this is buggy as hell. The Visual Studio plugin regularly misses edits to files, and if you edit a file outside Visual Studio (surely not!) then it will never be noted as checked out.

In some ways I could admit to it being my fault. I'm expecting it to work in a sensible manner. I'm expecting it to use file modification times or diffs or something to determine if a file has been changed since it was retrieved from the repository. I'm certainly not expecting a system so retarded that it requires the end user to manually tell it that a file is now different.

So there it is, two weeks work all but gone, because of the stinking pile of crap known as Team Foundation Server. If you're using this, install Subversion. You'll thank me, you really will.

Update: One more wonderful little gotcha ... If you have two copies of Visual Studio open and check out a file in one, the other won't notice. That's right, each one holds a cache of what it thinks the situation is and never, ever refreshes it unless you explicitly remember to tell it to at an opportune moment (the first of which is in the commit dialog, I think). So if you do a pile of work in one instance, switch to the other and tie up the other end of your changes, then commit, you'll only get half of it.

Truly it fits the Microsoft way, making the programmer work harder so the software doesn't have to.

Týpïñg Àll Chäráçtêrs ìn Wiñdøws - Üpdátêd

Working at a company that produces software to assist in machine translation of documents, staffed by people from all over the world, it's sometimes handy to be able to type non-english characters. Windows doesn't exactly make that easy. If you have a keyboard for the language in question it is fine, because you can use various mode switch and shift keys to build up the keystrokes required to get the necessary characters.

Unfortunately, I don't have all those shift keys and switch modes and such. I'm English, and get lumbered with the most basic keyboard in the world. I have no extra keys. Now, on a Mac or Unix machine it's OK. The Mac uses option+key to create umlauts, graves and so on, and anything running X11 can use a compose key to make just about any character known to man. Windows is rather more ... arcane. You can press altGr+key and see what you get, but that seems to be pretty much random and changes system to system, or you can hold alt and type out the unicode number for the character you want.

Visual C++ Incompatible time_t Types

One of the main reasons for using the correct named types in C programs is to ensure that, for a particular compiler on a particular architecture, the type is as expected at all times. One of these is time_t, for representing timestamps. In most compilers it is a 32 bit integer value, but you cannot just blindly assume that time_t can be cast to and from int, or long, or whatever, at will.

There is an issue with closed source, binary only libraries. What if you are linking them against a different compiler to the one they were built with, and what if it has a different idea of what different types actually are? Well, bad things can happen. In Visual C++ 2005, time_t is defined as a 64 bit integer. In all previous versions it was 32 bit. To demonstrate what can happen, consider this library, built with VC++ 2003, that exposes the following function:

    void populate_user(int user_id, user_t* user);

The type user_t is defined as a structure in the distributed header file like this:

    typedef struct _user_t {
        char username[8];
        time_t creation_time;
        time_t lastlogin_time;
        char realname[64];
    } user_t;

It's a fairly simple struct, but it'll do to demo the problem. So we build a new program that links against our library and #includes our header. It creates a new variable on the stack of type user_t and passes a pointer to it into the exported function.

So what happens? Well, the following values are inserted at the given offsets:

Member Offset Value Memory Contents
username 0 craiga 72 63 69 61 61 67 00 …
creation_time 8 1199215958 47 7a 95 56
lastlogin_time 12 1199216158 47 7a 96 1e
realname 16 Craig Andrews 43 72 61 69 67 20 41 6e 64 72 65 77 73 00 …

However, when that little lump of memory makes it into our VC++ compiled program with its 64 bit time types, this is what it looks like:

Member Offset Value Memory Contents
username 0 craiga 72 63 69 61 61 67 00 …
creation_time 8 5150594180643984726 47 7a 95 56 47 7a 96 1e
lastlogin_time 16 7944666846179979843 43 72 61 69 67 20 41 6e
realname 24 drews 64 72 65 77 73 00 …

What happened?! Well, all the offsets of the members are wrong. The two 32 bit integer values in the library have been crammed into one 64 bit field in the program. Then, the contents of the realname string have been used to populate the time values. The end result is that the realname string is offset by 8 characters and the two times are completely garbled.

Unfortunately, unless the vendor has provided a workaround, you are pretty much stuck with it. Fortunately for us, Microsoft have actually given us a sort-of fix for this issue. Simply include the definition of _USE_32BIT_TIME_T in your project's (or file's) Preprocessor Definitions field and you're away. Unfortunately it means that anything linking against your older binary will be stuck using 32 bit time_t, even if you want to use 64bit time_t. Not a great solution, then, but better than the alternative!

Windows Programmer's Keyboard Layout for Apple Keyboard

As my previous posting indicated, I now have a new aluminium Mac keyboard on for use on my Windows development machine. I also provided a link to the keyboard drivers and Boot Camp control panel. However, there was a problem!

For some ridiculous reason, the £ symbol is used on the 3 key, and you have to press ctrl-shift-3 to get a # symbol. For a programmer, this is not a good situation. The # is needed far more than £ ever is. What to do? Well, I figured I could do the same as I do on my MacBook; use the US keyboard map. The benefit is that it's exactly the same as the UK keyboard map, with the # and £ switched around. Marvellous. Could I find one? Could I hell.

Here's where the Microsoft Keyboard Layout Tool came in handy. I've created a keyboard layout based on the United Kingdom (Apple) layout installed by Boot Camp with one very small change.

  • The # (hash) is now accessed by shift-3
  • The £ (pound sign) is now accessed by ctrl-alt-3

Brilliant. You can download the United States (Apple) for English (United Kingdom) layout by just clicking the link. Have fun!

Another new keyboard? Apple Aluminium

Yes, another new keyboard. This time it's an Apple Aluminium keyboard from the new iMac line. The basic reasoning behind this purchase is because I have wrecked the knuckles of my right hand in a fight with a door and a pane of glass, so I can't bend my middle or index fingers. This means that traditional keyboards cause a problem due to their long key travel, but notebook keyboards are fine. The new Apple aluminium keyboard is almost identical to the 'chiclet' design of the MacBook, so is very much like a notebook keyboard writ large.

Some musings on Microsoft

Over the last few days I have been thinking. A dangerous habit, but an important one. In this case, I've been thinking about why people continue to use Microsoft products. The old adage "Nobody ever got fired for buying Microsoft" is hardly relevent, because it only shows that the people doing the firing are not the same people as those who are supposed to be technically capable. There are three things that have brough on this round of thinking.

Syndicate content