# Psychic debugging: Because of course when something doesn’t work, it’s because the program was sabotaged from above

When something stops working, you begin developing theories for why it doesn’t work, and normally, you start with simple theories that involve things close to you, and only after you exhaust those possibilities do you expand your scope. Typically, you don’t consider that there is a global conspiracy against you, or at least that’s not usually your first theory.

I’m trying to use the XYZ.DLL that comes with your product. I have successfully registered this DLL (as specified in the documentation) by performing a regsvr32 C:\path\to\XYZ.DLL.

According to the documentation, I should now be able to create a Xyz.Xyz­Widgetizer object, but when I try to do so from C#, I get the exception

Retrieving the COM class factory for component with CLSID
{...} failed due to the following error: 80040154.


I tried using the Visual Basic code sample which comes with the documentation, which contains only two lines:

Dim oXyzWidgetizer
Set oXyzWidgetizer = WScript.CreateObject("Xyz.XyzWidgetizer")


However, it still fails with the following error:

Microsoft (R) Windows Script Host Version 5.7
C:\test.vbs(2, 1) WScript.CreateObject: Could not create object
named "Xyz.XyzWidgetizer".


Has support for the XyzWidgetizer been silently dropped?

Let’s look at the error message more closely. Error 80040154 is REGDB_E_CLASSNOTREG: The class is not registered. Therefore, whatever regsvr32 did, it didn’t register the class.

My psychic powers tell me that you registered the 32-bit version of XYZ.DLL on a 64-bit machine.

Registering the 32-bit DLL records the entries into the 32-bit registry (because 32-bit programs run in an emulator), and the 32-bit registry is not consulted when you try to create a COM object from a 64-bit application. Letting 64-bit applications see the registration for 32-bit DLLs doesn’t actually accomplish anything because you cannot load a 32-bit DLL into a 64-bit process and vice versa—even if a 64-bit process can figure out what DLL it wants, it won’t able to load it.

It so happens that my psychic powers were correct. How did I know that the person asking the question was running the 32-bit version of XYZ on a 64-bit version of Windows? I didn’t, but it was the simplest theory that fit the (extremely limited) data. And it didn’t involve a global conspiracy.

Tags

1. prunoki says:

Sure. It is like starting with "is the monitor plugged in?".

How do you look up what error 80040154 means?  In this case it's easy to google, but that doesn't work for more obscure errors that aren't well-documented.  "net helpmsg <error#>" only seems to work for system error codes, not for HRESULTs.

3. parkrrrr says:

Possibly not relevant here, but given all the bad side-effects of the inability to load a DLL of the wrong bitness, I've often wondered why there isn't some sort of setting that would allow a nominally inproc COM server to be loaded in a surrogate process of the appropriate bitness when it can't be loaded inproc. Or maybe there is such a setting and I just don't know about it?

[Oh, you mean using a surrogate process like Explorer does sometimes? This assumes that the DLL meets the requirements for being moved out-of-process. (For one thing, it introduces re-entrancy.) -Raymond]
4. udas says:

It is so true that folks do not look for simpler explanations before getting more creative. My favorite examples : "Memory Corruption", "the API does not work as expected", "bug in Windows/Compiler/…"

5. Kyle says:

This should have the information you're looking for…

http://lmgtfy.com/?q=80040154

6. lixiong says:

haha

similar problem applies to regasm.exe and sn.exe.

7. Wayne says:

@Adam Use ERR.exe tool found here http://www.microsoft.com/…/details.aspx

I know it says Exchange but it has the header files for WinError.h among many others and will translate the error for you

err 0x80040154

# for hex 0x80040154 / decimal -2147221164 :

DIERR_DEVICENOTREG                                            dinput.h

STIERR_DEVICENOTREG                                           stierr.h

REGDB_E_CLASSNOTREG                                           winerror.h

# 3 matches found for "0x80040154"

8. Ooh says:

@Adam Rosenfield: Have a look at the Windows Error Lookup Tool [1]. "err.exe 0x80040154" prints

# for hex 0x80040154 / decimal -2147221164 :

DIERR_DEVICENOTREG                                            dinput.h

STIERR_DEVICENOTREG                                           stierr.h

REGDB_E_CLASSNOTREG                                           winerror.h

# 3 matches found for "0x80040154"

The problem has obviously nothing to do with DirectX or the user mode still image APIs, so it's most likely REGDB_E_CLASSNOTREG. (You could also argue that one doesn't need to know about the concrete APIs since each listed error code implies that something isn't registered.)

@Kyle: You obviously failed to read the first clause of the second sentence of my post.

10. Craig Matthews says:

Mr. Rosenfield is correct. Yes, this error is easy to Google, but more often that not, you end up finding a bunch of posts asking what the error means, with a bunch of people replying to the post who haven't read the post to begin with, with the thread finally ending with an MVP saying "I don't know, I'm just an MVP, I don't work for Microsoft."

11. jim says:

"I'm always baffled by the people who immediately assume that everything they don't like is some sort of conspiracy. -Raymond"

You're on to us. It's actually a global conspiracy to baffle you Raymond.

12. Joshua says:

One of our steps for 64 bit migration was remove all COM components.

We still COM-interop to office but otherwise no 64 bit COM.

One VB6 COM component still survives. The EXE that uses it is compiled 32 bit.

13. Leo Davidson says:

If you have Visual Studio then you already have an Error Lookup tool in the Tools menu (by default). Type 0x80040154 in and it'll tell you the error is "class not registered". (Don't forget the 0x part.)

I also wrote my own little error-lookup tool which can do the reverse lookup, i.e. find error codes based on some or all of their error messages. (It can also do number->message lookups. It saves you having to know/care whether the error code is hex/signed/unsigned but apart from that is no better than the other tools; that wasn't why I wrote it.) I wrote it to make it easier to find a suitable error code values to return when writing code. e.g. Type 'access' and 'denied' into it and it'll show you all the error codes that have those words in their messages. It only knows about the errors from the main SDK headers but the source is there if anyone wants to add more:

http://www.pretentiousname.com/…/index.html

14. Joshua says:

Haha, Leo Davidson favors the engineer's solution to corporate policies.

15. mxm says:

> It is so true that folks do not look for simpler explanations before getting more creative. My favorite examples : "Memory Corruption", "the API does not work as expected", "bug in Windows/Compiler/…"

The Garbage collector does not work. It's the top .net favorite.

16. James Schend says:

Slashdot had a rather wonderfully Slashdot-y post where the writer assumed that because he couldn't get his (cracked) copy of Photoshop to run in Windows 7, obviously Microsoft and Adobe must be in cahoots and installed some code to reject pirated applications! Link: tech.slashdot.org/…/Draconian-DRM-Revealed-In-Windows-7

Raymond feel free to remove this post if you think I'm singling out a person or product.

17. jmthomas says:

I assume you see problems from the field which may require changes to Microsoft code, as well as programming errors.

What's the ratio of ("true bug") code change problems to problems solvable by consulting an experienced programmer or even just RTFM?

I'm wondering about setting up an "agent" or "screening" business, where It's statically cheaper to have me look over problems, forwarding to Microsoft only the problems that can't be handled by user education, good debugging techniques, and/or psychic debugging…

18. Kyle says:

In my excitement to use LMGTFY, I neglected to read your entire post and instead posted some snark.  My apologies.  :)

19. Gabe says:

My favorite global conspiracy theory is "This security hole is so unusually difficult to trigger that MS must have intentionally put it in as a backdoor". As if it's so unusual that bugs are difficult to trigger — of course *most* bugs are difficult to trigger, which is why they weren't found before the product was released!

20. Ken Hagan says:

"Has support for the XyzWidgetizer been silently dropped?"

You know, he wasn't far off the mark there. There *is* no support for the XyzWidgetizer on his new platform and XyzWidgetizer users weren't specifically warned of the change. :)

21. Neil says:

Presumably the vbscript code sample would have worked if he'd used C:WINDOWSSysWOW64cscript.exe to launch it. (I was surprised to find that the 32-bit version lives in a folder with a 64 suffix…)

22. Napoleon I (1769 - 1821) says:

Never ascribe to malice that which is adequately explained by incompetence.

23. Gechurch says:

@Napoleon

That's one of my favourite quotes. It was the first thing I thought when reading this posts title!

24. 640k says:

16 to 32 bit migration was easy.

32 to 64 bit migration will be part of our lives for the next decade.

25. Rup says: