.Net Plugin

We proudly present: The release of DMXControl 3.3.3!


On September 29, 2026, we held our release show for DMXControl 3.3.3. During our usual “hour-long” session, we showed you all the new features in this version and what it now has to offer.
Read all about it in the corresponding news article: We proudly present: The release of DMXControl 3.3.3!


  • Is there any hope of creating DMXControl plugins in .Net? I tried to do this but I've hit some major problems.

    SUCCESS:
    I was able to add a reference to DMXCTypeLib.dll without a problem.

    SUCCESS:
    I was able to import and implement the IDMXCPlugin and IDMXCModule interfaces without a problem.

    PROBLEM:
    Type_Module_Info.Messages did NOT seem to translate to .Net correctly. It is imported as type VBA.Collection and I can't add any items to the collection or create a new collection instance. Without this, I can't specify which messages I want to process.

    SUCCESS:
    I am able to register my .Net class for COM interop.

    SUCCESS:
    I believe I am able to specify the needed class name using the ProgID attribute.

    PROBLEM:
    Whenever DMXControl loads it tries to register the .Net .dll with COM. Internally this calls DllRegisterServer, which does not exist for .Net assemblies. .Net assemblies are registered using RegAsm.exe. .Net components can be created using their ProgID but cannot be registered in the way that DMXControl is attempting to register them.


    The plugin I'm trying to write is an output plugin for the Rock Band stage kit, a cheap lighting kit for home use ($99 USD). The picture at that link shows a serial port, but serial is NOT supported in the retail kits. These kits connect to an XBOX 360 USB port and I have started reverse engineering the protocol on Windows using XNA (.Net). Light data is sent to these kits as controller vibration data. So I can control various lights by calling GamePad.SetVibration.

    For more information about my hacking attempt, see here:

    PC Stage Kit Control


    So, any thoughts? Will there ever be a way to load a .Net class as a plugin and allow that class to specify the messages it wants to recieve?

  • I do not know how to solve your problem, because I know too little about COM in .NET. But maybe it can help you when I will explain the way DMXControl detects and enables plugins.

    In the plugin initialization procedure there is one main loop that is repeated for each file with the correct file extension (.out.dll in case of output plugins).
    The first step is to register the DLL (can be supressed for debugging purposes with the command line switch -debugdll:filename). This uses the following API calls:
    * LoadLibrary (loads the dll to memory)
    * GetProcAddress (finds the address of "DllRegisterServer")
    * CreateThread (Starts a thread for the found procedure)
    * FreeLibrary (unloads the library)

    After this, the COM DLL should be correctly registered and can be used. The next step then is to load the type library information from the DLL (using TLBINF32.DLL):
    * TLI.TypeLibInfoFromFile(filename)

    This gives DMXC the information about the module name and the exported classes. Now it iterates over each class and tries to create an instance:
    * CreateObject

    If this was successful, the "PluginName"-Function of the object will be called. When the plugin was enabled by the user the normal process of Init'ing and Enabling will start.

    I hope this information can help you to solve the problem. I think the problem could be a missing typelib info in the dll?

    However, the next big version of DMXC (3.0) will be written in .NET, so it will be no problem to load .NET plugins. :D But as this will be a complete rewrite with a completely new architecture, development will take some time (at least a year).

    Regards,
    Stefan

  • Thank you very much for your reply Stephan. Your details confirm the incompatibility with the way that .Net exposes classes to COM.

    * LoadLibrary (loads the dll to memory)
    * GetProcAddress (finds the address of "DllRegisterServer")
    * CreateThread (Starts a thread for the found procedure)
    * FreeLibrary (unloads the library)

    These steps are invalid for a .Net COM dll. .Net DLLs do not implement the DllRegisterServer function and are registered with the system in another way (using RegAsm.exe).

    I understand why DMXControl is performing these functions. DMXControl wants to make it very easy for users to 'install' new plugins by simply copying them into the 'Plugins' folder. But all COM objects need to be registered. DMXControl is executing these steps to perform registration automatically instead of having to require an installation program for every plugin. But there is a problem with the way this is implemented.

    It appears these steps (including DllRegisterServer) are being called every time a plugin is loaded. DllRegisterServer is only supposed to be called once in the lifetime of a COM object and this happens at installation. In my humble opinion, DMXControl should first try to load the plugin and only if it cannot be created should DMXControl try to register it. This way, .Net plugins could be manually registered using RegAsm.exe and DMXControl could still use them.

    Now I've spent a bunch of time trying to understand if the rest of the DMXControl process will work correctly or not. Honestly, I'm not sure. I don't know if TypeLibInfoFromFile will work on .Net assemblies or not. I think it will, but I'm not sure.

    Now I don't fully understand everything going on, but it seems DMXControl may be doing more work than it needs to when loading plugins. Many people that use COM in C++ use smart pointers and ProgIDs. This simplifies the code immensely and it also offloads more of the initialization process to the framework. For example, if you know the plugin-specific ProgID (like "DMXNet.OutputPlugin"), you can load the plugin like this:

    Code
    CComQIPtr<IDMXCPlugin, &__uuidof(IDMXCPlugin)> ptr;hr = ptr.CoCreateInstance (L[B]"DMXNet.OutputPlugin"[/B]);

    Those two lines of code are all you need! If hr != HR_FAIL then your plugin is loaded and you've alreay got access to the IDMXCPlugin interface. No messy LoadLibrary calls or QueryInterface code. If you know the ProgID you don't even need to enumerate the DLL for classes. If you don't, you can still enumerate the DLL.

    If you want to know more about Smart Pointers, these may help:

    CComPtr and CComIQPtr

    CComPtr on MSDN


    Now, finally, let's talk about this in .Net. In DMXControl 3.0, this process changes quite a bit but it should still seem familliar.

    Code
    // First, get a list of all plugins in the directory:string[] pluginPaths = Directory.GetFiles("Plugins");// Next loop through every plugin path and try to load itforeach (string pluginPath in pluginPaths){	// Load the Assembly and enumerate types	Assembly asm = Assembly.LoadFrom(pluginPath);	// Now, check every type inside the assembly	foreach (Type type in asm.GetTypes())	{		// If the type is a pluging, create it and use it		if (typeof(IDMXCPlugin).IsAssignableFrom(type))		{			// Create an instance of the plugin			IDMXCPlugin plugin = (IDMXCPlugin)Activator.CreateInstance(type);			// TODO: Do something with the plugin			// plugin.Initialize(...);		}	}}

    In .Net, you can still easily load and instantiate COM objects using their ProgID. So it's theoreitcally possible that you could still support and load classic DMXControl plugins. However, DMXControl doesn't seem to use ProgIDs (as mentioned above). I'm not sure how easy this would be to do in .Net without ProgIDs, but here's how you'd do it WITH ProgIDs:

    Code
    // Get a .Net Type that represents the COM object
    Type pluginType = Type.GetTypeFromProgID("MyPlugin.OutputPlugin");
    
    
    // Create an instance of the COM plugin
    IDMXCPlugin plugin = (IDMXCPlugin)Activator.CreateInstance(pluginType)
    
    
    // TODO: Do something with the plugin
    // plugin.Initialize(...)

    For more info on loading COM objects in .Net by ProgId, see:

    Create COM Object by ProgID

    That was a long post! I hope it helps explain the incompatibilities and maybe even helps with some of the planning for DMXControl 3.0.

    Finally, I saw this post a year ago in January 2008. It said 3.0 was already under development. So is 3.0 still another year away? Like January 2010?

    Thanks

  • Quote

    Original von eXntrc
    It appears these steps (including DllRegisterServer) are being called every time a plugin is loaded. DllRegisterServer is only supposed to be called once in the lifetime of a COM object and this happens at installation. In my humble opinion, DMXControl should first try to load the plugin and only if it cannot be created should DMXControl try to register it. This way, .Net plugins could be manually registered using RegAsm.exe and DMXControl could still use them.


    DMXC registers plugins on each start because it unregisters them on each exit ;)

    Quote

    Original von eXntrc
    Now I've spent a bunch of time trying to understand if the rest of the DMXControl process will work correctly or not. Honestly, I'm not sure. I don't know if TypeLibInfoFromFile will work on .Net assemblies or not. I think it will, but I'm not sure.


    I know that someone was successfull writing an output plugin in .NET. But I do not have the sources or any clue how he did this. I can't even remember how the interface was called...

    Quote

    Original von eXntrc
    Those two lines of code are all you need! If hr != HR_FAIL then your plugin is loaded and you've alreay got access to the IDMXCPlugin interface. No messy LoadLibrary calls or QueryInterface code. If you know the ProgID you don't even need to enumerate the DLL for classes. If you don't, you can still enumerate the DLL.


    Thank you, but I can not use this because DMXControl is written in Visual Basic - where Pointers do not even exist! :D So I have to stick with what I have...

    Quote

    Original von eXntrc
    Finally, I saw this post a year ago in January 2008. It said 3.0 was already under development. So is 3.0 still another year away? Like January 2010?


    Yes, DMXC 3.0 is still in an early development phase. As it is rewritten from scratch with many, many new features in mind and a great flexibility in the "kernel", it will take the few developers working on it in their spare time some more time until there will be a first test release. But the 2.x-line of DMXC will be maintained during that time (by me).

    Stefan

  • Quote

    Thank you, but I can not use this because DMXControl is written in Visual Basic - where Pointers do not even exist! So I have to stick with what I have...

    Ahhhh. I see. I thought it was written in C++. I guess you're calling LoadLibrary, GetProcAddress via extern Lib calls.

    Quote

    I know that someone was successfull writing an output plugin in .NET. But I do not have the sources or any clue how he did this. I can't even remember how the interface was called...

    Can you help me find any information about this at all? Where could I look to find out how this was done?

  • Newly created posts will remain inaccessible for others until approved by a moderator. The last reply was more than 365 days ago, this thread is most likely obsolete. It is recommended to create a new thread instead.