They carry around their bridge library called MSVC redistributable, and that one is tied to compiler version. Fortunately for them they don't release compiler versions too often, but stuff you have on your Windows install perhaps carries around half dozen of MSVC redistributable library sets.
All Windows APIs are still C (stdcall to be precise) with some COM.
> All Windows APIs are still C (stdcall to be precise) with some COM.
Only if we are speaking about until Vista.
With Vista the majority of Win32 API are only COM, not "with some COM", even the userspace drivers are COM.
WinRT introduced in Windows 8, nowadays rebranded as UWP, is also COM.
Of course one can be masochist and make use of the low level C compatible COM bindings, or embrace ATL, WTL, C++/CX or the new C++/WinRT and enjoy productivity.
To clarify the above, new API's introduced since around Vista are more likely to be COM (and WinRT is of course entirely COM when used from C++), but the existing C API's have not been replaced, and some new C functions have been added since then as well.
I don't think it's unreachable, and I know plenty of devs who understood COM. I think the issue was a mixture of failing to match expectations combined with very poor marketing (specifically, shoving too many things under the umbrella of COM).
What people wanted COM to be was a way to share binary objects as DLLs—basically what the grandparent was assuming was actually the case on Windows. And at its simplest, COM is almost that. But what it actually did was provide something very different: a way to tell the OS, "Hey, I need you to give me an object that does X," where X was an interface you wanted the object to conform to, and then the OS would give you such an object, which you could address only by its interface. This is nothing more than factories/IoC in modern parlance, but it was new and confusing then, and people got frustrated.
Then, on top of that, Microsoft threw in a pile of other concepts. For example, if you want to use COM for system services, then, in the right situations, multiple people asking for a given interface could be given the exact same object—and this at a time when lots of devs weren't used to working with threading. And also, to accomplish that, you were doing local RPC, so here's also a full serialization framework, which you're probably also not used to. And also because now things are multithreaded a lot of the time, here's a way you can make your COM object single-threaded (think Java's synchronized keyword).
Nowadays, most of this isn't a big deal. Devs are used to RPC (via HTTP/JSON or things like gRPC and Thrift). They're used to factories and IoC. They're used to a single shared "object" being used by multiple processes in multiple services. But at the time, it was a lot of new stuff all at once, and I think it was just too much.
The core of COM is simple, elegant, and definitely "reachable". Don Box's "Essential COM" is a great book on the topic that clears away all the cobwebs that you fear are there. The more advanced topics do indeed become a bit more complicated.
The core idea of COM is that you have objects that you solely interact with as a client by using interfaces. An interface is just a set of methods (under the hood, it's an array of function pointers, in the form of C++ vtables). An object can implement multiple interfaces.
So, for example, in the context of a videogame, you might have a player object that you can send joystick input to, you can render, and and you can persist to JSON. That object would have something like IInput, IRender, and IPersistence interfaces. If you have a reference to any of these interfaces, you can ask that interface for any of the other interfaces (QueryInterface).
At the heart of COM, that's really all there is to it. Method dispatch is as fast as C++ virtual functions because that's exactly what they are under the hood.
There are layers on top of COM which start to add complexity, particularly when you want interface/method discoverability. But you often don't need that, particularly when working with C/C++. I've worked with code (long ago) where just the core of COM was used, and it's really quite straightforward.
There is a subset of COM that is elegant and usable. And there is a ton of stuff that is only rarely used and understood. I'm looking at you, apartment models.
Basically, COM are conventions how to layout structs and name functions, such that other code can load your DLLs. Coincidentially, they are almost identical to C++ classes, so you can often just return a pointer to a C++ class.
There are layers and layers of conventions stacked, which makes it a bit complicated. On the low level, you can call stuff by knowing the memory layout. You have a header file and a pointer, and call the function at pointer+4. Fine for consuming from C/C++. Later, they developed IDispatch to call a method by string name (good for Visual Basic or scripting). There were interfaces to make Widgets (Custom controls / ActiveX). I personally found that the documentation for all that stuff was not very good.
However, it was fairly easy to create and consume COM components Visual Basic (and to some extend MSVC). There was a booming market for VB custom controls long before .NET. Its a bit unfortunate we don't have something like that today.
Basically WinRT, being based on COM, with .NET being compiled to native code via .NET Native and UWP controls being implementations of IInspectable, is the return to that original design idea of the COM+ Runtime.
All Windows APIs are still C (stdcall to be precise) with some COM.