It is currently April 27th, 2024, 12:06 am

Alternative .NET Plugin Templates for C#, VB, F# and VC++

Share and get help with Plugins and Addons
Naiqet
Posts: 3
Joined: January 19th, 2014, 4:52 pm

Alternative .NET Plugin Templates for C#, VB, F# and VC++

Post by Naiqet »

Hello everyone,

I would like to share with you a modified version of the already available .NET plugin template. I tried not to stray too much from the original, but focused mainly on interop parts that I thought could be improved. The main difference of my approach is that no IL hacking using DllExporter is required while the final output is still only a single DLL. In addition, I have written versions of the template in 3 more .NET languages for people who would prefer to write code in them. Finally, I have also included an example C# plugin called WebReader, which was written using the template.

I hope this will be useful to some of you. Write here or send me a message if you find anything wrong with the code.

Edit: Added API instantiation to Reload method.
You do not have the required permissions to view the files attached to this post.
Last edited by Naiqet on January 23rd, 2014, 7:33 pm, edited 2 times in total.
User avatar
Aragas
Posts: 64
Joined: December 24th, 2012, 6:56 pm

Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+

Post by Aragas »

Awesome!
But, you have some problems with DynVar. Have fixed it.
https://github.com/Aragas/Rainmeter-NET-Plugin
Have already implemented in one of my plugins! Works perfect!
No more .NET 2.0 restriction. Hehehe. And working much faster.

UPDATE:
I find strange this code, why you use here ref and rewrite data?

Code: Select all

public static void Initialize(ref IntPtr data, IntPtr rm)
        {
            data = GCHandle.ToIntPtr(GCHandle.Alloc(new Measure(new API(rm))));
        }
poiru
Developer
Posts: 2872
Joined: April 17th, 2009, 12:18 pm

Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+

Post by poiru »

Thanks! I'll integrate some of your improvements into the official SDK. (If you'd like the commits assigned to you, please let me know what name and email you want to use for them.)
Naiqet wrote:The main difference of my approach is that no IL hacking using DllExporter is required while the final output is still only a single DLL.
While DllExporter is definitely ugly, it does result in binaries that are considerably smaller (7kB vs. 59kB for the Empty plugin). More importantly, your C++ CLR wrapper plugin results in a dependency on the VC++ CRT DLL (e.g. MSVCR120.dll), which means that the user will need to have the correct VC++ runtime installed on their system for the plugin to function (the Rainmeter installer only includes the runtime version used by Rainmeter itself). For that reason, I don't think this is a particularly good idea.
Aragas wrote:No more .NET 2.0 restriction. Hehehe. And working much faster.
The Rainmeter installer only ensures that .NET 2.0 is present on the system. If you use features in later versions of .NET, it is your responsibility to inform the user about the higher .NET version requirement.

(FWIW, you can definitely use later versions of .NET the current plugin SDK as well. You simply need to change the target framework in the project properites.)
User avatar
Aragas
Posts: 64
Joined: December 24th, 2012, 6:56 pm

Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+

Post by Aragas »

Yes. I know about .NET 4.0 warning.

Some bad news - using second plugin with this wrapper cause unstable work. My first plugin (that uses new wrapper too) just grab data from my second, lol.
And i have problem with using external .dll - i can't import it anymore in any way.

UPDATE:
Hm. Nope. Updating .NET version cause error by Rainmeter.
poiru
Developer
Posts: 2872
Joined: April 17th, 2009, 12:18 pm

Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+

Post by poiru »

Aragas wrote:Hm. Nope. Updating .NET version cause error by Rainmeter.
Are you referring to the current SDK? If so, it works fine for me with .NET 4.0. If possible, can you upload your project so I can take a look?
Naiqet
Posts: 3
Joined: January 19th, 2014, 4:52 pm

Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+

Post by Naiqet »

Poiru, you're right about the VC++ runtime dependency. If you want to integrate some of the implementation to official SDK, go for it. You don't need to assign the commits to me.

Aragas, as you can see in WebReader plugin sample, I use my wrapper, but I am still able to support dynamic variables. The following code

Code: Select all

public static void Initialize(ref IntPtr data, IntPtr rm)
{
     data = GCHandle.ToIntPtr(GCHandle.Alloc(new Measure(new API(rm))));
}
does the same thing the existing unmanaged C++ template does. It creates an instance of a Measure, gets unmanaged pointer to it, and stores it in data. In other callbacks such as Reload and Update the stored pointer is passed back, which is then used to access the Measure instance. This avoids the need to manually perform a generic dictionary lookup every time an interface function is invoked. If you have problems running some plugin with my wrapper, could you link me to it? I would be happy to look at it.
User avatar
Aragas
Posts: 64
Joined: December 24th, 2012, 6:56 pm

Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+

Post by Aragas »

Naiqet wrote:Aragas, as you can see in WebReader plugin sample, I use my wrapper, but I am still able to support dynamic variables. The following code

Code: Select all

public static void Initialize(ref IntPtr data, IntPtr rm)
{
     data = GCHandle.ToIntPtr(GCHandle.Alloc(new Measure(new API(rm))));
}
does the same thing the existing unmanaged C++ template does. It creates an instance of a Measure, gets unmanaged pointer to it, and stores it in data. In other callbacks such as Reload and Update the stored pointer is passed back, which is then used to access the Measure instance. This avoids the need to manually perform a generic dictionary lookup every time an interface function is invoked. If you have problems running some plugin with my wrapper, could you link me to it? I would be happy to look at it.
You make Rainmeter API global, what is not the best idea. Especially if you use multiple skins with one plugin. It is better to use in in Reload(API api). We can't know if Reload() func can be called in wrong order - than the return string/double can be wrong.
I think the best way here is to restore old-style Plugin class. I'll make some test later to see if it is a good idea.
poiru wrote: Are you referring to the current SDK? If so, it works fine for me with .NET 4.0. If possible, can you upload your project so I can take a look?
Maybe i'm wrong. Need to check that.
poiru
Developer
Posts: 2872
Joined: April 17th, 2009, 12:18 pm

Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+

Post by poiru »

The C# plugin SDK has been updated to incorporate most of the change here (excluding the use of a C++ CLR wrapper plugin): https://github.com/rainmeter/rainmeter-plugin-sdk

I'll try to get the VB/F# stuff there later on.

Thanks again Naiqet!
User avatar
Aragas
Posts: 64
Joined: December 24th, 2012, 6:56 pm

Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+

Post by Aragas »

Sorry, .NET 4.0 works.
Now i have a big trouble - i'm trying to load .dll from my skin path (e.g. Skins\VKPlayer\NAudio.dll), but i receive a error KERNELBASE.dll - Cannot load type from "Plugin.Plugin". Nevermind.
Could anyone show me how to right load a .dll from any path? :sly:


My previous methods don't work for some reason. If anyone want to see my "koolcode", see https://github.com/Aragas/VKPlugin_V2/tree/unstable-new-wrapper
Skins are here (use VKPlayer) https://github.com/Aragas/VKPlugin_V2/tree/unstable-new-wrapper/Rainmeter%20Sample
poiru
Developer
Posts: 2872
Joined: April 17th, 2009, 12:18 pm

Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+

Post by poiru »

Aragas wrote:Now i have a big trouble - i'm trying to load .dll from my skin path (e.g. Skins\VKPlayer\NAudio.dll), but i receive a error KERNELBASE.dll - Cannot load type from "Plugin.Plugin". Nevermind.
Could anyone show me how to right load a .dll from any path? :sly:
Is this specific to the updated SDK or did you have this issue with the old SDK as well?