Latest Version: 0.31
Download:
https://sourceforge.net/project/down...zip&a=99784981
Source:
http://carpal.svn.sourceforge.net/viewvc/carpal/

WORD OF WARNING:
The source may not match the version of the binaries. I am working to keep them up to date in parallel, but sometimes the source jumps ahead, and sometimes it's a day or two behind.

Changes from 0.30:
This release introduces a new feature, the ability to load and run .net compiled plugins (vb.net, c#, managed c++) via the InterfaceClass.dll reference.

Quick and dirty how-to for plugins:

Start a new .net library project for your favorite language, for this example I'm using c#.

Right click on "References" in the solution explorer. Click browse and find "InterfaceClass.dll" in the CarPal base directory. Select this file. At the top of your source code, below the normal "using" statements, add a new one:

using InterfaceClasses;

Below is a code example of a simple plugin, that listens for a message "SamplePlugin:test play" and sends a play command to the media engine. I will be posting a more comprehensive guide including VB.net examples and a full description of what commands are available, as well as an introduction to the event system within a day or two (As soon as I get it written up).

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using InterfaceClasses;

public class Plugin
{
    
    public Plugin()
    {

    }
    InterfaceClasses.IPluginHost _hostPlugin;
    public String Name()
    {
        return "SamplePlugin"; //This MUST be a single word, no spaces and unique to your plugin
    }
    public String Author()
    {
        return "Michael Carpenter";
    }
    public String Description()
    {
        return "A small sample plugin";
    }
    public String Version()
    {
        return "1.0.0";
    }
    public void Initialize(InterfaceClasses.IPluginHost host)
    {
        _hostPlugin = host;
    }
    public void passPluginMessage(String sender, String message)
    {
        try
        {
            IPCMessage ipcMessage = new IPCMessage(message);
            if (ipcMessage.getClass() == "test")
            {
                if (ipcMessage.getMethod() == "play")
                {
                    _hostPlugin.passCoreMessage("SamplePlugin", "MediaEngine:media play");
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

        
    }

}