2

TL;DR: Why would a COM+ Component by successfully activated from .NET but fail to load from ASP?

My scenario:

  • I've created a COM+ object using C#/.NET (Framework 4.0).

  • I'm deploying it to the server using a Visual Studio Installer project, which both install the DLL to GAC and also register it to COM.

  • Browsing C:\Windows\Microsoft.NET\assembly\GAC_MSIL, I can successfully find the DLL I've registered.

  • Looking at the Component Services add-in I can create an application and add the component that I've registered. Note that the names are different (between the DLL/namespace and the ProgId) which does give me confidence that both things occurred correctly.

However, I'm trying to create a new instance of this COM from ASP Classic. This means that there's a single line calling CreateObject("PROGID") in the program., which is throwing.

I've already done the following:

  • I've created a VBS file with a single line, CreateObject("PROGID"), and called it. It also fails, so the issue isn't restricted to ASP.
  • I've used Powershell 2.0 (the only one available on the machine) and called New-Object -ComObject "PROGID", and it also fails.
  • I've copied LinqPad to the machine and used Type.GetTypeFromProgID together with Activator.CreateInstance. I had success calling the instance.

The error, which seems pretty common, is 80070002. This is supposed to indicate that COM couldn't find the assembly file. Upon checking the registry, I can see that the Assembly name (the FQ Assembly Name) of the COM record does corresponds to the Assembly that I've installed. The runtime is the new CLR (v4.0.30319) and the class name is also correct.

I'm completely baffled by the fact that .NET can instantiate the COM object without any issues whereas VB6/ASP is aborting.

To make matters worse, the DLL was sucessfully deployed last week and I'm just installing a new version, so I should be having any troubles.

Is there any difference how COM's are loaded between ASP and .NET that can lead to such a scenario? What I'm thinking:

  • Any kind of permissions that must be set and haven't.
  • A dependency from any .NET DLL that, running from .NET, is found but running from VBS isn't.
  • The core runtime version may be to great for ASP/VBS.

The last item should be true since I've done this successfully just last week and I didn't changed anything about the runtime.

Bruno Brant
  • 8,226
  • 7
  • 45
  • 90
  • 1
    Possibly related to [How do I properly instantiate 32-bit COM objects in classic ASP after installing Windows Update KB4340558?](https://stackoverflow.com/q/51289285/692942) – user692942 Jul 23 '18 at 23:39
  • The Classic ASP issue is permission related, they've tightened up how an App Pool can interact with COM. So the VBScript / Powershell tests likely failed because they weren't run in an elevated process *(UAC strikes again)*. – user692942 Jul 23 '18 at 23:42
  • 2
    What about the bitness: 32bit vs 64bit? – Simon Mourier Jul 24 '18 at 05:36
  • @SimonMourier I need to double check but I guess the app is 32 bits. I'm compiling the .NET Component to MSIL. – Bruno Brant Jul 24 '18 at 13:23
  • What happens if you run your VB script by using c:\windows\SysWOW64\cscript.exe ? Does it work then? If it works, it would indicate you have registered your object with the 32-bit hive. Normal running of a vbscript file is done with the 64-bit engine. Is your ASP engine 64-bit or 32-bit? – Joseph Willcoxson Jul 24 '18 at 13:56
  • If the app is 32 and you compile for any CPU, and you run on a 64-bit machine, it won't work (it should work on a 32-bit machine) – Simon Mourier Jul 24 '18 at 16:12

1 Answers1

0

It seems this was much less of an elusive problem as it seems. I will still document it here as some people might run into this question on the exact same situation, although that's unlikely.

The reason why ASP, VBScript and PowerShell weren't seeing the changes I applied and for some reason not finding the component (80070002) was that either an IIS reset or a complete shutdown/restart cycle of the server was necessary.


What led me to this scenario was both the fact that the server admin forgot to perform the reset - something I didn't consider - and the fact that .NET was able to obtain the COM instance.

I do not know the details that would explain why this is so - maybe .NET hadn't shadowed the assembly yet and whatever runs COM (yeah, I have no idea, sorry) did had. Certainly, something to that effect was going on.

A clean reboot of the server completely solved the issue.

A final point - just shutting down the application on Component Services wasn't enough.

Bruno Brant
  • 8,226
  • 7
  • 45
  • 90