Microsoft pulled it off with dotnet, sort of, because they approached it like a completely new language, sold people on the benefits of it.
And the people they were selling that to, ( It's free and open souce now! ), were a very different group to the market they left behind on .NET Framework, who are often still struggling to make the transition now.
Had they actually killed off .NET Framework, it would have been a different story, much more like the VB6/VBA to VB.NET transition, which so few people bothered with that VB.NET died out, because if you had to retrain that much, you figured you might as well go to C# or a instead, or indeed a completely different language entirely.
I briefly worked professionally on a VB.NET project, but outside that job I've never met anyone else who can say the same. I've met a few who went straight from VB6 to C# though.
The whole push behind .Net Core was to get .Net running on Linux well and natively and was being lead largely by those of us using .Net for web. We were being murdered by other languages at the time; mono was an option but Microsoft shops usually needed to target something blessed/backed by MS.
Largely the same market (Enterprise) but not the different segment (web as opposed to Windows/WinForms).
I ported about 15 years of projects from various versions of .Net to .Net Core whilst they were developing (and sent feedback to the team - they were asking us to do that) and the process was pretty reasonable. You were only really stuck if you were using something very very Windows specific (certain image processing libraries iirc) and even then it was largely manageable.
The old full-fat framework is, AFAIK, still supported, as there's a whole lot of legacy code which is Windows specific which is still expensive / hard to port over.
Unfortunately "something windows specific" was pretty broad.
Between MSMQ, WCF over named pipes, MSDTC, and MSI installers, there's a lot to replace that is hard to provide the same guarantees or performance with straight replacements, if they even exist.
The end goal, being on modern dotnet, is better, but it's difficult to get there with a phased approach without accepting a temporary worsening, which is often hard to sell.
Both of those were a vendor X electing to stop updating framework A in favor of framework B. That’s a high cost for vendor X’s users, but if their business depends on vendor X, they have no choice. Maybe they can switch to vendor Y at that point, but now you are switching both vendors and frameworks.
Replacing CUDA with another framework has much lower motivation. That advantages of the new framework must cover the switching costs and the risk of such a switch. All while CUDA continues to evolve and allow access to additional features.
Apple and Microsoft had something of a captive userbase. New vendor on the block trying to replace CUDA does not.
Neither of those are a competitor replacing another, they are a same-vendor replacement. This is easier, because the company whose established product you are trying to displace is cooperating (because its you!) not actively resisting.