Page 1 of 3

Events don't work with C#

Posted: Sat May 10, 2008 12:47 pm
by Christoph
Hey,
I'm trying to catch some event from MM.
So I tried the following code:

Code: Select all

private void Form1_Load(object sender, EventArgs e) {
  SDB = new SongsDB.SDBApplication();
  SDB.OnPlay += new ISDBApplicationEvents_OnPlayEventHandler(SDB_OnPlay);
}

void SDB_OnPlay() {
  MessageBox.Show("a");
}
But unfortunately it doesn't work. Have I forgotten something?

Thanks,
Christoph

Posted: Sun May 11, 2008 8:47 am
by Steegy
This has been asked quite a few times in the past (including by me), but the problem didn't get solved.

Hopefully you will have better luck.

Meanwhile, you can use the "old-style event system", i.e. checking each x seconds (using a timer) if a property has changed.

Posted: Sun May 11, 2008 2:04 pm
by Christoph
Hey,
thanks for your reply. I will think about your method.
But it would be great a statement from the MM team. :)

Christoph

Re: Events don't work with C#

Posted: Thu Mar 03, 2011 10:25 am
by jitterjames
last post was 2008... wow.

Has this been fixed yet?

Re: Events don't work with C#

Posted: Thu Mar 17, 2011 1:17 pm
by Melloware
jitterjames wrote:last post was 2008... wow.

Has this been fixed yet?
As far as I know this is still not fixed. The only way I have gotten it to work is to make my C# app a COM object and then register it with MediaMonkey and then it receives the events properly.

Re: Events don't work with C#

Posted: Thu Mar 17, 2011 4:10 pm
by jitterjames
sounds complimificated.

Is it?

Re: Events don't work with C#

Posted: Thu Mar 17, 2011 4:25 pm
by Melloware
jitterjames wrote:sounds complimificated.

Is it?
Yeah its definitely not simple.

Re: Events don't work with C#

Posted: Tue May 17, 2011 11:56 am
by mcow
Melloware wrote:The only way I have gotten it to work is to make my C# app a COM object and then register it with MediaMonkey and then it receives the events properly.
How do you "register it with MediaMonkey"?

Re: Events don't work with C#

Posted: Tue May 17, 2011 11:59 am
by Melloware
The guys who wrote teh MonkeyToy's sample provided their code. That is how I figured it out...

http://www.stax76.bplaced.net/index.php?slab=monkeytoys

Re: Events don't work with C#

Posted: Wed May 18, 2011 2:10 pm
by mcow
Pertinent to receiving events from MM, I see three things happening in that source code (assuming I'm reading this right):
1) They set up their VB.NET app as a registered COM server. (COM does not depend on .NET, but .NET assemblies are easy to turn into COM components. Of course, MM is a native app, not a .NET/managed one.)
2) They create an autoscript that instantiates the app instance of the plugin, and then calls Init() on the instance. (I assume this is the "register with MM" step.) It's not clear but I think in this case the app is running InProc, not as a local server.
3) They attach a handler to SDB.OnShutdown (which removes the system-wide keyboard hooks installed during the Init() call). There are also numerous hooks into the controls of the app itself, which I guess are driven by MM.

That event-hook-in uses .NET delegation. In C#, the code would similarly be

Code: Select all

SDB.OnShutdown += ExitApplication; //or something like this
This presumably is enabled by .NET providing appropriate wrappers to the COM event handler exposed by MM.

Out-of-proc event handlers are still elusive! They should be as easy to implement as out-of-proc calls into MM, but so far, no go. (Which, I know, is a common complaint.)

Re: Events don't work with C#

Posted: Wed May 18, 2011 2:22 pm
by Melloware
You are 100% correct in all of the above.

I based my MonkeyTunes plugin on the same architecture (in C# instead of VB) and it works great. It is a lot of trouble to go through but it is the only way to get in-process calls in your plugin. Since the script instantiates your C# app as a COM object the COM runs in-process with the main MM process and thus is handed the events from the SDB object already running in the script engine.

Re: Events don't work with C#

Posted: Wed May 18, 2011 2:36 pm
by jitterjames
The way I got around this may not be pretty but it actually seems to work extremely well. My application already receives events through UDP broadcasts, so I used a simple MM script that calls a command-line udp sender with a parameter. The added bonus is that your other computers on the LAN can receive the events as well.

Code: Select all

'==========================================================================
'
' INSTALL:
' - Put script into MediaMonkey's "Scripts\Auto" folder and (re)start MediaMonkey
'
'========================================================================== 
Option Explicit
'-------------------------------------------------------
  Dim WShell
  Set WShell = CreateObject("WScript.Shell")

Function sendEvent(strEvent)	
	WShell.Run("""" & SDB.ApplicationPath & "Scripts\Auto\udpsender.exe"" 33000 " & strEvent),0,1
End Function
'-------------------------------------------------------

Sub OnStartup
  Script.RegisterEvent SDB, "OnShutdown", "SDBShutdown" 
  Script.RegisterEvent SDB, "OnPlay", "SDBPlay" 
  Script.RegisterEvent SDB, "OnStop", "SDBStop" 
  Script.RegisterEvent SDB, "OnSeek", "SDBSeek" 
  Script.RegisterEvent SDB, "OnPause", "SDBPause" 
End Sub 

'Events Handling 
Sub SDBShutdown 
    sendEvent("""event&&MM.ShutDown""")
End Sub 
 
Sub SDBPlay
    sendEvent("""event&&MM.Play&&"&SDB.Player.CurrentSong.Title&"&&"&SDB.Player.CurrentSong.Artist.Name&"""")
End Sub
 
Sub SDBStop 
    sendEvent("""event&&MM.Stop""")
End Sub

Sub SDBSeek 
    sendEvent("""event&&MM.Seek""")
End Sub 
 
Sub SDBPause
    sendEvent("""event&&MM.Pause""")
End Sub 
 
You can get the commandline exe here:
http://dl.dropbox.com/u/514879/udpsender.exe

If someone could put together a simple C# application that shows how to register for com that would be great. It's all over my head, but I imagine I could adapt it to my code given a working example.

Re: Events don't work with C#

Posted: Wed May 18, 2011 2:38 pm
by mcow
@melloware: OK. Well, I want to write in Python. It's not clear whether I can make this work in-proc or not. However, this code (from Python's win32com package) works -- that is, it displays the event-message after the Visible property is changed:

Code: Select all

import win32com.client

class IEEventHandler:
  def OnVisible(self, visible):
    print "Visible changed:", visible
ie = win32com.client.DispatchWithEvents("InternetExplorer.Application", IEEventHandler)
ie.Visible = 1
and this code does not display anything:

Code: Select all

import win32com.client

class MMEventHandler():
    def OnPlay(self):
        print "Now playing"
sdb = win32com.client.DispatchWithEvents('SongsDB.SDBApplication', MMEventHandler)
sdb.Player.Play()
In my view, this means the COM implementation within MM is faulty.

Re: Events don't work with C#

Posted: Wed May 18, 2011 2:42 pm
by Melloware
You are correct the COM implementation for Events in MM is faulty.

If you read these forums you will see people have had this problem for years. You can manipulate the SongsDB object through Python out-of-process but the only thing you can do is register for events like OnPlay etc. It is the same problem I had with C#. the only way I have gotten it to work is to use the COM trick where basically I am having MM load and run my COM object just like MonkeyToys example.

Or like in JitterJames trick of having the VBS Script forward you the events somehow like his UDP Sender which is messy but will also work.

Re: Events don't work with C#

Posted: Wed May 18, 2011 2:45 pm
by mcow
Is there a bug filed about the faulty COM implementation?