Use a stringify macro:
#define STRINGIFY_1(x...) #x
#define STRINGIFY(x...) STRINGIFY_1(x)
#define VER_X_ 0
#define VER_H_ 2
#define VER_M_ 0
#define VER_L_ 3
#define SERIALNUMBER_STR STRINGIFY(VER_H_) L"." STRINGIFY(VER_M_) \
L"." STRINGIFY(VER_L_)
EDIT1: I added the L in L"." to have wide strings. I don't put a L#x as it got expanded with a space and something in the form L "string" is not a string literal in C. Nevertheless concatenating a string literal and a wide string literal result in a wide string literal.
EDIT2: As put in the comments, the example above work with the last revisions of C (c99 and c11) but not with c89 (i.e., not with MSVC). First reason is variadic macros are not supported in c89. The second reason is in c99 you can concatenate a character string literal and a wide string literal but in c89 this is undefined behavior. Below is a standard solution that also work in c89:
#define CAT(x, y) x##y
#define WIDE(x) CAT(L,x)
#define STRINGIFY_1(x) #x
#define STRINGIFY(x) STRINGIFY_1(x)
#define VER_X_ 0
#define VER_H_ 2
#define VER_M_ 0
#define VER_L_ 3
#define SERIALNUMBER_STR WIDE(STRINGIFY(VER_H_)) L"." WIDE(STRINGIFY(VER_M_)) \
L"." WIDE(STRINGIFY(VER_L_))
2*VERSION_Nwill give you the wrong result because it will only multiply theVER_L_by2since*has higher precedence than+.