Hi!
Itai Bar-Haim's solution is nice but has a problem with dead keys.
The first time you call CodeToString(int scanCode) with the scan code of a dead key, the return code of ToUnicodeEx() is -1 and your method returns the right value.
But on the next call, ToUnicodeEx() will return 2. The result string will contain the dead key before the expected result, followed by memory junk data.
For instance, I call your method with ^ (dead key) and then with $. The first call returns ^ (nice), but the second call returns ^$azertyui.
You must do two things to fix that :
1) You must use the ToUnicodeEx() return code absolute value to set the length of your StringBuilder. So you avoid getting junk data after the characters.
2) When ToUnicodeEx() return code is -1, you must take the first char of your StringBuilder as a result for your method. And then you must remove the dead key from the keyboard state : recall ToUnicodeEx() with the scancode of the Space key.
Another problem you could have : if the keyboard state has been modified by a user who hit a dead key before you call ToUnicodeEx(), the returned string will contains the dead key character before the expected value. A workaround I found is to call ToUnicodeEx() with the scancode of the Space key before the actual call.
Hope this help!