Re: .Net Exodus plugins - Example updated.

Daniel Chandran <[email protected]> Mon, 19 Dec 2005 10:22:40 -0500
Newsgroups gmane.network.jabber.exodus.user
Message-ID <[email protected]>
I've added to Exodus.cs a base class for IExodusChatPlugin. Also attached
are files for an example that implements both the BasePlugin and
BaseChatPlugin.

Feel free to make corrections.
daniel.


On 12/15/05, Joe Hildebrand <joe-bvCY4hpNeH/[email protected]> wrote:
>
> Sorry this took so long.
> Class1 is an example, and Exodus.cs has the base class.
>
>
>
>
> Again, don't put the .dll in the plugins directory for now.
>
> On Dec 9, 2005, at 11:15 AM, Daniel Chandran wrote:
>
> > Could Joe H. or somebody who is an expert an COM - .Net Interop
> > outline the exact steps to follow for Exodus to recognize the
> > plugins written in .NET?
> >
> > I am using Visual Studio, so it automatically does the regasm, and
> > I see the plugin listed in the registry under HKEY_CLASSES_ROOT\CLSID.
> >
> > VS generates two assemblies Interop.ExodusCOM.dll and MyPlugin.dll.
> > I put both of them in C:\Program Files\Exodus\Plugins.  Exodus does
> > not recognize my plugin.  I did a TlbExp on MyPlugin.dll.  After
> > that Exodus recogizes the MyPlugin,  but on attempting to load,
> > complains that it's not a valid Windows Image!!
> >
> > Any help is greatly appreciated.
> >
> > Thanks,
> > Daniel Chandran
> >
> > On 12/9/05, Durga Prasad <dprasad_114-/[email protected] > wrote:
> > hi,
> >
> > Thanks your very much for your reply.  Your information helps a lot
> > to develops plugins accurately for Windows environment.  I still
> > have doubts on custom plugin interaction  of Exodus.  I ll post it
> > in the near time.
> >
> > Would you send your .NET base class that will register
> > automatically to windows registry?
> >
> > thanks,
> > Durga Prasad T
> >
> >
> > [email protected] wrote: Send Exodus mailing list
> > submissions to
> > [email protected]
> >
> > To subscribe or unsubscribe via the World Wide Web, visit
> > http://mail.jabber.org/mailman/listinfo/exodus
> > or, via email, send a message with subject or body 'help' to
> > [email protected]
> >
> > You can reach the person managing the list at
> > [email protected]
> >
> > When replying, please edit your Subject line so it is more specific
> > than "Re: Contents of Exodus digest..."
> > Today's Topics:
> >
> > 1. Re: Help in Exodus Plugin creation in C# (Joe Hildebrand)
> > From: Joe Hildebrand < joe-bvCY4hpNeH/[email protected]>
> > To: Discussion list for all things <[email protected]>
> > Date: Sun, 27 Nov 2005 17:13:07 -0700
> > Subject: Re: [Exodus] Help in Exodus Plugin creation in C#
> >
> > If you use the head of subversion, you'll find this a *lot* easier.
> > Here is the procedure:
> >
> > - Put your .dll anywhere. Eventually, if you put it in Exodus/
> > plugins/net or something, this will get more automated, but for the
> > moment it doesn't matter
> > - Make sure to call regasm on the .dll
> > - Put a registry value at HKCU\Software\Jabber\Exodus\Plugins whose
> > name is the progid of your control, and whose value is a string that
> > describes the plugin.
> > - If you don't have the head of SVN, edit your preference file, and
> > add your progid to the plugin_selected preference. It's a
> > stringList, so each item has an around it.
> > - If you *do* have the head of SVN, your plugin will just show up in
> > the list and can be selected.
> >
> > You'll no longer have to try to get the .TLB into the .dll, which is
> > nice. The downside is that you'll have to figure out (for the
> > moment) how to get your users to call regasm on your .dll to install
> > it. Eventually I'll figure out how to determine which CLR version
> > you compiled with, find the correct version of regasm, and run it
> > automatically.
> >
> > I've also got a .Net base class that does all of the registry stuff
> > automatically. I'll try to remember to post it when I'm back in the
> > office on Monday.
> >
> > On Nov 22, 2005, at 8:19 PM, Durga Prasad wrote:
> >
> > > hi All,
> > >
> > > I want to write a Plugin for Exodus Client using C#. For testing
> > > purpose, I wrote main class which implements IExodusPlugin
> > > interface that will add a Menu Item if the user clicks on a Roster
> > > name.
> > >
> > > The following is the structure of the Main Class ::
> > >
> > > using System;
> > > using System.Runtime.InteropServices;
> > >
> > > namespace ExodusPluginTesting
> > > {
> > > ///
> > > /// Summary description for Class1.
> > > ///
> > >
> > > [ Guid("E10C6CDE-8D8B-46c2-AE85-0185039E9958") ]
> > > [ClassInterface( ClassInterfaceType.AutoDual)]
> > > public class ExodusPluginTesting : Exodus.IExodusPlugin
> > > {
> > > public string ID = "";
> > > Exodus.ExodusController exodusController;
> > >
> > > public void Startup(Exodus.ExodusController exController)
> > > {
> > > string s = "This is my Plugin";
> > > exodusController =
> > > ( Exodus.ExodusController) exController;
> > > ID = exodusController.addContactMenu(s);
> > > }
> > >
> > > public void Shutdown()
> > > {
> > > exodusController.removeContactMenu(ID);
> > > exodusController = null;
> > > }
> > >
> > > public void Process(string xpath, string eventRaised,
> > > string xmlObject)
> > > {
> > > }
> > >
> > > public void NewChat(string jID, Exodus.ExodusChat exodusChat)
> > > {
> > > }
> > >
> > > public void NewRoom(string jID, Exodus.ExodusChat Room)
> > > {
> > > }
> > >
> > > public string NewIM(string jID, ref string body, ref
> > > string subject, string xTags)
> > > {
> > > string k = " " ;
> > > return (k);
> > > }
> > >
> > > public void Configure()
> > > {
> > > }
> > >
> > > public void MenuClick(string ID)
> > > {
> > > }
> > >
> > > public void MsgMenuClick(string ID,string jID, ref string
> > > body,ref string subject)
> > > {
> > > }
> > >
> > > public void NewOutgoingIM(string jID, Exodus.ExodusChat
> > > instantMSG)
> > > {
> > > }
> > > }
> > > }
> > >
> > >
> > > I converted "Exodus.tlb" to "Exodus.dll" using "tlbImp.exe" tool.
> > > And I included this 'Exodus.dll' in my code to import the
> > > "IExodusPlugin" interface structure into the Main Class
> > > (ExodusPluginTesting()).
> > > I built the solution (with Component Registry). THE OUTPUT files I
> > > got is "ExodusPluginTesting.dll" and "ExodusPluginTesting.tlb".
> > >
> > >
> > > Then I placed the 'ExodusPluginTesting.dll' file in "C:\Program
> > > Files\Exodus\Plugins" directory. I started Exodus client. But I
> > > didn't view the PLUGIN in the LIST. I tried several builds and
> > > placed it in PLUGINS directory, still, I didn't find it in the list.
> > >
> > >
> > > Is my Interface implementation correct or shall I need to declare
> > > the interface structure also (without using Exodus.dll).
> > >
> > > Can anybody help me in this aspect what procedure to follow to
> > > create .DLL Plugin for EXODUS.
> > >
> > >
> > >
> > > Thanks,
> > > Durga Prsad T
> > >
> > > Win a Yahoo! Vespa NEW - Yahoo! Cars has 3 Vespa LX125s to be won
> > > Enter Now!
> > > _______________________________________________
> > > Exodus mailing list
> > > [email protected]
> > > http://mail.jabber.org/mailman/listinfo/exodus
> >
> > _______________________________________________
> > Exodus mailing list
> > [email protected]
> > http://mail.jabber.org/mailman/listinfo/exodus
> >
> >
> > Yahoo! Messenger NEW - crystal clear PC to PC calling worldwide
> > with voicemail
> >
> >
> > _______________________________________________
> > Exodus mailing list
> > [email protected]
> > http://mail.jabber.org/mailman/listinfo/exodus
> >
> >
> >
> > _______________________________________________
> > Exodus mailing list
> > [email protected]
> > http://mail.jabber.org/mailman/listinfo/exodus
>
>
>
> _______________________________________________
> Exodus mailing list
> [email protected]
> http://mail.jabber.org/mailman/listinfo/exodus
>
>
>
>

_______________________________________________
Exodus mailing list
[email protected]
http://mail.jabber.org/mailman/listinfo/exodus
DotNetPlugin.cs (text/plain, 1.1 KB)
using System;
using System.Runtime.InteropServices;
using ExodusCOM;

namespace ExodusDotNet
{
	[ComVisible(true)]
	[Guid("99AFBCC1-5D19-41e6-BC70-4119585EB062")]
	[Exodus.HelpString("Exodus Plugin in .NET")]
	public class DemoPlugin : Exodus.BasePlugin
	{	
		private int _authcb;
		
		public override void Startup(ExodusCOM.ExodusController ExodusController)
		{
			// This will get us the base class m_controller
			base.Startup (ExodusController);

			// Let's register for some callbacks
			_authcb = m_controller.RegisterCallback("/session/authenticated",this);
		}

		public override void Shutdown()
		{
			m_controller.UnRegisterCallback(_authcb);
			base.Shutdown ();
		}
		
		public override void Process(string xpath, string @event, string xml)
		{
			if ( @event == "/session/authenticated" ) 
			{
				System.Windows.Forms.MessageBox.Show("Succesfully authenticated");
			}
		}

		public override void NewChat(string jid, ExodusChat Chat)
		{
			ChatPlugin chatPlugin;

			chatPlugin = new ChatPlugin("DemoChatPlugin",Chat);
			chatPlugin.regID = Chat.RegisterPlugin(chatPlugin);
			
		}


	}
	
}
ChatPlugin.cs (text/plain, 649 B)
using System;
using System.Runtime.InteropServices;
using ExodusCOM;

namespace ExodusDotNet
{
	[ComVisible(true)]
	[Guid("F1B1E16E-2E72-410d-B5D4-317AF1FDCD28")]
	public class ChatPlugin : Exodus.BaseChatPlugin
	{
		private ExodusChat _chat;
		public int regID;

		public ChatPlugin(string name, ExodusChat chat)
		{
			Name = name;
			_chat = chat;

		}

		public override void onBeforeMessage(ref string body)
		{
			System.Windows.Forms.MessageBox.Show("ChatPlugin: onBeforeMessage");
			
		}

		public override void onRecvMessage(string body, string xml)
		{
			System.Windows.Forms.MessageBox.Show("ChatPlugin: onRecvMessage");
		}



		
	}
}
Exodus.cs (text/plain, 4.9 KB)
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Collections;
using ExodusCOM;

namespace Exodus
{
    /// <summary>
    /// Annotate a class with a Help string, so it can be pulled off at register time.
    /// Note: this doesn't actually set anything in the generated typelib.
    /// </summary>
    [ComVisible(false)]
    [AttributeUsage(AttributeTargets.Class)]
    public class HelpStringAttribute: Attribute
    {
        private string value;
        public HelpStringAttribute(string value) 
        {
            this.value = value;
        }
        public string Value 
        {
            get { return value; }
        }
    }


    public abstract class BasePlugin : IExodusPlugin, IDisposable
    {
        protected IExodusController m_controller = null;

        [ComRegisterFunction]
        static public void Register(Type t)
        {
            // oops.  Gets called for the base class, too.
            if (t.IsAbstract)
                return;

            try
            {
                RegistryKey key = PluginKey;

                string name = GetProgId(t);
                string help = null;
                HelpStringAttribute[] hattr = (HelpStringAttribute[]) 
                    t.GetCustomAttributes(typeof(HelpStringAttribute), false);
                if (hattr.Length > 0)
                    help = hattr[0].Value;
                else
                    help = name + " Plugin";
                key.SetValue(name, help);
            }
            catch(Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString());            
            }
        }

        [ComUnregisterFunction]
        static public void Unregister(Type t)
        {
            // oops.  Gets called for the base class, too.
            if (t.IsAbstract)
                return;

            RegistryKey key = PluginKey;
            string name = GetProgId(t);
            key.DeleteValue(name, false);
        }

        static private RegistryKey PluginKey
        {
            get
            {
                // HKEY_CURRENT_USER\Software\Jabber\Exodus\Plugins
                RegistryKey key = Registry.CurrentUser;
                key = key.CreateSubKey("Software");
                key = key.CreateSubKey("Jabber");
                key = key.CreateSubKey("Exodus");
                key = key.CreateSubKey("Plugins");
                return key;
            }
        }

        /// <summary>
        /// Have to check for a ProgIdAttribute, which overrides the class name.
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        static private string GetProgId(Type t)
        {
            ProgIdAttribute[] nattr = (ProgIdAttribute[]) t.GetCustomAttributes(typeof(ProgIdAttribute), false);
            if (nattr.Length > 0)
                return nattr[0].Value;
            else
                return t.FullName;
        }

        #region IExodusPlugin Members

        public virtual void Process(string xpath, string @event, string xml)
        {

        }

        public virtual void MenuClick(string ID)
        {
        }

        public virtual void Configure()
        {
        }

        public virtual string NewIM(string jid, ref string Body, ref string Subject, string XTags)
        {
            return "";
        }

        public virtual void NewChat(string jid, ExodusCOM.ExodusChat Chat)
        {
        }

        public virtual void NewOutgoingIM(string jid, ExodusCOM.ExodusChat InstantMsg)
        {
        }

        public virtual void Shutdown()
        {
            m_controller = null;
        }

        public virtual void NewRoom(string jid, ExodusCOM.ExodusChat Room)
        {
        }

        public virtual void MsgMenuClick(string ID, string jid, ref string Body, ref string Subject)
        {
        }

        public virtual void Startup(ExodusCOM.ExodusController ExodusController)
        {
            m_controller = ExodusController;
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            m_controller = null;
        }

        #endregion
    }

	public abstract class BaseChatPlugin : IExodusChatPlugin
	{
		private string _name;
		#region IExodusChatPlugin members

		public virtual string Name
		{
			get { return _name;}
			set { _name = value;}			
		}

		public virtual string onAfterMessage(ref string body)
		{
			return "";
		}

		public virtual void onBeforeMessage(ref string body)
		{
			
		}

		public virtual void onClose()
		{
		}

		public virtual void onContextMenu(string ID)
		{
		}

		public virtual void onKeyPress(string key)
		{
		}

		public virtual void onMenu(string ID)
		{
		}
		
		public virtual void onNewWindow(System.Int32 HWND)
		{
		}

		public virtual void onPaste()
		{
		}

		public virtual void onRecvMessage(string body, string xml)
		{
		}

		#endregion

	}


}