Reputation: 2204
So I feel like this is very basic, but for whatever reason, I cannot get this to work.
I have a C# class that I want to use in Excel through COM. So when the C# class is registered to the ROT (and my application is running), when I do a GetObject
in Excel, it should find out if there is any running instance of my class, and if so, return that instance for Excel to use. My issue is, I'm getting a 429 error - it cannot find the class :(
I don't want to just post a wall of code (unless it's requested), but I did a regasm /codebase
on my .exe, which contains the COM visible class I want to use in Excel. I also specified my own GUID and ProgID, and the ProgID is what I use in Excel to get my object.
Most of this code was written by someone else and I have to figure out how to fix it, so the following code snippets are things I don't really know what they do but might be additional information that could be useful:
// this gets called before my class (MyApp) is made
RegistrationServices services = new RegistrationServices();
return services.RegisterTypeForComClients(typeof(MyApp), RegistrationClassContext.LocalServer, RegistrationConnectionType.MultipleUse);
// this gets called right after my class (MyApp) is made
if (MyApp == null) return;
Guid guid = typeof(MyApp).GUID;
RegisterActiveObject(MyApp, ref guid, 0, out _RegActiveObjectKey);
and here's just some info about the class, if that's useful:
[Guid("FDDBEB42-9E44-45fb-806B-EA535E2947F2")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("MyExe.MyApp")]
[ComVisible(true)]
public class MyApp : IDisposable
{
// ...
}
EDIT: I even explicitly registered my class in the ROT, using this code:
IRunningObjectTable rot = null;
IMoniker pMoniker = null;
string filename = string.Empty;
int retVal = GetRunningObjectTable(0, out rot);
retVal = CreateFileMoniker(filename, out pMoniker);
retVal = rot.Register(1, _MyApp, pMoniker);
Upvotes: 1
Views: 598
Reputation: 942348
I did a regasm /codebase on my .exe
That does not do what you hope it does. Regasm exclusively registers in-process servers, they normally have a .dll extension. The fact that your file has a .exe extension does not make any difference. The CLR doesn't treat them any different from an assembly with a .dll extension. .NET assemblies have a display name, same as the file name. The filename extension is not part of the assembly's full name and the CLR will first look for an .exe, then for a .dll whenever it is asked to load an assembly.
So you have a chicken-and-egg problem, Excel will not load your assembly until it creates an object of one of the classes that you made [ComVisible]. Necessarily, that object can never be present in the ROT, your assembly never registered one yet.
The ROT is normally only useful to have two separate processes talk to each other. In other words, when you start the EXE yourself. Creating an out-of-process server in .NET is a pretty awkward affair, you have to use COM+ hosting and derive your class from ServicedComponent.
Upvotes: 2