Regional and Locale Settings Affects Parsing Decimal Strings in C#

Yesterday, someone who was trying to use Jackknife, our gesture recognition library, reported that he couldn’t reproduce our results with our C# code. Naturally, we started looking into the issue.

Strangely enough, the code worked fine for me (both Debug and Release configurations). I then built the code under multiple versions of Visual Studio, tried both Windows 8 and Windows 10, and even built the code on Mono under Ubuntu. Everything was working as expected. He even sent me his compiled binaries so that I could try his build, yet to my surprise I was still getting correct outputs on all my machines.

Since our C++ code was working fine for him, I knew the issue was connected to .NET somehow. While trying to figure out what was causing this mind-boggling issue, I noticed that he was in Europe and I got this crazy idea that his operating system’s locale settings were interfering with something somewhere. As a last resort, I changed the regional settings on my computer to his region and voila! I was able to reproduce his problem!!

It turned out that in his region, decimal numbers are separated by commas, rather than periods, which is common in the US. Consequently, in that region the decimal number 123.45 is written as 123,45. In our tool, we were manually parsing CSV files. Since we hadn’t thought of issues like this, we were naively calling double.Parse() on strings containing decimals. Therefore, .NET was using the operating system’s locale settings to parse the string, giving completely different results than the ones we expected.

One easy hack to fix this issue was to force the locale of the current thread to “en-US” locale. The code excerpt below does exactly that:

In our C++ code, however, we were using std::stod which does not care about locale settings, so it was working fine.

Visual Studio Setup Blocked or Can’t Uninstall

For some reason a Visual Studio 2015 Community Edition installation I had on one of my machines was experiencing problems: solution files were not loading properly, and what’s worse is that installation instance had gone totally missing from “Uninstall a Program” in Windows Control Panel. Also, every time I tried running the setup file vs_community.exe from the ISO image, I would get an error saying “The product version that you are trying to set up is earlier than the version already installed on this computer”.

What I ended up doing was to run the setup file with the two following switches:

vs_community.exe /uninstall /force

Luckily, it went forward with uninstalling the instance I had on my machine.

Tracking down BadImageFormatException in C#

I know It’s been quite some time since my last post, but what can I say? I’ve been quite busy 🙂 Here is the latest issue that I got stuck on for a few hours, and I thought I’d share what worked in the end.

I was working on a large C# project that had a lot of dependencies on native C++ DLLs in Visual Studio 2015. I had compiled all the 3rdparty dependencies to DLLs myself and had included them in the C# project. On my main development machine, everything was working fine, but I couldn’t get the project to work on another machine with a clean Windows 10 install. The project would compile fine but would fail to run with BadImageFormatException.

From prior experience, I knew this error had to do with a mismatch between dependency architectures somewhere (e.g. 32 bit binary is trying to load a 64 bit binary or vice versa). However, this time I was so sure that wasn’t the case because I had built almost all the DLL dependencies myself and I knew that everything was built in x64 mode. Also, it was working fine on my development machine.

After a few hours of frustration and using the Fuslogvw.exe tool without obtaining much more insight about the problem, I decided to use Dependency Walker to see what’s happening. This great little tool did magic! I noticed that one of the dependencies that I hadn’t built myself was actually a 32-bit binary. The reason this was not causing an issue on my development machine was that as bad luck would have it, the 64-bit version of that dependency was in my PATH variable on that machine, so my C# project would load up the correct DLL. However, on other machines with a clean Windows installation, this wasn’t the case and because the only found binary was the 32-bit version, I would receive that dreaded BadImageFormatException.

CheckedListBox throws “Out of Memory Exception” When Adding New Items

I was using WinForm’s CheckedListBox control a few minutes ago and my application was crashing with an out of memory exception. This was happening on the line where new items were being added to the CheckedListBox. It did not make any sense at all, since I was only adding the second item to the control. Also, I was pretty sure I wasn’t being even close to running out of memory! 😀

By some happy coincidence, I figured out what the problem was. Some of the items I was adding to the list would return null in their ToString() method. Turned out that was what was causing the exception. I simply made sure that ToString() would not return null values and that solved the issue. .NET can sometimes be stupid 😀

I guess it is advisable to always write the ToString() methods with a blank string as the starting point (eg. return "" + this.ID so that it wouldn’t break in case ID is null).

Distinguish Between Touch/Pen and Mouse Input in WinForms

In WinForms, mouse events are raised regardless of the original source of the mouse. If you click a button with the stylus for instance, you’d still get the MouseClick event. This MSDN page explains how to distinguish between the sources of the event. To make the long story short, you’d have to place an API call to the GetMessageExtraInfo() function and check the returned value. The following C# code snippet performs the checking:

 

C# Deserialization of a List<> Returns a List with “null” objects

In .NET, the List<> class is serializable. However, you should note that during a call to the deserialization constructor of the objects the list contains, the list will be empty. All operations on the newly deserialized objects (such as value checking and so on) need to be performed in another function marked by the [OnDeserializedAttribute] attribute. More info on this can be found here.

Rotate a 3D object around its center and own axes in WPF 3D

In WPF 3D, various transformations could be applied to an object. One particular problem that I occasionally run into is when I want to apply a rotation transformation to an object and rotate it around its own center and axes.

The way I do it is as follows. First I apply 3 identity RotateTransform3D‘s to the object with AxisAngleRotation3D‘s objects underneath: one for the X axis, one for the Y axis and one for the Z axis. Then whenever I want to rotate the object around a certain axis, I obtain the corresponding RotateTransform3D object, set its center according to the (possibly) translated center of the object, and apply the rotation angle to the underlying AxisAngleRotation3D object. Some code will make this more clear.

First apply the 3 identity transforms to the object:

Let’s say the function SetRotation is to be used for setting the rotation of the object. It will work as follows: