Menu

GetMenuItem plgx backwards compatibility

Luckyrat
2019-04-04
2019-04-06
  • Luckyrat

    Luckyrat - 2019-04-04

    I'm looking at using the new GetMenuItem method API for KeePass 2.41+

    I want this to work in a plgx file that can load in older KeePass versions (at least back to 2.34 but I suspect the exact version isn't relevent).

    Ideas so far include:

    1) Defining the override method using Reflection, after establishing that the method exists on the Plugin base class.
    2) Using a #if conditional compilation flag so that the method is only included (and existing fallback code is not) if the plgx is being compiled inside KeePass 2.41+

    I'm not sure (1) can be done but it looks like if it's possible it will require writing raw IL to implement the method. I'm not all that keen on exploring that rabbit hole.

    I don't know of any way to target specific KeePass versions with flags for idea (2). Is there a way?

    Anyone have any further ideas or should I park this idea until I no longer need to support versions older than 2.41?

    Thanks,
    Chris

     
  • Dominik Reichl

    Dominik Reichl - 2019-04-04

    1) I don't know whether this is possible.
    2) There is no symbol that you could use for testing the version. Such an approach would be impractical, as in C# a symbol may only be defined or not, i.e. symbols cannot have values that could be used in a comparison. Defining symbols like 'KeePass_2_0' to 'KeePass_2_41' doesn't really make sense.

    PLGX files support pre-build command lines. You could write a small helper program that detects the KeePass version (by querying the file version information of the currently running KeePass process) and replaces certain source code files of your plugin depending on the version.

    Alternatively, simply recommend users to update to the latest KeePass version...

    Best regards,
    Dominik

     
    ❤️
    1
  • AlexVallat

    AlexVallat - 2019-04-05

    If you were to go the symbol-definition route, can I suggest defining symbols based on capabilities rather than version numbers? So a KeePass_GetMenuItem symbol, a KeePass_HotKeyControlEx2 symbol, and so on. If a version makes no breaking changes, it needs no symbol defined. If there are breaking changes in a version (such that implmementing them would cause a plugin to be unloadable on a previous version), a symbol is defined for each breaking change that a plugin may want to use.

     
  • Dominik Reichl

    Dominik Reichl - 2019-04-05

    Almost every KeePass release has changes to public classes/methods. Defining symbols for all such changes is even less feasible than symbols for each version.

    Best regards,
    Dominik

     
  • Rookiestyle

    Rookiestyle - 2019-04-05

    Defining symbols like "KeePass 2.0 to 2.4" indeed don't make sense. Would it be an option to always add the current version's symbol instead of changing them?
    E. g. for the current version these symbols would be defined:

    #define KP_2_4_1
    #define KP_2_4_0
    #define KP_2_3_9
    ...
    

    Once 2.4.2 is released it will additionally define symbol KP_2_4_2.
    Maintenance effort from KeePass development perspective shouldn't be that much.
    To be honest... I don't know a way to make the CSharpCodeProvider aware of the symbols defined in KeePass beside adding them to the compileroptions which would mean you wouldn' need to define them as symbols in KeePass at all

     plgx.CompilerParameters.CompilerOptions = "/d:KP_2_3_9;KP_2_4_0;KP_2_4_1";
    

    In most cases it would be sufficient to simply check for one symbol but one could do pretty complex checks as well

    #if KP_2_3_9 - all versions >= 2.3.9
    #if KP_2_3_9 && !KP_2_4_1 - only versions 2.3.9 and 2.4.0
    #if (KP_2_3_9 && !KP_2_4_0) || KP_2_4_1 - only versions 2.3.9 or 2.4.1 and higer, 2.4.0 is excluded
    

    On the other side: Upgrading to the newest KeePass version is not a bad idea either :)

     
  • Dominik Reichl

    Dominik Reichl - 2019-04-05

    I don't think that defining such symbols is a good solution.

    Anyway, as it has been requested a few times, I've now added a version symbol. When compiling a PLGX, KeePass defines 'KP_V_*_*_*', where the asterisks specify the version (first three components, decimal).

    Here's the latest development snapshot for testing:
    https://keepass.info/filepool/KeePass_190405.zip

    In the development snapshot, the version is set to 2.41, i.e. 'KP_V_2_41_0' is defined. The next stable release will be 2.42, i.e. 'KP_V_2_42_0' will be defined.

    Best regards,
    Dominik

     
  • Dominik Reichl

    Dominik Reichl - 2019-04-05

    KeePass defines only one symbol, for the current version. Additionally defining symbols for previous versions would be problematic when a new version removes a class/method that was available in earlier versions.

    Best regards,
    Dominik

     
    • AlexVallat

      AlexVallat - 2019-04-05

      OK, so what's the intended usage pattern? Let's say we want to gate usage of GetMenuItem to be 2.41 or greater. If I check for KP_V_2_41 then it won't work with 2.42, right? So all plugins that make use of the symbols have to release a new version every time there's a new KeePass version, whether or not any compatibility changes are needed?

      From a plugin perspective, all I want to know is whether I need to include shim code for older versions or not. So if KP_V_2_41 is not defined, I need to add my menu item manually, and not override GetMenuItem. If, in version 2.42 you then decide to rename it to GetMenuItemEx then that's a breaking change, sure, but that's nothing new. Whether the plugin used symbols or not it would still break.

      If you add all version symbols then it means that it keeps the same behaviour of optimistically hoping that a plugin will continue to work with the new version without needing a mandatory new release.

       
  • Dominik Reichl

    Dominik Reichl - 2019-04-05

    If you want to be optimistic, you could check for 'KP_V_2_42_0', 'KP_V_2_42_1', 'KP_V_2_43_0', 'KP_V_2_43_1', 'KP_V_2_44_0', 'KP_V_2_44_1', and so on.

    I don't like the approach of using symbols for version detection. My recommendation would be to focus on the latest KeePass version and tell users to upgrade to it.

    Best regards,
    Dominik

     
  • AlexVallat

    AlexVallat - 2019-04-06

    OK, well just FYI I won't be using the symbols. If it doesn't stay defined in future versions, it's not helpful, and I'll be sticking with the "bump the major version number and announce breaking compatibility with older KeePass versions" scheme instead.

     

Log in to post a comment.