So I am creating an outlook plugin using NetOffice.
On the plugin entry point it has something like this:
[GuidAttribute("d7066ab2-ac03-431a-bea5-b70d3efab2a5"), ProgId("OutlookPlugin"), ComVisible(true)]
Now I understand that the ComVisible
bit sets the library as, well, ComVisible. I assume this is so that I can make individual classes ComVisible rather than the whole library via Assembly Information -> Make assembly COM-Visible.
But I don't understand what the GuidAttribute
and ProgId
are used for?
One important feature of COM is that an application can ask for the class object to be created and COM sorts out what executable implements it and loads it for you. This requires a good way to identify the component.
You'd say: "well, not a problem, just give it a name". Problem is, people are not very good at picking good names. There are a wholeheckofalot of guys called "Hans" and I know of at least one other guy that has my exact name. Lives somewhere is the Netherlands, don't know who he is.
That's a problem, unlike people names, component name collisions are deadly. You'll get the completely wrong component loaded and your program will crash. So the COM designers decided that the only good solution is a Globally Unique ID, a number that's guaranteed to be unique throughout the known Universe, and beyond. A GUID.
A COM application uses that number to ask for the object to be created. The underlying api function is CoCreateInstance, the first argument is the CLSID which is the guid that identifies the class.
People are however not very good at remembering very long numbers. So there's a back-up way to identify a component, it is used in scripting languages in particular. The kind of runtime environment where getting that guid value in a reliable way is not so easy. So there's still a name attached to the number. It is the ProgId. You pass it to a helper function that's typically named CreateObject(). It makes one extra step, it uses the CLSIDFromProgID() helper function to map the name to the number, then calls CoCreateInstance. Needless to say, this can and does go wrong sometimes.