I have a two .NET assemblies which are registered as COM+ components and I'm testing them from a regular console application test harness;
Dim objFirst As New MyFirstComponent() 'COM+ initialisation
Dim RC As Boolean = objFirst.GetValue()
The method call is executed successfully. This is the definition of MyFirstComponent;
<ProgId("MyFirstComponent")> _
<Guid("...")> _
<ClassInterface(ClassInterfaceType.None)> _
<Transaction(TransactionOption.Supported)> _
Public Class MyFirstComponent
Inherits ServicedComponent
Implements IMyFirstComponent
Public Function GetValue() As Boolean Implements IMyFirstComponent.GetValue
Dim objSecond As New MySecondComponent() 'COM+ initialisation
Dim RC As Boolean = objSecond.GetValue()
Return RC
End Function
End Class
At the point where MySecondComponent is initialised, I get a RemotingException with the following message;
Cannot l开发者_StackOverflowoad type 'MySecondComponent', ..., Version=..., Culture=neutral, PublicKeyToken=...'
All assemblies are strongly named too. I cannot work out why I can successfully fire a method call to the first component, but when it tries to subsequently load up the second component itself, it can't resolve the type.
As a sidenote, if I run the code from the body of "GetValue()" in my test harness, it executes as expected. The problem seems to only crop up once things have moved into the realm of COM+ components calling other COM+ components.
Update
I think I am narrowing in on the problem now. It appears that COM+ was persisting something in process, and I had to manually shut down the COM+ applications from the Component Services window before running my client against it. The problem before was that I was testing the client every time I changed something (like adding the assembly to the GAC), and for some reason COM+ still believed that the assembly could not be found. Shutting the app down, adding the required assemblies to the GAC and running the client again worked as expected.
This was fine for my small proof of concept client. So I went back to my real code and tried it out, but now I am getting another strange issue. My COM+ applications seem unable to locate their normal project references now. I don't really want to go down the road of adding EVERYTHING that they reference to the GAC, so I'm now trying to work out why my normal, non-COM+ references aren't being resolved.
I have finally found a solution to the problem described above. I'm answering the question myself here to save anyone else the pain that I went through trying to get this to work.
Go to Component Services > COM+ Applications > YourComApplication
Bring up the properties window for YourComApplication and go to the Activation tab.
Under "Application Root Directory", supply the path in which your DLLs reside.
Create an "application.manifest" file for your COM+ application and put it in the same directory as above. A sample file looks like this;
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> </assembly>
- This final step is what I had missed before and this solution will not work without it.
Also, make sure that you have a separate directory for each of your COM+ applications. This approach will allow you to have mulitple COM+ applications based on .NET assemblies calling each other without anything having to be in the GAC.
Have you looked into using regasm to register the assemblies for access with COM. I am not sure but it may have to do with the /codebase parameter being passed when you register the assembly. It is worth a shot. Hope this helps.
Although you obviously resolved the issue with the steps included in the answer, this problem can also occur if you have a version of PowerShell that is not compatible with the assembly you are trying to load.
For example, you may have an assembly targeting .NET framework 4.5.1, but the PowerShell version you are running is version 2.0. If you upgrade the version to 4.0 or 5.0, you should have no issue.
精彩评论