Tuesday, 29 November 2011

object does not match target type

Another of MSs suitably abstract errors which don't really tell you what is going on. They have gone to the effort of catching a problem so why not describe it better?
Anyway, I got this while calling onto a Rhino mock class which I had supposedly setup an expectation for. It was unusual since my understanding would be if the expectation matched, I would get a response and if it didn't then I would get null back and it would fall over elsewhere. There is obviously a middle ground.

The code in question was this:
internal void EstablishDetect(DetectRequest detectRequest)
    mock.Expect(proxy => proxy.Detect(detectRequest)).Constraints(Property.AllPropertiesMatch(detectRequest));
A fairly simple use of the expectation. The problem appeared to be the fact that one of the request properties was a class, not just a number or string etc. and in the code I was using, effectively, I was using this for the expectation:
req = new DetectRequest { Id = Id, Stage = new ClassA() };
but calling this on the mock:
req = new DetectRequest { Id = Id, Stage = new ClassB() };
The different class was intentional and I would have expected if these didn't match, the AllPropertiesMatch() would fail and therefore the mock would return null. In fact, it generates the above error, "object does not match target type". All I had to do was to set-up the expectation with the same class I was passing into the actual call and it was fine.

Wednesday, 23 November 2011

Windows XP Activation - evil

The problem with any reasonably secure activation system is a) it will cause a lot of problems for certain people/hardware and b) it will probably be hackable anyway. I had just endured the pain of losing my linux files due to the terrible way in which windows installations simply overwrite the master boot record ignoring any existing systems in my case actually overwriting it with a new type of boot record (GPT) which was incompatible with Windows XP 32 which  then couldn't install. I thought my pain was over, all I needed to do was boot XP, install any missing drivers and be done with it. Oh no.
Activation. I have a legit copy of XP (although I had lost the key) so I expected to at least be able to get 30 days to find my key so I could activate it. In order to get past the installation, I used some key I found on the internet (expecting it to be blacklisted for activation).
I booted up to the login screen and was immediately told I had to activate before I could log in and surely enough, my only options were to activate or it would log me back off. This didn't seem right, I had never come across this before.
Surprise, surprise, there is a bug in the way activation works. The simple cause was that I had no network installed because neither of my drivers (wired and wireless) were installed by XP. Firstly, this causes activation to get confused and think you have done something bad which requires immediate activation (which is understandable if it worked) but the major problem is then you cannot activate over the network (no big deal) but if you click "telephone", it displays a page with your hardware id which is - BLANK. Why? Because part of this key comes from the network card which is not installed yet. I called Microsoft but they were mostly useless and told me to ring tech support.
What I had to do was reboot into safe mode (press F8 when starting up) but NOT safe mode with networking, that won't work. In safe mode, I had to get the network drivers (via CD because the network wasn't working) and attempt to install them along with the video drivers. The wi-fi installer wouldn't work in safe mode but the lan looked like it did. I also tried this hack to disable the activation check by changing a registry key.
Rebooted into normal and it still said I needed to activate but when I pressed "Activate Now", it told me I was already activated (presumably because of what I changed in the registry) so I changed it back. Rebooted again and this time it told me to activate and brought up the screen to activate. This time, the lan was enabled so I brought up the internet activation window and it told me my key was invalid (as I expected). Since I couldn't find my key, I found a key gen on t'internet and it generated me a key that worked! I then had the joy of installing service pack 1 and then 3 although after 3 was installed, the screen started working properly and the whole thing seemed better. I then obtained and installed the remainder of the drivers from the Samsung site (they are hard to find!) so that there were no more little yellow icons in device manager.
Now all I have to do is reinstall Ubuntu which will take MUCH less time (and no activation).

The pain of Windows XP installations! MBR/GPT

I have spent about 10 hours of time trying to install Windows XP as a dual boot on my Linux laptop and all the problems I had and the fact I lost my Linux partitions are all related to Microsoft's selfish installer that overwrites the master boot record rather than installing alongside whatever is already there but it is worse than that.
I have two Windows XP CDs a full 64 bit one and an upgrade 32 bit one and the reason I am installing it, although I am more than happy with Ubuntu is because, as you might expect, there is a piece of software I want to use that only runs on Windows and Mac.
Simple, I thought, I've done it before. You partition your disk from the Linux boot CD using GParted and then run the windows installer which overwrites the MBR. You then re-run the grub install from the bLinux boot CD and you're back in business. Except I wasn't.
The problem I had related to something I didn't know existed. Guid Partition Table (GPT) which is a more modern and better use of the master boot record that doesn't require a limit on primary partitions and the funny use of extended and logical partitions - fair enough. What I didn't realise was that Windows XP 64 bit (and presumably other new Windows) installs this without telling you that it is totally incompatible with older systems like Windows XP 32. This wouldn't have even been noticed since grub can handle GPT except for one problem. I installed Windows XP 64 bit and most of the drivers for my hardware weren't there (or even on the net, they were probably never written). So I had got a working dual boot system with XP 64 but which was mostly useless.
No problem, I thought, I'll just run the XP 32 bit installation and choose the XP 64 bit partition as the destination and it can overwrite everything. Right? Nope. Run up the XP installation CD and all it can see is 131Gb of an unknown partition type (it's 160Gb disk but more on that later). I was confused. What was happening? Ah. Maybe I need to re-run grub to reset the MBR before the installation will read it correctly. Nope. Still the same. I couldn't work out what was happening, even from Google so the helpful people at ubuntuforums suggested the problem was related to my new GPT boot record which XP 32 didn't understand. They were right so now I was a bit stuffed, how can I overwrite the GPT with MBR so that XP 32 will understand?
This is where I cocked up a bit. I ran up GParted again and found out there was an option to re-write the boot record (with the MBR format) which I chose. It warned about data loss but I presumed it meant there was a risk. What actually happens is that it wipes all the current partition information and then writes the MBR. I tried disktool to get them back but somewhere, they must have experienced a quick format and lost the data. I wasn't too bothered. I have a backup of most of my stuff and use Google quite heavily, at least.
So I then spent the next hours trying various combinations of GParted and diskpart (the windows equivalent) as well as fdisk to try and get XP 32 to read the 160Gb disk. It was like nothing made any difference. Was I actually resetting the MBR at all?
This was when I learned something else. Various combinations of HDD, 32 bit OS and BIOS settings means that the installation would only be able to 'see' the first 131Gb of the disk. What I ended up doing was what is suggested for a clean dual boot install. Do Windows XP first. I removed all partitions, created a 50Gb partition for Windows to use and then ran the installation. Did the pain end there? Nope, see my next post.

Tuesday, 15 November 2011

Internationalisation - ooo, err

Perhaps it is Internationalization? We live in a global market now with a web site in Nepal appearing in the Google results of Brazil and one of the knock-on effects of this is to make sure your web sites are foreign speaker friendly.
Unfortunately, this whole area is very complex because languages are complex, alphabets vary and you might have a Chinese person living in an English speaking country - all of this adds up to a headache which for most people is simply avoided. It needn't kill your brain however, I thought I would guide you through some of the pitfalls and give you some pointers to how to make your web sites work for more than just English people.

  1. Use a pre-built application framework where possible, one that already includes functionality for multi-locale functionality. It is much easier if you use something pre-built even if it is slightly different than you might have designed it.
  2. Learn what the words mean. A locale is a means of formatting dates and times. It is generally related to a single country or groups of neighbouring countries and to a single language. For instance, you can get a locale for Spanish (Spain) and a different locale for Spanish (Mexico).
  3. A language is a complex idea since some languages are really just dialects of each other. For the most part we are concerned about languages that have different written forms rather than spoken forms since our websites are predominantly written down.
  4. For practical reasons, if we make our site multi-lingual, we should restrict the languages we support to a minimum. For some of us, we might be happy with English, Spanish, Portuguese, Russian and Chinese as covering most of the globe. For others we might have Mandarin Chinese and Yue Chinese (Cantonese). Of course, if we are a Chinese site, we might have 12 Chinese languages. We would probably also decide that Scots English is close enough to English English to not need a separate translation (although again in some specialist areas this might be required).
  5. It is easier to de-normalise databases for language work and make each row a single language selection. This row might have a country name, locale, language name (possibly translated into the other language e.g. Deutsch instead of German). Some of these values might be duplicated but it makes for easier administration.
  6. If you want your site to be highly multi-lingual, consider adding a system whereby volunteers can translate the words for you rather than you having to pay people to do it.
  7. Use as few words as possible on your site and use pictures where these are clearer. A picture of an exit door saves you umpteen translations of the word "Exit".
  8. Try and auto-detect the language from the browser post variables for convenience.
  9. It should be easy to get to the language you want. If you have, for instance, logged onto a site in China but are an English speaker, your site might have detected Chinese as the browser language and left you staring at something you cannot possibly understand. By using something like a flag in the top corner of all pages and translating the language names into those languages, it should always be easy to find the language you want.
  10. Try and monitor the translation status of languages on your site and if you feel they are not adequately finished, include a mechanism to disable the language. It would look pretty lame if your site was only 10% Tajiki when switched to that language.
  11. Default all messages to English if there is no suitable translation (don't put blank strings there instead!)
  12. Do not re-invent the wheel. Even if you are building your site from scratch (which you hopefully are not!) the data for countries and locales is all out there for free, do not type in the names of 6400 languages.
  13. Unlucky for some

Friday, 11 November 2011

Find in Files - Linux Style

Lots of people ask this in forums and there are various complex answers that come back - enough to make the most hardened GNU cohorts shiver. Anyway, dead easy, just use grep from the command line.

grep -r 'search term in here' *

-r is to recurse sub directories and the * says look in everything. The result is written to the console but you could always redirect it to a file using "> something" at the end (without the quotes of course).

Cannot cast enum from type A to type A

This is a common error that doesn't seem to make sense. How can you not cast an enum from a type to itself? Makes more sense when we realise that types are often shared by copying libraries between projects. We might create a service contract version 1 and then add an enum entry and create version 2. We update the sender with version 2 but not the receiver and then we get the error listed above.
Trying to get another piece of code working was taking much longer than it should have and I thought that the change was pretty easy. Unfortunately, the fix I was making was in a shared library which then had to be copied into another project which would run the code (and fail!) and without any easy way to get the debugger to work without project changes. What I realised was that there were various combinations of things I was trying but I wasn't recording them. Use update panel or not? use declarative event handler or code one? Deploy to deployment folder or bin folder? Am I testing the code that I've changed or not?
All I needed to do was actually write down the combinations I had tried and then be careful to point the web site I was testing to the correct place (we effectively have two web sites in the project). Once I did this, I realised that I had missed a combination, one that worked, and that the code was correct, I just kept breaking one thing as soon as I fixed something else.
Be methodical people!

Thursday, 10 November 2011

Web site referencing wrong versions of DLLs

Classic problem here. Visual Studio web site project that includes various projects and a number of MS and third party dlls that are referenced. A specific project was referencing Microsoft.Practices.Unity version 2.0 whereas when we built the project, we got the error "Thirdpartylibrary.dll references Microsoft.Practices.Unity version 2.0... which is higher than the referenced version 1.2".
Checking into it and the only version we reference is version 2.0 and I couldn't see where the version 1.2 was possibly copied from (into the website bin directory). Eventually I resorted to modifying a Powershell script which listed every dll in our project that was referencing Unity and looked for one which was version 1.2. It turned out to be EnterpriseLibrary.Logging, something we no longer used (and something which wouldn't obviously reference unity). Removed all references to that and it was fine.

Thursday, 3 November 2011

There was an error reading from the pipe: Unrecognized error 109 (0x6d).

It's annoying when you see an error that lots of people report but you can't find out any useful answers! I had this today when calling a Mock via a named pipe. It was a case of having changed so little and not seeing what might have caused something that looked so serious.
Anyway, after following advice from another post and enabling WCF logging in the app config for the unit tests, the log DOES include the error and its in red so nice and easy to find. The problem? I was returning an object from my mock expectation which had about 20 properties, only 5 of which I wanted to consume and therefore which I set. It turned out that one of the properties I hadn't set was an enum that defaulted to 0 although 0 was not a valid enum entry so the serializer was throwing the error.