Hey guys,


So I've been slamming my head hard against this one for about a day now, and I'm at that point of wit's end. Here's a little background: a few years ago, I built a program in C# that does some automation using the UIA ("Microsoft UI Automation") API. Then Windows 10 hit, and with it came a bug that made managed UIA painfully slow. So I wrote a DLL in C++ to do the heavy lifting. All the DLL functions rely on this:
Code:
/**
 * Loads UIA :)
 * @returns The UIA COM object, or nullptr if it fails
 */
IUIAutomation* LoadUIA() {
    IUIAutomation* uia = nullptr;
    HRESULT startUIA = CoCreateInstance(CLSID_CUIAutomation, nullptr,
        CLSCTX_INPROC_SERVER, IID_IUIAutomation,
        reinterpret_cast<void**>(&uia));
    if (FAILED(startUIA) || uia == nullptr) {
        printf("LoadUIA failed with code %x\r\n", startUIA);
        return nullptr;
    }
    return uia;
}
And in literally every other scenario, for the past year or so, it has worked like a charm. But now, for reasons only God and Bill Gates could ever understand, it just... "evaporates" (to borrow a very apt description from one of the many SO posts I've poured over today). It doesn't hang or freeze or crash or show any error. The HRESULT doesn't contain an error code (well it might if I could see it) and there's nothing from .NOT (no managed error like "Unhandled System.This.That.These.Those.WhoCaresWhichObjectEx ception"). Speaking of .NOT, the interesting part is that after the DLL function falls on its sword, it also prevents further execution of the C# code. The C# code is supposed to play a sound letting the user know the automation is done; this should happen regardless of whether there was an error or not. It doesn't, because STOP!!!! lol...

From there, i decided, the heck with LoadUIA or even fail-checks; let me just try the part that's self-destructing on me and see what the HRESULT says...
Code:
// "interesting" (more like annoying, infuriatng)...
    IUIAutomation* uia = nullptr;
    HRESULT startUIA = CoCreateInstance(CLSID_CUIAutomation, nullptr,
        CLSCTX_INPROC_SERVER, IID_IUIAutomation,
        reinterpret_cast<void**>(&uia));
    printf("startUIA = %x\r\n", startUIA);        // It never prints this.
I tried using NULL instead of nullptr (I'm a die hard C guy myself, not at all a fan of C++, so idk what the subtle differences are between NULL and nullptr, but whatever). Same result.

I tried some other values instead of CLSCTX_INPROC_SERVER (I will admit, I know very little about this enum or whatever funky client/server thing COM/UIA uses under the hood). Same result.

I tried rebooting. I tried deleting the ".vs" folder (cuz at one point Visual Studio was flagging text in comments as having syntax errors, but that's just typical VS garbage - VS is just junk sometimes). And of course I've also tried "GetLastError" (always zero) and perror (always "No error"), and of course I've been over the docs for CoCreateInstance; again, there's nothing there that would explain this. Of course I called CoInitialize before it and made sure that call didn't fail (so it's not like I forgot to load COM first)............................................ .................................................. .....

This bug defies all human reason or understanding. It laughs at logic, spits at sense, and screams "kiss my bits, puny human!" at anyone who dares to try and fix it Why would a block of code that works perfectly in LITERALLY EVERY OTHER SITUATION - other DLL functions in this project, other projects, etc. - do something so bizarre? Is there some kind of undocumented limit of how many functions a DLL can have, or how many functions of a DLL are allowed to use COM, or some... oh dad burn it I don't know!

Has anyone here ever dealt with COM dot bomb randomness like this?

PS: Sorry it's all one giant CODE tag. This stupid forum keeps yelling at me about "surrounding my code with code tags". I DID! I DID! WHY CAN'T YOU UNDERSTAND THAT! GRRRRRRRRRRR.....
lol sorry, guess the forum hates me as bad as Windows. this is the kinda day that sends me screaming back to my Linux terminal.