Jump to content

Rules for plugins that are published on this forum


Recommended Posts

Plugins can do many things, especially given the creativity of some of our authors here :) However, there are some things that plugins should not do. For some of these rules, if you break them then you are simply not guaranteed that your plugin will work in any future version of Paint.NET. For others, your plugin may be removed from the forum if you break the rule. Just because something is possible does not mean it is okay.

This list may be amended in the future as I find and/or document other best practices, guidelines, and rules. Some rules will become moot for various reasons: new plugin types will be introduced, or runtime measures will block certain "bad" behavior (e.g. for effects, the source surface will be write-protected in v3.5).

If a rule uses the word "must", then your plugin will be removed for breaking the rule. If you are just developing something for your own personal use, feel free to break whatever "rules" you want.

If a rule uses the word "should", then your plugin may break in future versions of Paint.NET. No attempt at compatibility will be maintained, even for very popular plugins. You have been warned, in other words!

Effect plugins must follow "the rules."
This means, no writing to the source surface. No writing to the destination surface except where indicated by "rois" (region of interest). Rendering must only happen in the Effect's Render/OnRender methods, and not in the EffectConfigDialog or EffectConfigToken implementations.

Plugins may not require the installation of any "beta" software components
This includes beta or "CTP" versions of the .NET Framework, and even Paint.NET itself. However, feel free to publish these in the "Plugin Developer's Central" section.

 

Plugins may not require installing/using an older version of Paint.NET
When a new plugin or a new plugin update is published, it must work on the latest public/stable release of Paint.NET. 

 

Plugins may not require adding any files to the main application directory

For earlier versions of Paint.NET (pre-4.3), this was sometimes a hack to get certain shared libraries or other things to work. This is no longer necessary, and any plugin that has instructions or requirements like this will be deleted from the forum and blocked in the next app update. Effects go into Effects, FileTypes go into FileTypes. With 4.3+ you can now place the plugin into its own directory, along with dependencies, and they will be loaded privately for your plugin (in an AssemblyLoadContext).

 

Plugins must not do discovery and loading of other plugins

If you enumerate the DLLs in the plugin directories and load them (e.g. via Assembly.Load*()), you will cause problems and your plugin will definitely be blocked / removed. Instead, use the IEffectsService or IFileTypesService to retrieve the list of effects or file types. These are available via this.Services.GetService<T>() (for effects) or with the IServiceProvider you receive when implementing IFileTypeFactory2 (for file types).

 

Plugins must not hook global events for Assembly loading, e.g. AppDomain.AssemblyResolve

This causes all sorts of problems. Do not do this. Your plugin will be deleted from the forum and blocked in the next app update.

FileType plugins must not masquerade as "export" plugins. Nor must they have other "side effects."
A plugin for "export to photobucket" would be completely inappropriate, for instance. The user experience would be completely inappropriate: the user would asked to choose a file, and then your UI would upload the file somewhere, and then the user would have a 0-byte file on their disk because you ignored the Stream object that Paint.NET handed to you. These types of plugins will be deleted.

FileType plugins must always use the Stream they are given.
You may not assume that the Stream is any particular type, e.g. FileStream, which would give you additional information (such as the file name or path). It may be a FileStream, or a MemoryStream, or a SiphonStream, or a GuardedStream, or even something determined at runtime for any number of reasons. For instance, in a recent update I had to add the "GuardedStream" to work around some bugs in GDI+ that caused Paint.NET to think the file was saved correctly, when in fact it was totally corrupted.

Plugins must not use "reflection" to try and "hack" Paint.NET.
For example, using some of the stuff in System.Reflection, you could potentially add stuff to the File menu, or create new toolbar items. Or even new tools. Don't do this.

 

Plugins must not use reflection to reach into Paint.NET's internals.

If something is private or internal, then it's off-limits. Do not use reflection to reach in to get access. This includes instantiating classes, accessing private fields, etc.
(NOTE: Just because something is "public" does not mean it is okay to use.)

 

Plugins must not modify the Paint.NET user interface.
There are non-Reflection methods for doing this. Plugins are not allowed to modify Paint.NET's UI in any way such as by adding menu commands, etc.

 

Plugins with dependencies (shared DLLs) must have a .deps.json and go into their own directory

Starting with PDN 4.3 and .NET 5, plugins can be packaged into their own sub-directory (within Effects or FileTypes), with private dependencies, even if those dependencies are the same name as dependencies that other plugins have (but possibly different versions). Include the .deps.json file, which VS should automatically generate, which will instruct the assembly loader about your dependencies so they can be loaded correctly.

 

Plugins should not use C++/CLI
Assemblies compiled using C++/CLI are what's called "mixed-mode", as they contain managed and native code. This used to be the only reasonable way to interoperate with certain types of native code. Nowadays there are better ways to do that. Moreover, mixed-mode assemblies present problems with CPU architecture flexibility (can't run on CPU types you didn't compile for), load-time restrictions, and the fact that the language is basically abandoned and deprecated. Newer versions of C# can do everything C++/CLI did, although sometimes still not as conveniently, but it's pretty close now. For interoperating with Win32 APIs, I recommend importing TerraFX.Interop, which is as close as you can get to #include <windows.h>, and does everything in a performance-maximized manner. Bundle the DLL, include a YourDllName.deps.json, and put the whole thing in its own sub-directory within Effects or FileTypes.


Plugins must not use the PdnResources or PdnInfo classes.
The text and images that Paint.NET uses for its own user interface are not for plugins. Strings are not guaranteed to have the same text between versions, or to even exist. Same with images. If you want to take advantage of the localized text for effect submenus such as Artistic, Blurs, Distort, etc. then please use the static SubmenuNames class.

I have changed this rule from "should" to "must." In 4.0, these classes are now marked as 'internal' and it will not be possible for plugins to use them. If your plugin has been using these, please make sure that your next update does not. If you need functionality from the PaintDotNet.Resources DLL, please ask and I will decide if it is worth making something available in one of the other DLLs (Base, Core, Data, Effects).

Plugins must not use UI controls from PaintDotNet.Core.dll, PaintDotNet.Data.dll, or PaintDotNet.Framework.dll.
This includes classes such as DocumentView, ImageListMenu, SurfaceBox, and TaskDialog. These should be treated as "internal" to Paint.NET. As time goes on, I've been moving this into PaintDotNet.exe or marking them as private/internal, so that it will not be possible to accidentally do this.

I have changed this from from "should" to "must". There have been many changes in 4.0 as to how these are organized, and any plugins which are using these controls will likely not work. Please make sure your next plugin update takes that into account. If there is a control that you are using that you need, please ask. I can probably just give you a copy of its source code.

Plugins must not use the built-in FileTypes in PaintDotNet.Data.dll
In 4.0, these have been moved into PaintDotNet.exe and are 'internal'. So, your plugin will break.

Plugins must not require replacing any of the Paint.NET DLL or EXE files.
In other words, a user should not have to install a modified version of Paint.NET in order to use your plugin. This will really put the user in a bad situation when they go to install the next update.

Plugins should not use anything from the SystemLayer DLL.
This DLL is very much subject to change for all sorts of reasons. It is not a utility library for plugins to use. If there is functionality on SystemLayer that your plugin would benefit from, or even require, then please ask for it and I will see about making something available in PaintDotNet.Base, Core, Data, or Effects.

Plugins should try to avoid using the "Utility" class.
This has been deprecated in 4.0. Some of the functionality was moved into various other utility classes, e.g. RectangleUtil, and a whole bunch was just removed.


Things which are allowed

Effect plugins may use the built-in Effects in PaintDotNet.Effects.dll

I've decided to officially keep the programmatic interface for these backwards-compatible. If there are changes that I must make, and there are plugins using what is changing, then I will find a way to preserve backwards compatibility.


All that said, if you are just playing with plugins for your own private use, then feel free to do whatever you want!

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

  • 3 weeks later...
Plugins must not use "reflection" to try and "hack" Paint.NET.

For example, using some of the stuff in System.Reflection, you could potentially add stuff to the File menu, or create new toolbar items. Or even new tools. Don't do this.

you just told people how to do it?

|my myspace|----------------|my site|---------------|my gallery|

firetext.png

Link to comment
Share on other sites

Plugins must not use "reflection" to try and "hack" Paint.NET.

For example, using some of the stuff in System.Reflection, you could potentially add stuff to the File menu, or create new toolbar items. Or even new tools. Don't do this.

you just told people how to do it?

It's not like it's some magical secret.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

  • 1 month later...
  • 3 months later...

I'm not sure I follow you ... can you be more specific?

My comment mostly refers to not using the facilities in PaintDotNet.Data for file type plugin discovery. That code is subject to change, and is not for plugins (effect plugins, that is).

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

  • 2 years later...
  • 3 weeks later...

Is it permissible for an Effects plugin to change the contents of the clipboard?

If not what is the recommended way to handle an effect where the output is larger or smaller than the input? (for instance, pixel art scaling algorithms or seam carving)

Link to comment
Share on other sites

The effect system is design to handle a mathematical mapping of (input bitmap, properties) -> (output bitmap). No size changes. What you want to do is not appropriate for an effect, and thus question of "is it okay to use the clipboard" is really beside the point. What you need is another type of plugin, which Paint.NET v3.5.x doesn't support.

Basically, whether it's "okay" to use the clipboard depends on whether that makes sense for your plugin in the first place. There are some plugins that read from the clipboard and that's perfectly fine. I haven't seen any that write to it, but in principle, it's not something that Paint.NET owns in the first place so it's not really up to its judgment (or rather, my judgment).

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...