Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / February 2006

Tip: Looking for answers? Try searching our database.

COM+ LC Event - Transient Subscription

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Blair Allen Stark - 18 Feb 2006 10:11 GMT
I am getting "An event was unable to invoke any of the subscribers (Exception
from HRESULT: 0x80040201)" on what appears to have been a properly subscribed
transient event.  

I have an Event Class in a signed library, LceEvent.dll, registered in COM+
via
           regsvcs LceEvent.dll

--------------------------------------------------------------------------------
Imports System.Runtime.InteropServices
Imports System.EnterpriseServices

<ComVisible(True)> _
Public Interface ITheEvent
   Sub Fire()
End Interface

<ComVisible(True), _
   EventClass()> _
Public Class TheEvent
   Inherits ServicedComponent
   Implements ITheEvent
   Public Sub Fire() Implements ITheEvent.Fire

   End Sub
End Class

--------------------------------------------------------------------------------
above class registers appropriately

I have a sink library, LceSink.dll with an Event Sink :

--------------------------------------------------------------------------------
Imports System.EnterpriseServices
Imports System.Runtime.InteropServices
Imports LceEvent

<ComVisible(True)> _
Public Class TheEventSink
   Implements ITheEvent
   Public Event Fired As EventHandler
   Private _subId As String
   Public Sub New()
   End Sub
   Public Sub Fire() Implements LceEvent.ITheEvent.Fire
       RaiseEvent Fired(Me, EventArgs.Empty)
   End Sub
End Class

--------------------------------------------------------------------------------

I have a helper class for transient subscriptions:

--------------------------------------------------------------------------------
Public Class LceHelper
   Public Shared Function CreateTransientSubscription( _
 ByVal clsid As String, ByVal subscriber As Object) As String
       Dim catalog As New COMAdmin.COMAdminCatalog
       Dim catalogCollection As COMAdmin.COMAdminCatalogCollection = _
           catalog.GetCollection("TransientSubscriptions")
       catalogCollection.Populate()
       Dim subscription As COMAdmin.ICatalogObject = catalogCollection.Add()
       subscription.Value("SubscriberInterface") = subscription
       subscription.Value("EventCLSID") = "{" & clsid & "}"
       subscription.Value("Name") = "TransientSubscription"
       catalogCollection.SaveChanges()                  
       ' POINT 1      
       Return subscription.Value("ID").ToString()
   End Function
   Public Shared Sub DeleteTransientSubscription(ByVal subid As String)
       Dim catalog As New COMAdmin.COMAdminCatalog
       Dim catalogCollection As COMAdmin.COMAdminCatalogCollection = _
           catalog.GetCollection("TransientSubscriptions")
       catalogCollection.Populate()
        ' POINT 5
        For i As Integer = 0 To catalogCollection.Count - 1
           Dim subscription As COMAdmin.COMAdminCatalogObject =
catalogCollection.Item( i )
           If subscription.Value("ID").ToString() = subid Then
               catalogCollection.Remove( i )
               Return
           End If
       Next
   End Sub
End Class

--------------------------------------------------------------------------------

I am trying to use in a form:

--------------------------------------------------------------------------------
Public Class Form1

   Private WithEvents _TheSink As LceSink.TheEventSink
   Private _thesub As String

   Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
       Dim t As Type
       t = Type.GetTypeFromProgID("LceEvent.TheEvent")
       _TheSink = New LceSink.TheEventSink()
       Try
           _thesub = LceSink.LceHelper.CreateTransientSubscription( _
                                                     t.GUID.ToString(),
_TheSink)
           ' POINT 2            
       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
       MyBase.OnLoad(e)
   End Sub

   Private Sub Button1_Click(ByVal sender As System.Object, _
                         ByVal e As System.EventArgs) Handles Button1.Click
       Dim evt As LceEvent.ITheEvent = New LceEvent.TheEvent
       Try
           ' POINT 3                
           evt.Fire()                
       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
   End Sub

   Private Sub Form1_Disposed(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Disposed
       ' POINT 4        
       LceSink.LceHelper.DeleteTransientSubscription(_thesub)
   End Sub
End Class

--------------------------------------------------------------------------------

At POINT 1 (LceHelper.CreateTransientSubscription), catalogCollection.Count
has increased by 1

At POINT 2 (Form1 above), it appears the subscription succeeds as the call
to CreateTransientSubscription assigns a giud string to _subID

At POINT 3 (Form1 above), I get  exception An event was unable to invoke any
of the subscribers (Exception from HRESULT: 0x80040201)

At POINT 4 (Form1 above), trace into LceHelper.DeleteTransientSubscription

At POINT 5 (LceHelper.DeleteTransientSubscription )CatalogCollection.Count >
1, the subid is found and the subscription is released

What am i doing wrong? Why isnt the subscription being called?
"Peter Huang" [MSFT] - 20 Feb 2006 09:31 GMT
Hi,

Currently I am researching the issue and we will reply here with more
information as soon as possible.
If you have any more concerns on it, please feel free to post here.

Thanks for your understanding!

Best regards,

Peter Huang
Microsoft Online Partner Support

Signature

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

"Peter Huang" [MSFT] - 21 Feb 2006 10:47 GMT
Hi,

I think you may try to go through the link below, which works at my side.
Generally your code seems to be OK.
You may try to compare with the code in the link.

http://groups.google.com/group/microsoft.public.dotnet.framework.component_s
ervices/browse_frm/thread/3b6846145a4c937f/d5922fb1d4f29ab7?lnk=st&q=EventCL
SID+TransientSubscription+ServicedComponent&rnum=1&hl=en#d5922fb1d4f29ab7

Also You are set the subscription.Value("SubscriberInterface") =
subscription , but I think we need to set to "subscriber"

  Public Shared Function CreateTransientSubscription( _
 ByVal clsid As String, ByVal subscriber As Object) As String
       Dim catalog As New COMAdmin.COMAdminCatalog
       Dim catalogCollection As COMAdmin.COMAdminCatalogCollection = _
           catalog.GetCollection("TransientSubscriptions")
       catalogCollection.Populate()
       Dim subscription As COMAdmin.ICatalogObject =
catalogCollection.Add()
       subscription.Value("SubscriberInterface") = subscription
       subscription.Value("EventCLSID") = "{" & clsid & "}"
       subscription.Value("Name") = "TransientSubscription"
       catalogCollection.SaveChanges()                  
       ' POINT 1      
       Return subscription.Value("ID").ToString()

If you still have any concern, please feel free to post here.
Also for ServicedComponent issue it would better post in the dedicated
newsgroup.
microsoft.public.dotnet.framework.component_services

Best regards,

Peter Huang
Microsoft Online Partner Support

Signature

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Blair Allen Stark - 21 Feb 2006 13:44 GMT
thanks peter. . . when I get to work I will try the code on that newsgroup
post.
It appears he is using late-binding. . . would there be any difference in
interoping the COMAdmin library?

as far as
subscription.Value("Subscriber") = subscription

that throws "not in valid range" exception.

if you have a chance, heres a link to my solution . . .

http://www.obj-tec.com/msdnforums/lcedemo2.zip

just be sure to register LceEvent.dll via:

    regsvcs /u LceEvent.dll

oh, microsoft.public.dotnet.framework.component_services does not list in
the menu of available newsgroups. I fudged my URL to get there (don't want to
subscribe to google)
"Peter Huang" [MSFT] - 22 Feb 2006 02:09 GMT
Hi

Commonly the latebinding should worked as expeced with early binding.
But if we use the COMAdmin in .NET, there will be Interop Layer which is
produced by .NET IDE.
Because there is no official tested COMAdmin PIA, there may be problem to
use the generated interop assembly.
So to use latebinding will be a good alternative in this scenario to
isolate and workaround problem.
Alsp regsvcs /u is do the reverse job to regsvcs LceEvent.dll.
Every time you recompile the event dll, I suggest you regsvcs /u first and
then call regsvcs to refresh the com+ setting.

Also thanks for your solution, if you still have any concern, please feel
free to post here.

Best regards,

Peter Huang
Microsoft Online Partner Support

Signature

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Blair Allen Stark - 22 Feb 2006 04:09 GMT
hey peter. . . I appreciate your help, but still no joy.

changing to late binding . . .

and implementing the solution posted in that link yields is not a valid LCE
test. . . he is calling  a method on some object p - neither p nor the method
are defined.

his code:
------------------------
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
       p.RealizarPedido(1)
   End Sub
------------------------

there is no declaration for p nor the method.  In the event, the method is
"PedidoRealizado"

if you change his code to:
------------------------
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
       Dim p As New LceEvent.EventosPedidos
       p.PedidoRealizado(1)
   End Sub
---------------------------------
you get the same error that I received. "Unable to invoke..."

furthermore, his subscription release methodology throws an error

If you get a chance. . . please take a look at my code here:
http://www.obj-tec.com/msdnforums/lcedemo2.zip

(I have messed around with switching the event from server/library.)
the sink shouldnt have to be a serviced component. . . should it???

or please send me an email containing the code you got to work based on the
link that you referenced in the google mirror.

thank you

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.