"Linux" is only the kernel - i'm not trying to be pedantic, this is the actual issue actually. The kernel has a stable ABI, you can run software from the late 90s on modern kernels and it'll work, but it'll work only as long as the program either makes these calls directly or all the libraries it links to dynamically also provide a stable ABI.

A "Linux distribution" or "Linux OS" or whatever people install in their computers and call "Linux" is not just the kernel though, it is the kernel and a bunch of additional software and -most importantly- libraries on top of it that provide functionality the kernel itself doesn't provide. This includes stuff like getting a desktop environment, which is often made up of -among others- several dynamic libraries that provide functionality such as opening windows, providing elements like buttons, checkboxes, inputboxes, etc and of course handling graphics and user input.

Very few of these libraries however provide a stable ABI. On average, you can expect a program from the late 90s that uses the GNU C Library and X11 to work because those libraries provide stable ABIs (as long as you are not trying to abuse them and do not use undocumented features) but anything beyond becomes harder. cURL does provide a stable ABI since the 2005 and they promise not to break it, but there are very few libraries that make such promises (for many that haven't broken their ABI it seems to be more of a consequence of their development than an explicit goal). It is really up to the developers of each library to keep their ABIs stable - assuming they care of that in the first place (IME with talking with some developers, even here on Hacker News, many do not care or even seem to actively refuse to understand what the problem is in the first place).

All the above means that Linux distributions come with a lot of different libraries and library versions (so even if a binary depends on libfoo and libfoo exists on the system, it will still not work if it depends on libfoo version 1 but the system has libfoo version 2 which broke compatibility with version 1) just to provide a regular desktop environment.

On the other hand on Windows you get a ton of functionality out of the box - not just for making GUI applications, but also for networking, graphics, audio, video encoding and decoding, etc. Even if that stuff aren't the best in class, they're there and applications can simply depend on them.

More importantly, Microsoft promises to not break the Windows API ABI and that promise has held for literal decades.

In the case where an application needs more/different stuff, it doesn't need to provide everything of the above, it only needs to provide the stuff that it needs - e.g. a video encoding application can use the GUI functionality that Windows provides but still use ffmpeg for performing that encoding. While it'd be duplicating functionality that technically Windows already provides, it'd only be functionality related to encoding, not everything.

So basically, Windows applications tend to pretty much always work because they can rely on Windows to both provide a lot more functionality out of the box and remain compatible than Linux applications do.

Note that this is not a technical problem but a cultural problem - most Linux developers of libraries that would be the equivalent of parts of the Windows API that has remained stable over the decades do not believe that such backwards compatibility is important or even possible (assuming you can get them to accept that there is such a problem in the first place).