Premise Error when using Minibroker to subscribe to a property in vb.net

Motorola Premise

etc6849

Senior Member
Any help is much appreciated! I'm working on a minibroker application that will grap emails from a POP3 SSL server and build corresponding objects in SYS under a Home object called "MissedCalls." MissedCalls has a property called "Update" that is triggered so that Minibroker will run the subscribed .net subroutine. Everything works, except I always receive the error below when attempted to make the subscription.

System.InvalidCastException was unhandled
Message="Specified cast is not valid."
Source="Interop.MINIBROKERLib"
StackTrace:
at MINIBROKERLib.IRemotePremiseObject.SubscribeToProperty(String PropertyName, String NameOfCallbackFunction, Object ObjectContainingCallback)
at WindowsApplication1.Form1.Connect() in C:\Documents and Settings\etc6849\My Documents\Visual Studio 2005\Projects\PremiseClient\PremiseClient\Form1.vb:line 41
at WindowsApplication1.Form1.Button1_Click(Object sender, EventArgs e) in C:\Documents and Settings\etc6849\My Documents\Visual Studio 2005\Projects\PremiseClient\PremiseClient\Form1.vb:line 22
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(ApplicationContext context)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at WindowsApplication1.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()


Code:
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Data
Imports MINIBROKERLib
'OSPOP3_Plus is a free POP3 COM built for vb.net
Imports OSPOP3_Plus

Public Class Form1
    Inherits System.Windows.Forms.Form
    Private miniBroker As MINIBROKERLib.ISYSMiniBroker = New MINIBROKERLib.SYSMiniBroker()
    Private oRoot As MINIBROKERLib.IRemotePremiseObject = Nothing
    Private oHome As MINIBROKERLib.IRemotePremiseObject = Nothing
    Private oMissedCalls As MINIBROKERLib.IRemotePremiseObject = Nothing
    Private oCollectionMissedCalls As MINIBROKERLib.IRemotePremiseObjectCollection = Nothing
    Private oMissedCall As MINIBROKERLib.IRemotePremiseObject = Nothing
    Private oSession As New OSPOP3_Plus.Session
    Private iSubscription As New Integer
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' Connect to Premise after user clicks the "Connect" button
        Connect()
    End Sub
    Public Sub Connect()
        ' Connect to Premise
        oRoot = miniBroker.Connect(Me.tbIPAddress.Text, Me.tbUserName.Text, Me.tbPassWord.Text)
        oHome = oRoot.GetObject("sys://Home")

        ' Get MissedCalls object from SYS; if it doesn't exist, create it
        Try
            oMissedCalls = oRoot.GetObject("sys://Home/MissedCalls")
        Catch oExc As Exception
            oMissedCalls = oHome.CreateObject("sys://Schema/Modules/GoogleVoice/Classes/MissedCalls", "MissedCalls")
        End Try

        GetMissedCalls(oMissedCalls)

        ' Subscribe to Home.MissedCalls.Update
        ' Update is a boolean property that a timer will toggle periodically within SYS
        ' This should then run the UpdateCallBack() subroutine found below
        oMissedCalls.SubscribeToProperty("Update", "UpdateCallBack", Me)
    End Sub
    'ByVal subscriptionID As Long, ByVal parent As MINIBROKERLib.IRemotePremiseObject, ByVal obj As MINIBROKERLib.IRemotePremiseObjectByVal subscriptionID As Long, ByVal parent As MINIBROKERLib.IRemotePremiseObject, ByVal obj As MINIBROKERLib.IRemotePremiseObject
    Public Sub UpdateCallBack()
        'Dim line As String

        ' Initialize POP3
        oSession = New OSPOP3_Plus.Session

        With oSession
            .RaiseError = False
            .Timeout = oMissedCalls.GetValue("Timeout")
            .ServerName = oMissedCalls.GetValue("POP3Server")
            .Login = oMissedCalls.GetValue("AccountName")
            .Password = oMissedCalls.GetValue("AccountPassword")
            .PortNumber = oMissedCalls.GetValue("PortNumber")
            .UseSSL = oMissedCalls.GetValue("UseSSL")
        End With
        oMissedCalls.SetValue("Status", "Connecting...")

        ClearMissedCalls()
        GetMissedCalls(oMissedCalls)
        'line = String.Format("Property id {1} of ojbect {1} has changed.", obj.ObjectID, Parent.Name)
        'MsgBox(line)
    End Sub
    Sub ClearMissedCalls()
        oCollectionMissedCalls = oMissedCalls.GetObjectsByType("sys://Schema/Modules/GoogleVoice/Classes/MissedCall", False)
        For Each oMissedCall In oCollectionMissedCalls
            If Not IsNothing(oMissedCall) Then
                oMissedCalls.DeleteObject(oMissedCall.Name)
                'oHome.DeleteObject("MissedCall1")
            End If
        Next
    End Sub
    Sub GetMissedCalls(ByVal oMissedCalls As MINIBROKERLib.IRemotePremiseObject)
        Dim oMLE As OSPOP3_Plus.MessageListEntry
        Dim oMessage As OSPOP3_Plus.Message
        Dim iNum As Integer
        Dim iMsgCount As Integer
        Dim oStoreMissedCall As MINIBROKERLib.IRemotePremiseObject

        If oSession.OpenPOP3 Then
            oMissedCalls.SetValue("Status", "Acquiring MissedCalls information ...")
            oSession.GetMailboxSize()
            oMissedCalls.SetValue("MissedCallCount", 0)
            iMsgCount = oSession.GetMessageCount()

            oSession.GetMessageList()
            For Each oMLE In oSession.MessageList
                If 200 > oMLE.ID > (oSession.GetMessageCount() - oMissedCalls.GetValue("MaxMissedCalls")) Then
                    oMessage = oSession.GetMessage(oMLE.ID)
                    If oMessage.Sender.Address = "[email protected]" Then
                        iNum = iNum + 1
                        oMissedCalls.SetValue("MissedCallCount", oMissedCalls.GetValue("MissedCallCount") + 1)
                        If iNum <= oMissedCalls.GetValue("MaxMissedCalls") Then
                            oStoreMissedCall = oMissedCalls.CreateObject("sys://Schema/Modules/GoogleVoice/Classes/MissedCall", "MissedCall" & iNum)
                            oMessage = oSession.GetMessage(oMLE.ID)

                            oStoreMissedCall.SetValue("EMID", oMLE.ID)
                            oStoreMissedCall.SetValue("SenderName", oMessage.Sender.Name)
                            oStoreMissedCall.SetValue("SenderAddress", oMessage.Sender.Address)
                            oStoreMissedCall.SetValue("CallDetails", oMessage.Subject)

                            '.DateCallReceived = this.ConvertDate(oMissedCall.DateSent)
                            '.CallDetails = Trim(Left(oMissedCall.Subject, Len(oMissedCall.Subject) - 11))
                        Else
                            Exit For
                        End If
                    End If
                End If
            Next
            oMessage = Nothing
            oMLE = Nothing
            oSession.ClosePOP3()
            oMissedCalls.SetValue("DisplayName", oMissedCalls.GetValue("Name") & ": " & oMissedCalls.GetValue("MissedCallCount"))
            oMissedCalls.SetValue("LastUpdate", Now)
            oMissedCalls.SetValue("Status", "Idle")
        Else
            oMissedCalls.SetValue("Status", "Unable to open MissedCalls.")
        End If

        ' Let SYS handle the update timer instead...?
        ' Reset the MissedCalls polling timer
        'If oMissedCalls.GetValue("UpdateInterval") > 0 Then
        'System.addTimer(this.UpdateInterval * 60, "this.Update=true", 1, this.name & this.ObjectID)
        'End If
    End Sub
End Class
 
The property subscription looks right except for the return value. Subscribe to property returns an integer, so you should probably modify your code to look something like this:

Code:
dim iRet as integer
iRet=oMissedCalls.SubscribeToProperty("Update", "UpdateCallBack", Me)

The other thing you need to do is match up the callback signature to what minibroker is expecting. The signature should be something like this:

Code:
Public Sub UpdateCallback(ByVal subID As Integer, ByVal objChanged As MINIBROKERLib.IRemotePremiseObject, ByVal propChanged As MINIBROKERLib.IRemotePremiseObject, ByVal newValue As Object)

Don't forget to COM-enable your project under project properties.
 
You guys are way outta my league!!!!
icon_pray.gif
 
Thanks John, I'll try you suggestions tonight :) I think I found a few of the older examples buried in a zip file on the original support thread. Other than that and exploring the objects in VS, I'm guessing there's no documentation?

UPDATE: Attached is the COM-Visable setting John was talking about. Enabling it fixed my issue :)
 

Attachments

  • COMVisable.JPG
    COMVisable.JPG
    77.4 KB · Views: 3
Since we can all program in vbscript, VB.net is not too hard. The benefit to using minibroker for this application is that the other modules can continue to run while emails (aka googlevoice messages) are being fetched. This can take 10-30 seconds. I'd give minibroker a try! There's also a web example that uses minibroker that looks interesting, but it's in C# and would take a lot of work for me to begin to understand.

You guys are way outta my league!!!!
icon_pray.gif
 
Hi John, everything works good thanks to your help. I made your suggested changes and cleaned up the code the other night. The only thing I did differently was I decided not to capture the integer returned from the call to SubscribeToProperty; it appears capturing this is optional?

Also, is it ok to let vb.net implicitly convert oNewValue (object passed to "UpdateCallBack") to a new data type or should I learn casting? VB.net seems ok with using the object as a boolean, but this seems like it might be a bad idea for all data types?

Unrelated, but I've run into a problem with OSPOP3 not being able to grab more than 301 messages from a large mailbox. This wouldn't be an issue except that it grabs the 301 oldest messages from the POP3 server! Consequently, I'm looking for a better method to grab emails... EDIT: The 301 message limit can be increased by adjusting the time out for the POP3 connection.

Code:
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Data
Imports MINIBROKERLib
Imports OSPOP3_Plus

Public Class Form1
    Inherits System.Windows.Forms.Form
    Private miniBroker As MINIBROKERLib.ISYSMiniBroker = New MINIBROKERLib.SYSMiniBroker()
    Private oRoot As MINIBROKERLib.IRemotePremiseObject = Nothing
    Private oHome As MINIBROKERLib.IRemotePremiseObject = Nothing
    Private oMissedCalls As MINIBROKERLib.IRemotePremiseObject = Nothing
    Private oCollectionMissedCalls As MINIBROKERLib.IRemotePremiseObjectCollection = Nothing
    Private oMissedCall As MINIBROKERLib.IRemotePremiseObject = Nothing
    Private oSession As New OSPOP3_Plus.Session
    Private iSubscription As New Integer
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.tbIPAddress.Text = "LocalHost"
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' Connect to Premise after user clicks the "Connect" button
        Connect()
    End Sub
    Private Sub Disconnect()
        If (miniBroker.connectionStatus = MINIBROKERLib.MiniBrokerConnectionStatus.miniBrokerConnected) Then
            ' Add code to disconnect
        End If
    End Sub
    Private Sub Connect()
        If (miniBroker.connectionStatus <> MINIBROKERLib.MiniBrokerConnectionStatus.miniBrokerConnected) Then
            ' Connect to Premise
            Try
                oRoot = miniBroker.Connect(Me.tbIPAddress.Text, Me.tbUserName.Text, Me.tbPassWord.Text)
                'MessageBox.Show("Connected to " & Me.tbIPAddress.Text, "Server Connection")
                Me.Button1.BackColor = Color.Green
            Catch
                ' If we can't connect, exit Connect subroutine...
                'MessageBox.Show("Could not connected to: " & Me.tbIPAddress.Text, "Server Connection")
                Me.Button1.BackColor = Color.Red
                Exit Sub
            End Try

            oHome = oRoot.GetObject("sys://Home")

            ' Get MissedCalls object from SYS; if it doesn't exist, create it
            Try
                oMissedCalls = oRoot.GetObject("sys://Home/MissedCalls")
            Catch
                oMissedCalls = oHome.CreateObject("sys://Schema/Modules/GoogleVoice/Classes/MissedCalls", "MissedCalls")
            End Try

            GetMissedCalls(oMissedCalls)

            ' Subscribe to Home.MissedCalls.Update where Update is a boolean property that a timer will toggle periodically within SYS
            oMissedCalls.SubscribeToProperty("Update", "UpdateCallBack", Me)
        End If
    End Sub
    Public Sub UpdateCallBack(ByVal subscriptionID As Integer, ByVal parent As MINIBROKERLib.IRemotePremiseObject, ByVal obj As MINIBROKERLib.IRemotePremiseObject, ByVal oNewValue As Object)
        If (miniBroker.connectionStatus = MINIBROKERLib.MiniBrokerConnectionStatus.miniBrokerConnected) And oNewValue = True Then
            InitPOP3(oMissedCalls)
            GetMissedCalls(oMissedCalls)
        End If
    End Sub
    Private Sub InitPOP3(ByVal oMissedCalls As MINIBROKERLib.IRemotePremiseObject)
        ' Initialize POP3 connection
        oMissedCalls.SetValue("Status", "Connecting...")
        oSession = New OSPOP3_Plus.Session
        With oSession
            .RaiseError = False
            .Timeout = oMissedCalls.GetValue("Timeout")
            .ServerName = oMissedCalls.GetValue("POP3Server")
            .Login = oMissedCalls.GetValue("AccountName")
            .Password = oMissedCalls.GetValue("AccountPassword")
            .PortNumber = oMissedCalls.GetValue("PortNumber")
            .UseSSL = oMissedCalls.GetValue("UseSSL")
        End With
    End Sub
    Private Sub GetMissedCalls(ByVal oMissedCalls As MINIBROKERLib.IRemotePremiseObject)
        Dim oMLE As OSPOP3_Plus.MessageListEntry
        Dim oMessage As OSPOP3_Plus.Message
        Dim iNum As Integer = 0
        Dim iMsgCount As Integer
        Dim oStoreMissedCall As MINIBROKERLib.IRemotePremiseObject

        ClearMissedCalls(oMissedCalls)
        If oSession.OpenPOP3 Then
            oMissedCalls.SetValue("Status", "Acquiring MissedCalls information ...")
            oSession.GetMailboxSize()
            iMsgCount = oSession.GetMessageCount()
            oSession.GetMessageList()
            oSession.MessageList.Reverse()
            For Each oMLE In oSession.MessageList
                'I still need to clean this code up a lot...
                'If oMLE.ID > (oSession.GetMessageCount() - oMissedCalls.GetValue("MaxMissedCalls")) Then
                If iNum < 100 Then
                    oMessage = oSession.GetMessage(oMLE.ID)
                    If oMessage.Sender.Address = "[email protected]" Then
                        iNum = iNum + 1
                        oMissedCalls.SetValue("MissedCallCount", oMissedCalls.GetValue("MissedCallCount") + 1)
                        If iNum <= oMissedCalls.GetValue("MaxMissedCalls") Then
                            oStoreMissedCall = oMissedCalls.CreateObject("sys://Schema/Modules/GoogleVoice/Classes/MissedCall", "MissedCall" & iNum)
                            oMessage = oSession.GetMessage(oMLE.ID)

                            oStoreMissedCall.SetValue("EMID", oMLE.ID)
                            oStoreMissedCall.SetValue("SenderName", oMessage.Sender.Name)
                            oStoreMissedCall.SetValue("SenderAddress", oMessage.Sender.Address)
                            oStoreMissedCall.SetValue("CallDetails", oMessage.Subject)

                            '.DateCallReceived = this.ConvertDate(oMissedCall.DateSent)
                            '.CallDetails = Trim(Left(oMissedCall.Subject, Len(oMissedCall.Subject) - 11))
                        Else
                            Exit For
                        End If
                    End If
                End If
            Next
            oSession.ClosePOP3()
            oMessage = Nothing
            oMLE = Nothing
            oMissedCalls.SetValue("DisplayName", oMissedCalls.GetValue("Name") & ": " & oMissedCalls.GetValue("MissedCallCount"))
            oMissedCalls.SetValue("LastUpdate", Now)
            oMissedCalls.SetValue("Status", "Idle")
        Else
            oMissedCalls.SetValue("Status", "Unable to open MissedCalls.")
        End If
    End Sub
    Private Sub ClearMissedCalls(ByVal oMissedCalls As MINIBROKERLib.IRemotePremiseObject)
        oMissedCalls.SetValue("MissedCallCount", 0)
        oCollectionMissedCalls = oMissedCalls.GetObjectsByType("sys://Schema/Modules/GoogleVoice/Classes/MissedCall", False)
        For Each oMissedCall In oCollectionMissedCalls
            If Not IsNothing(oMissedCall) Then
                oMissedCalls.DeleteObject(oMissedCall.Name)
            End If
        Next
    End Sub
End Class
 
Glad to hear it's working!

Also, is it ok to let vb.net implicitly convert oNewValue (object passed to "UpdateCallBack") to a new data type or should I learn casting? VB.net seems ok with using the object as a boolean, but this seems like it might be a bad idea for all data types?

You want to leave the NewValue parameter in the callback procedure as "Object". .NET will take care of late-binding the actual variable being passed at runtime, so you don't need to explicitly define it as a boolean (or whatever else you expect). I think the idea is to use a single callback procedure to handle changes in more than one property or if you don't exactly know what type the property is you are watching.

Good stuff! What kind of hardware/OS are you running on?

-John
 
Here are some pics of my install: http://www.cocoontech.com/forums/index.php?showtopic=18302

I built a mini-ITX PC to run Premise. It uses an SSD, an Atom 330 dual core processor and has 1GB of ram. It was running XP SP1, but I upgraded it to SP2 when I installed VS 2005. I use remote desktop to maintain the PC (has no keyboard, mouse or monitor attached to it) and use VS 2005.

It's over spec'd for Premise, but I built it with the intention of recording and serving media. I'm still using a dedicated HTPC for that now though.

I believe you're the creator of the UPnP module and this is something I definitely want to explore now that Windows 7 supposedly acts as a true UPnP client. I'm assuming the UPnP module for Premise will work with an XBOX 360, Windows Media Player and Windows Media Center (assuming you're using windows 7 anyway)?

Good stuff! What kind of hardware/OS are you running on?
 
So, I'm finally getting back to this topic. The reason I quit working on it is still this:

Unrelated, but I've run into a problem with OSPOP3 not being able to grab more than 301 messages from a large mailbox. This wouldn't be an issue except that it grabs the 301 oldest messages from the POP3 server! Consequently, I'm looking for a better method to grab emails... EDIT: The 301 message limit can be increased by adjusting the time out for the POP3 connection, but the oldest messages still show up first.

However, there appears to be a solution if I use gmail:
http://code.google.com/apis/gmail/docs/inbox_feed.html

Since I know have full Google Voice integration with Sprint, hopefully I can figure out to get Google Voice to work with Premise via the gmail API.
 
Back
Top