Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

All COM classes -- Also known as CoClass(es) -- and interfaces are identified by their GUID (also known as CLSID and IID respectively). CoClasses have also a ProgID which is kind of a friendly name.

All of these are stored in the Registry when the COM component or COM-Visible assembly are registered (respectively with RegSvr32.exe or RegAsm.exe), and reference each other.

For ProgId, I think the documentation is quite clear on its usage:

ProgIDs are automatically generated for a class by combining the namespace with the type name. This can produce an invalid ProgID however, as ProgIDs are limited to 39 characters and can contain no punctuation other than a period. In such case, a ProgID can be manually assigned to the class using ProgIdAttribute.

The reason not listed here is that manually assigning it makes it consistent across builds.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top