Home

Awesome

PLGX Build Tasks

The MSBuild task in this package uses build items, item metadata and a "clean room" implementation of the KeePass 2.x archive creation utility to generate .PLGX files as a plugin project's build product. This was inspired by and partially mimics the KeePassPluginDevTools package, a.k.a. PlgxTool.

So....why?? Primarily for development flexibility. While the strict coding requirements for KeePass plugins are well defined, new build environments such as the dotnet CLI are welcome changes to old-school .NET development. Also, by fully integrating .PLGX production within MSBuild, new features leveraging intermediate build products are achievable, such as localization resource deployment.

The hope is to encourage new plugin development, and help existing plugin authors migrate to new, perhaps improved tooling.


Requirements

The software has been tested thoroughly with Visual Studio 2019 Community, and .NET 5 development tools, with net472 and net45 TFMs. And only on Windows.

Background

.PLGX files are an installation media file format often distributed by plugin providers as recommended by KeePass. Traditionally, .PLGX archives contain the source code files of the plugin, optional WinForms-based resources, non-framework assembly dependencies, and a copy of the plugin's ".csproj" project file. When KeePass loads a new plugin, it extracts the contents of the .PLGX archive, reads select portions of its project file, and invokes the installation target's .NET Framework C# compiler to create and install the plugin assembly. This is done "on the fly", usually without user intervention. Ostensibly, this convention ensures that the plugin is compliant with the interface and runtime characteristics of the installed version of KeePass. Further, the scheme allows KeePass to maintain control of a central "cache" of plugins installed on the target machine.

Today, KeePass users benefit from a large collection of useful plugins. But while the KeePass v2 plugin interface and the .NET Framework are both now quite mature, with only infrequent and compatibility-conscious changes, .PLGX archive distribution remains a well established regimen within the plugin community.

Unique Features of This Tool

PlgxTool Compatible Features

PlgxTool Incompatibility

Limitation

These packages can allow projects targeting older .NET frameworks access to features available in newer .NET frameworks. One example is System.Runtime.InteropServices.RuntimeInformation. The types in this package are provided by mscorlib.dll, etc., in .NET 4.7.1 and newer frameworks. By referencing the NuGet package, projects targeting frameworks as old as .NET 4.5 may also access those types. Unfortunately, this technique won't work for PLGX builds run by KeePass, unless the target machine is actually running an older framework. Machines running .NET 4.7.1 or later will fail to install the plugin via PLGX, due to the collision of types in System.Runtime.InteropServices.RuntimeInformation and mscorlib.

Hint: When PLGX builds fail, use the -debug option of KeePass.exe to see compiler error output.

KeePass doesn't currently provide a way to control how these supplemental references are compiled into the plugin (like MSBuild does, for example). The only workaround for this issue is to avoid referencing such packages.

Project TODOs

Quick Start

  1. Add the NuGet package reference to a plugin project using a NuGet package management tool of choice (too many to list here).

  2. Run a release build of the project. If all requirements are met, a distributable .PLGX file should be copied to the output directory. To customize the build, read on.

Likely Next Steps

  1. By default, the GeneratePlgx property is set to create the .PLGX file after a successful release build, precisely as shown below. Optionally modify the GeneratePlgx property in your project file if desired. When set true, the PlgxBuild task is run after a successful build.
  <PropertyGroup Condition=" '$(GeneratePlgx)' == '' and '$(Configuration)' == 'Release' ">
    <GeneratePlgx>true</GeneratePlgx>
  </PropertyGroup>
  1. To exclude project items from the .PLGX, such as certain <None> or <Content> files, use the <ExcludeFromPlgx> metadata tag in the XML content of the item. For example:
  <None Include="MyTemplate.tt">
      <Generator>TextTemplatingFileGenerator</Generator>
      <LastGenOutput>MyTemplate.cs</LastGenOutput>
      <Visible>true</Visible>
      <ExcludeFromPlgx/>
  </None>
  1. Optionally configure customizations with property extensions. For example, alter the output path of the .PLGX file:
  <PropertyGroup>
    <PlgxArchiveFileName>$(MyAssemblyName)-$(MyVersion)</PlgxArchiveFileName>
    <PlgxOutputFolder>bin\$(Configuration)\plgx\</PlgxOutputFolder>
  </PropertyGroup>

Properties

Use the following MSBuild property extensions to set various options, including those that configure the way KeePass prepares the plugin for loading. Some of these correspond to options specified in the <PlgxConfiguration> property used by PlgxTool. In particular, the properties named PlgxTarget* correspond to manifest options in the .PLGX archive.

Specify these properties within a <PropertyGroup> element of your project file to override the default values shown in the table.

PropertyDefault valueDescription
PlgxArchiveFileNameBase name of the plugin assembly, for example MyPlugin.The name of the output .PLGX file, specified as a base file name (without the .PLGX extension).
PlgxOutputFolderThe project output folder, $(OutputPath).The directory where the output .PLGX file will be placed. Must be specified as a partial path relative to the project file directory, e.g., "bin\$(Configuration)\plgx\".
PlgxTargetKpVersionNo default.Optional. If specified, sets the --plgx-prereq-kp option to declare the "minimum" KeePass version supported by the plugin. KeePass only recognizes release numbers given in simple, dotted notation, e.g., "2.09".
PlgxTargetNetFrameworkThe project target framework, $(TargetFrameworkVersion).Sets the --plgx-prereq-net option to declare the .NET Framework version requirements of the plugin. Valid values are dotted notation .NET Framework version numbers with no prefix. For example, "4.5" or "4.7.2". Set this property to an empty string to omit --plgx-prereq-net from the .PLGX manifest.
PlgxTargetOsWindowsSets the --plgx-prereq-os option to declare the operating system required by the plugin. KeePass recognizes only two values: Unix, and Windows. Set this property to an empty string to omit --plgx-prereq-os from the .PLGX manifest.
PlgxTargetPtrSizeNo default.Optional. If specified, sets the --plgx-prereq-ptr option to declare the pointer size (platform architecture) required by the plugin. Valid values are 4 and 8.
PlgxUseCompiledResourcefalseIf set true, .RESOURCE files created by MSBuild are archived, rather than the <EmbeddedResource> .RESX source files from which they derive. This improves initialization performance and usually reduces .PLGX file size. If false, .RESX source files are archived instead. Recommended: if set to true, use the default value of the PlgxTargetNetFramework property, to allow KeePass to determine if the target platform is compatible with the archived .RESOURCE files.
PlgxReferencesArchivedFolderName___PLGX_ReferencesDefines the name of the folder within the .PLGX archive where "copied", non-framework assembly dependencies, if any, reside.
PlgxSatelliteAssembliesArchivedFolderName___PLGX_SatellitesDefines the name of the folder within the .PLGX archive where resource-only satellite assemblies, if any, reside.