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.
It is currently April 27th, 2024, 12:06 am
Alternative .NET Plugin Templates for C#, VB, F# and VC++
-
- Posts: 3
- Joined: January 19th, 2014, 4:52 pm
Alternative .NET Plugin Templates for C#, VB, F# and VC++
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.
-
- Posts: 64
- Joined: December 24th, 2012, 6:56 pm
Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+
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?
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))));
}
-
- Developer
- Posts: 2872
- Joined: April 17th, 2009, 12:18 pm
Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+
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.)
(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.)
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.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.
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.Aragas wrote:No more .NET 2.0 restriction. Hehehe. And working much faster.
(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.)
-
- Posts: 64
- Joined: December 24th, 2012, 6:56 pm
Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+
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.
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.
-
- Developer
- Posts: 2872
- Joined: April 17th, 2009, 12:18 pm
Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+
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?Aragas wrote:Hm. Nope. Updating .NET version cause error by Rainmeter.
-
- Posts: 3
- Joined: January 19th, 2014, 4:52 pm
Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+
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
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.
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))));
}
-
- Posts: 64
- Joined: December 24th, 2012, 6:56 pm
Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+
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.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
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.Code: Select all
public static void Initialize(ref IntPtr data, IntPtr rm) { data = GCHandle.ToIntPtr(GCHandle.Alloc(new Measure(new API(rm)))); }
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.
Maybe i'm wrong. Need to check that.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?
-
- Developer
- Posts: 2872
- Joined: April 17th, 2009, 12:18 pm
Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+
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!
I'll try to get the VB/F# stuff there later on.
Thanks again Naiqet!
-
- Posts: 64
- Joined: December 24th, 2012, 6:56 pm
Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+
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?
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
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?
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
-
- Developer
- Posts: 2872
- Joined: April 17th, 2009, 12:18 pm
Re: Alternative .NET Plugin Templates for C#, VB, F# and VC+
Is this specific to the updated SDK or did you have this issue with the old SDK as well?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?