Hi
I registered my COM component using:
c:\windows\syswow64\regsvr32.exe dcfusionamp.dll
and everything succeeded. However when I try use it I always get a COM error. So I tried the following Powershell command to check my COM server
$server = new-object -comObject 'dcfusionamp.dcfusionamp'
I got the following error message:
new-object : Retrieving the COM class factory for component with CLSID {7E9CB621-86D9-44B6-8C5D-1B7BF8D8813F} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)). At line:1 char:12
- $server = new-object -comObject 'dcfusionamp.dcfusionamp'
- CategoryInfo : ResourceUnavailable: (:) [New-Object], COMException
- FullyQualifiedErrorId : NoCOMClassIdentified,Microsoft.PowerShell.Commands.NewObjectCommand
This component is running on a number of Windows 2012 & 2016 servers but this is the first Windows 2019 server I have tried. Does anyone have any ideas about the cause and how to fix it?
Thanks, Simon
Are you sure registration works? regsvr32.exe
requires Administrator rights in order to work... Make sure you get the dialog that says it works.
Also not all COM objects are IDispatch
objects that are callable from FoxPro or Powershell. If they are only exposing IUnknown
then it's not COM callable.
If that's not it (and it works on other machines) check the registry after registration to see if the COM object is actually getting in there. You can search for the ProgId and from there get the ClassId and make sure it's pointing to the right location.
If it's a FoxPro COM object there might a few other things that need to happen - Fox runtime needs to be installed for example.
+++ Rick ---
This is a VFP COM object and I ran the registration in Power Shell (Administrator Mode) and it reported that the registration was successful.
The CLSID and ProgID all seem to be correct in the registry. However I cannot find my COM Object when I use DCOMConfig (I used the 32bit mode).
VFP run times are installed because I have a number of VFP applications running on the server.
Simon
If it's a DLL it won't be DCOMCnfg - that only applies to EXE Out of Process COM servers...
If VFP is installed on the machine try launching the COM object with CREATEOBJECTEX()
in FoxPro and see what you get.
It sounds to me there's a permissions problem with the COM server not actually getting properly registered in the Registry or some sort of system policy that is blocking invocation of COM objects for certain accounts (not sure what that would be to be honest).
+++ Rick ---
When I use the CreateObjectEX() I get the following error
OLE error code 0x80004005: Unspecified error.
Simon
I'm going to guess you have a problem with your server's Init()
processing that fails to load it.
Simplify your server so that Init()
has no code in it and perform initialization in a separate step. If an error occurs in Init()
you can't trap the error because the server is not actually running yet so the error is completely generic and tells you that the object is invalid. So offloading intialization to a separate method that is not called off off Init()
is a better way to go.
Something like this:
loInst = CREATEOBJECTEX("MyApp.MyAppServer")
loInst.Initialize() && code that was in Init() goes into Initialize()
Now when you load any failures will cause a proper COM error and not a com instantiation issue.
If that's not the problem you can try put a TRY/CATCH
into the Init()
or any other code that runs during COM Server instantiation and write out an error log file into a temp folder (make sure the user has access whereever you write to).
+++ Rick ---
Hi Rick
Thanks for the suggestion about checking my Init(). I have been using this component for years without issues so I never thought about the fact that something in the Init might be the cause of the problem. So I added a Try/Catch to the Init and found the issue. It was a Postgres connection password.
Thanks, Simon
Ah - the old "I've been using this for 20 years and it has always worked!" 😃
Been there done that, but always double check.
I advise against doing things like opening a connection in the constructor in COM objects because it's so hard to debug this. There's just nothing you can do in the Init()
(other than logging) to tell the caller what's happening because all you can do is throw or return null, which will then fails with a generic COM error that usually points at something seemingly unrelated.
The problem is that COM objects do behave differently depending on the security environment of the host application and so there are a LOT of variables that can break COM instantiation and unfortunately the COM system isn't very good about reporting startup errors in a meaningful way.
+++ Rick ---