|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
EventHandler for late-bound COM objectI'm trying to handle an event from a late-bound COM object.
Here is my code so far: Dim t As Type = o.GetType() Dim eInfo As EventInfo = t.GetEvent(EventName) Dim d As New MyDelegate(AddressOf MyHandler) eInfo.AddEventHandler(o, d) However this fails as GetEvent is returning Nothing. The problem appears to be that GetType is returning a __ComObject rather than the underlying COM object itself, so it can't find the event. Is there a way of getting the events for the COM object? Or is there a better way to do this? TIA Phil Hello Phil,
From your post, my understanding on this issue is: you wonder why your COM object does not expose its events in late binding and how to resolve it. If I'm off base, please feel free to let me know. According to your sample code, I think you are using VB.*NET*. In order to get all the events of a COM object with .net Reflection, we could call GetEvents() method on a System.Type object. In this post, it seems that GetEvents() returns an empty array. As you said, it is because the object type is System.__ComObject, and it does not expose any real type information. .NET Reflection generally only understands managed metadata, not COM's ITypeInfo. In order to let it discover the COM events, we need a managed description of the COM types in an interop assembly, which is called RCW. I did the following test to reproduce your issue: As we know, we need Office Primary Interop Assembly (PIA) to automate Office in .NET. If the PIA has already been installed, the line CreateObject("Word.Application") will return an object of type: Word.Application, and the call of Type.GetEvents() will return all the public events of the word application object. But if we uninstall the Office PIA and try the CreateObject again, it only returns a System.__ComObject object and no event is returned in GetEvents() call. To resolve the problem: 1. If the COM component is a self-designed one, we could manually create a .net interop assembly by running tlbimp command on it. Then add the reference to the primary dll in your project. For more information about how to create a .net interop assembly, please refer to the MSDN article http://msdn2.microsoft.com/en-US/library/tw4zwhbe.aspx 2. If the COM component belongs to a product, like the COM component of Office, we could search for their .NET PIA from product owner and install the PIA in your computer. 3. If the COM component has no way to be retrieved, you may consider hook up the events via IConnectionPoint interfaces. The KB article http://support.microsoft.com/kb/811645/en-us gives an example. For more information about COM events in .NET, please refer to http://msdn2.microsoft.com/en-us/library/1hee64c7(VS.71).aspx Please let me know if you have any other concerns, or need anything else. Sincerely, Jialiang Ge (jia***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== For MSDN subscribers whose posts are left unanswered, please check this document: http://blogs.msdn.com/msdnts/pages/postingAlias.aspx Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. If you are using Outlook Express/Windows Mail, please make sure you clear the check box "Tools/Options/Read: Get 300 headers at a time" to see your reply promptly. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. > That's basically it, yes.> From your post, my understanding on this issue is: you wonder why your COM > object does not expose its events in late binding and how to resolve it. > If > I'm off base, please feel free to let me know. > Correct. That's why I posted the question in the VB.NET ng :-)> According to your sample code, I think you are using VB.*NET*. I've just upgraded from VB 2005 Express to the Professional Edition. My previous experience is mostly with VB6 though, so I am unfamiliar with many of the new concepts in .NET. > In order to Actually it returns 'Nothing' rather than an empty array, but you're right, > get all the events of a COM object with .net Reflection, we could call > GetEvents() method on a System.Type object. In this post, it seems that > GetEvents() returns an empty array. I don't see the events that I had hoped to see.. > As you said, it is because the object OK. I guess I need to read up on Interop assemblies.> type is System.__ComObject, and it does not expose any real type > information. .NET Reflection generally only understands managed metadata, > not COM's ITypeInfo. In order to let it discover the COM events, we need a > managed description of the COM types in an interop assembly, which is > called RCW. I did the following test to reproduce your issue: > Actually I didn't know that.> As we know, we need Office Primary Interop Assembly (PIA) to automate > Office in .NET. > If the PIA has already been installed, the line In this particular case I am automating Excel rather than Word, but it's > CreateObject("Word.Application") will return an object of type: > Word.Application, and the call of Type.GetEvents() will return all the > public events of the word application object. But if we uninstall the > Office PIA and try the CreateObject again, it only returns a > System.__ComObject object and no event is returned in GetEvents() call. essentially the same thing. I did originally add a reference to Excel to my project, but I don't want my application to be reliant on Office being installed on the target system, so I chose to use late-binding. I can use CreateObject to start an Excel Application instance, and can call methods and properties, no problem. I don't think I need the PIA to do this do I? I have had it running on several different machines, without installing this PIA. I suppose it's possible, that it's already installed? How can I check this? It seems odd that I can access all the properties and methods, but not the events. > At the moment, I am just using Excel objects, but I'll perhaps take a look > To resolve the problem: > > 1. If the COM component is a self-designed one, we could manually create a > .net interop assembly by running tlbimp command on it. Then add the > reference to the primary dll in your project. > For more information about how to create a .net interop assembly, please > refer to the MSDN article > http://msdn2.microsoft.com/en-US/library/tw4zwhbe.aspx at this for future reference. I want to avoid adding a reference to my project though, because I need it to run even if the COM component is not installed (albeit with reduced functionality). > 2. If the COM component belongs to a product, like the COM component of It sounds like this might be what I need. Will I be able to reference the > Office, we could search for their .NET PIA from product owner and install > the PIA in your computer. Office PIA, and still have my application deploy OK on a system that does not have Office installed? What I do at the moment is disable those parts of my application that rely on Excel if CreateObject fails to return a valid reference. I can do this at runtime, but I'm concerned that if I explicitly reference the COM object or the Interop Assembly that my application may not run at all, when Office is unavailable. > 3. If the COM component has no way to be retrieved, you may consider hook Thanks, I'll perhaps take a look at this and see if this might do the trick.> up the events via IConnectionPoint interfaces. The KB article > http://support.microsoft.com/kb/811645/en-us gives an example. For more > information about COM events in .NET, please refer to > http://msdn2.microsoft.com/en-us/library/1hee64c7(VS.71).aspx > Thanks for your response, it is most appreciated.> Please let me know if you have any other concerns, or need anything else. Cheers, Phil. Hello Phil,
According to your reply, now I know that you are actually using late binding, and trying to add event handlers for Excel.Application object. Below, I will first provide two new workarounds for COM events in late binding because the first two I provided in the last reply may not fit your situation, then I will answer several additional questions you posted in the last response. The call of COM events in .NET are indeed different from the call of COM methods/properties. We are able to access the COM methods/properties without the reference of interop assemblies, but COM events cannot be retrieved directly because .NET always requires a clearly defined event source interface. For this specific problem, I find two workarounds for your reference: 1. Since we decide to do late binding and cannot refer to the generated COM-Interop wrapper (Office PIA), we need to copy the definition of the interface into our COM client application, to simulate the job of IConnectionPoint. The codeproject article http://www.codeproject.com/csharp/zetalatebindingcomevents.asp shows a complete explanation/example of it. 2. The second workaround is not to use late-binding. But in order to support multiple office versions in target machine, we could reference the type library of the earliest version of the Office application you intended to Automate. For instance, if your application intends to support Office 2000 and above, we could add a reference to Office 2000 PIA. In this way, we are using early binding and the event handlers can be easily added. For more information, please refer to the KB article "Writing Automation clients for multiple Office versions" http://support.microsoft.com/kb/244167/ For your additional questions in the last reply: >Actually it returns 'Nothing' rather than an empty array, but you're What I referred to is the method: 'GetEvents', rather than 'GetEvent'. > right, I don't see the events that I had hoped to see.. 'GetEvents' returns all the events available to the COM object in the form of an array. It returns an empty array if there are no events. >Actually I didn't know that. (About Office PIA) A .NET COM interop assembly is necessary if a .NET class expects to access COM events/methods/properties with early binding. Office Primary Interop Assembly is such a thing that allows .NET clients automates Office COM objects. Office 2003 PIA can be downloaded at http://www.microsoft.com/downloads/details.aspx?familyid=3c9a983a-ac14-4125- 8ba0-d36d67e0f4ad&displaylang=en, Office 2007 PIA can be downloaded at http://www.microsoft.com/downloads/details.aspx?familyid=59DAEBAA-BED4-4282- A28C-B864D8BFA513&displaylang=en, and Office XP at: http://www.microsoft.com/downloads/details.aspx?familyid=C41BD61E-3060-4F71- A6B4-01FEBA508E52&displaylang=en To add the reference to the PIAs in Visual Studio.NET, we should right click the project->Add Reference->Turn to 'COM' tab->Find the object library we need. For instance, for Excel automation, we could add Microsoft Excel (version number) object library. If you have any other question or need anything else, please feel free to let me know. Regards, Jialiang Ge (jia***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================= When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================= This posting is provided "AS IS" with no warranties, and confers no rights. Hi Phil,
Would you mind letting me know the result of the suggestions? If you need further assistance, feel free to let me know. I will be more than happy to be of assistance. Have a great day! Sincerely, Jialiang Ge (jia***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================= When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================= This posting is provided "AS IS" with no warranties, and confers no rights. |
|||||||||||||||||||||||