A lot of the original designs of Windows were elegant in theory but never simplified and unified. COM objects are a good example, they were just a pain to deal with from languages at the time (and arguably still are).
That’s indicative of poor bindings for those other languages.
The nice thing about COM is that it provides a well-defined, C-based ABI for calling object-oriented interfaces; if your language has a FFI that supports C, then you can call COM objects.
I’m a big believer that COM bindings for any language with automatic memory management should not expose refcounts directly to the programmer (at least in 90% of cases). It’s not far fetched — the original, pre-.NET Visual Basic did a very good job of this.
COM was still a pain even when using MS languages. The WinRT era COM is a bit better but WinNT era was just needlessly elaborate. Everything was done with giant 128-bit GUIDs that were impossible to recognize or memorize, so they added a naming layer on top but it wasn't used consistently. COM servers had to be registered before they could be used, and that was the _only_ way to use them, so you couldn't just export some objects from a DLL and load them directly from that DLL (or at least it wasn't well documented, my memory is getting fuzzy about this stuff). Then you had the obscure thread safety approach in which instantiating some kinds of COM objects would create an invisible window that you were just expected to know about and then you had to write the boilerplate to pump the message loop, if you weren't doing the COM call on the UI thread. Etc.
The goals were good, and other platforms haven't really tried to achieve them (KParts and Bonobo were the closest equivalents but both were abandoned a long time ago, DBUS isn't quite the same thing). But COM was fiddly.