Web Connection
COM mode cannot load class
Gravatar is a globally recognized avatar based on your email address. COM mode cannot load class
  Zach Lankton
  All
  Feb 28, 2023 @ 12:57pm

I'm having a strange issue. First a little background. I've been tasked to upgrade the operating system that a web connection application runs on from Win2012 to at least Win2016.

However, to prove that I could take a copy of the application and run it I'm starting with a fresh copy of Win2012 to minimize the variables.

This application is currently running just fine on a production server, but I'm having some trouble getting it to work by completely installing everything on a fresh box.

I've got the site mostly working except for an issue that seems strange to me.

Everything works great in file mode.

Almost everything works in COM mode, but one thing (that I've found so far)

It's an older code base that is using the WebControlFramework but using WebConnection 6.21

So what happens is when a specific page loads that calls a CREATEOBJECT('whatever.whatever') it fails with a message saying the "OLE error code 0x80040154: Class not registered".

However, I can run the exact same CREATEOBJECT('whatever.whatever') from the VFP command window and it works.

I can also perform the same test from PowerShell and it works.

And as mentioned above, this line of code seems to run just fine in File Mode.

I've poured over ApplicationIdentity Docs (and it is set to the same user that I'm running the manual commands from, can't use LocalService as it doesn't have access to a local domain service that I require)

Also tried DCOM configuration and added all kinds of extra permissions. I've really tried to make sure I've gone through everything, hoping you can nudge me in the right direction.

Thanks in advance!

Gravatar is a globally recognized avatar based on your email address. re: COM mode cannot load class
  Rick Strahl
  Zach Lankton
  Feb 28, 2023 @ 01:15pm

Yes, the most likely culprit is an errant path in your application that's loading from a different Web site or virtual on that Web site. If it works fine for most requests but not that one you should look carefully at the URL and see if it's not pointing at a different path that is treated differently.

ApplicationPoolIdentity is very difficult to make work under COM - I would not recommend that. Use a custom account and set the specific permissions you need on that and add that account to the machine DCOM permissions (so you don't have to reset them every time you update the COM server).

The main thing though is that if it works for most but not all requests is to pin down what's different about that one request rather than focusing on the error.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: COM mode cannot load class
  Zach Lankton
  Rick Strahl
  Feb 28, 2023 @ 01:31pm

Thanks for the quick reply Rick!

So to clarify a couple points, I am logged in as a domain user (ourdomain\zach) and I have set the Application Pool "Identity" to use this user as well (not the ApplciationPoolIdentity)

Also the URL works for the initial GET request, but upon POSTING (Submitting the form - same url) it runs a different function that makes the CREATEOBJECT call that returns the Class Not Registered Error.

Currently this works in file mode, not in COM mode, that is the only difference identified so far.

Is it possible the request (from the browser) is different in file mode than it is in COM mode?

Gravatar is a globally recognized avatar based on your email address. re: COM mode cannot load class
  Rick Strahl
  Zach Lankton
  Feb 28, 2023 @ 01:50pm

I thought you said most requests work fine, just one of them doesn't. If that's the case security is working as expected and you have a problem with the particular URL - most likely because a different security environment is applied somehow.

If COM does not work at all then you likely are missing the DCOM permissions. Make sure you use the 32 bit DCOM configuration and as I mentioned it's best to set up security at the machine level for the Application Pool's Identity rather than for the specific ProgId.

When in doubt - start with the LocalSystem and have some dummy requests that you can check (if LocalSystem doesn't work because you have network requirements). LocalSystem doesn't require DCOM permissions and neither does a local Administrator account.

I would also be wary of using a domain account for your IIS Application Identity account. Use a local account on the IIS box. That account has no other purpose than running your application. Start with an Admin account, make sure it works, then dial back. Actually start with System first (as mentinoed), just to make sure the server loads and it's not some other issue then go to Admin account and then dial back.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: COM mode cannot load class
  Zach Lankton
  Rick Strahl
  Feb 28, 2023 @ 01:56pm

You are correct, I've currently identified only ONE request that fails. All others work.

The COM object is also working and serving requests.

What fails is the specific request only when in COM object message mode.

When I run the server in File Mode this request works perfectly.

Gravatar is a globally recognized avatar based on your email address. re: COM mode cannot load class
  Zach Lankton
  Zach Lankton
  Feb 28, 2023 @ 08:53pm

I figured it out... I had all my permissions, paths, identities and everything set correctly. But apparently any subsequent com objects that are called from within the Application COM object server need to be in the bin folder.

Here is my setup:

Client Request --> IIS --> WebConnection --> COM Object Server --> Calls CREATEOBJECT('another.comserver')

When I originally posted this I had registered my Application COM Object Server in the bin folder where it was expected to be.

But 'another.comserver' was registered in a separate directory as part of a separate project.


The thing that fixed it was moving the EXE for 'another.comserver' into the bin folder of my web application and re-register in that location.

Again, To be totally clear, this is ONLY when trying to use COM object mode.

In File mode, 'another.comserver' worked just fine being registered in its own project.


Can you enlighten me as to why this condition exists? Or is there some detail I'm missing?

Gravatar is a globally recognized avatar based on your email address. re: COM mode cannot load class
  Rick Strahl
  Zach Lankton
  Mar 1, 2023 @ 11:25am

No, I have no idea why that would be a problem. The location of a server does not matter since COM object write the location into the registry which is then used to launch the server by COM. Only thing that could change is permissions.

I suspect perhaps you have a conflict in your COM configurations. Multiple EXE servers with the same COM id perhaps? One lookup goes to one, another goes to another where the file doesn't exist. I would do a search in the registry for your COM ProgId and ClassID and see if you have multiples pointing at different locations.

My guess: You copied an existing project with the same ClassIds into a new project. Now both projects have the same ClassIds but different progIds (or not). That will cause problems...

It may have just been the re-registration that has fixed it. Last one wins...

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: COM mode cannot load class
  Zach Lankton
  Rick Strahl
  Mar 1, 2023 @ 12:29pm

The plot thickens... turns out whoever set this project up largely ignored any advice you had in the documentation around setting up COM objects and I assumed that they had followed it.

I was using the same Application Pool Identity user that was used in production (domain\webuser). Turns out this user has access to the database, but not the network folder where the EXE was originally registered.

In production, they had registered this EXE in a local drive that domain\webuser did have access to.

So, looks like they had the same problem I had and solved it by moving the EXE to the local machine.


To add insult to injury, there was another project being served on the same IIS server that was using LocalSystem in the ApplicationPool.

I setup my dev environment using LocalSystem and surprised to find that this project was not working.

A few hours of onion peeling later... LocalSystem of course does not have access to the database, so I changed it to webuser.

Well, webuser again, does not have access to the network folders that contain other project dependencies.

Round and round I went, then got it in my head to check the Identity in the DCOM configuration...

M!@#$ Fu!@#$!@#$

They changed the DCOM launching user in production to user domain\webuser and the application pool to use LocalSystem.

Insert Face Palm emoji here.

LocalSystem had access to all the network folders that the project depended on and webuser had access to the database.

😅

Gravatar is a globally recognized avatar based on your email address. re: COM mode cannot load class
  Rick Strahl
  Zach Lankton
  Mar 1, 2023 @ 09:10pm

Most of that makes sense. However what doesn't is: Why would it work for some request and not that one request.

You definitely need execute permissions for the Application Pool Identity user at minimum, and have the user registered with DCOM (if not a local Admin account).

COM Servers should never sit on a network drive - there will be other Windows permissions issues that come into play that you really will not want to do deal with. Register the server locally even if you have multiple servers in a server farm and use a local account if at all possible. If you must use a domain account make sure it has access in the Web and Deploy and Temp folders, plus the machine DCOM permissions.

It's a lot of crap you have to deal with unfortunately, but such is the nature of 32 bit COM that FoxPro needs to run in an automated fashion. If you stick with the advice though it's a lot easier:

  • Use a local account
  • Add to Machine DCOM
  • Start with an Admin account (or SYSTEM) to make sure it all works
  • Then remove rights

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: COM mode cannot load class
  Zach Lankton
  Rick Strahl
  Mar 2, 2023 @ 07:19am

Thanks a lot Rick!

The one request that was failing was the one that was using the CREATEOBJECT call to the COM object that was located on the network drive.

All the other requests were not making that specific call to CREATEOBJECT.


RE: the good advice...

You are absolutely right, I have not had a problem when following all the advice as its laid out in your documentation.

The latest project is all legacy code that I'm about to inherit and I've been going through it to make sense of it all.

This codebase was developed by a single developer (largely in isolation) over the last 20 years. They are retiring and moving on. I don't like to talk crap about developers of old legacy code as they were most likely using the best information they had at the time, (and alas someday, some young punk will be talking crap about all the code I've written over the last 20 years, so full circle inevitable, trying to keep it in mind)

That all being said, almost every good piece of advice that I've come across in your documentation was either not available to this developer at the time of development or completely ignored.

I really appreciate you taking the time to add to and clarify this advice in your responses. I will absolutely be using it to my benefit in the near future.

Thanks again!

© 1996-2024