├── .gitignore ├── Build.bat ├── README.md ├── TrayRecentFiles.plgx ├── TrayRecentFiles.sln ├── TrayRecentFiles ├── Properties │ └── AssemblyInfo.cs ├── TrayRecentFiles.csproj └── TrayRecentFilesExt.cs ├── imgs ├── KeePassMainWindowOpenRecentFiles.png └── KeePassTrayIconOpenRecentFiles.png └── pluginVersion /.gitignore: -------------------------------------------------------------------------------- 1 | KeePass.exe 2 | *.suo -------------------------------------------------------------------------------- /Build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rmdir "..\TrayRecentFiles\obj" /S /Q 3 | rmdir "..\TrayRecentFiles\bin" /S /Q 4 | KeePass.exe --plgx-create "%~dp0TrayRecentFiles" 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KeePassTrayRecentFiles 2 | A KeePass plugin to list your recent files directly on your systray icon 3 | 4 | This plug-in will add the (exact) same "Open Recent" menu to your systray KeePass icon. 5 | 6 | I believe this is a very useful plugin for people who use more than one KeePass databases on a daily basis (such as me). 7 | 8 | ## Instalation 9 | As per [KeePass's documentation](http://keepass.info/help/v2/plugins.html), in order to **install** this plugin you should copy the [TrayRecentFiles.plgx](TrayRecentFiles.plgx) to your KeePass folder (usually %ProgramFiles% (x86)\KeePass Password Safe 2). 10 | 11 | #### Chocolatey 📦 12 | Or you can [use Chocolatey to install](https://community.chocolatey.org/packages/keepass-plugin-trayrecent#install) it in a more automated manner: 13 | 14 | ``` 15 | choco install keepass-plugin-trayrecent 16 | ``` 17 | 18 | To [upgrade KeePass Plugin KeePassTrayRecentFiles](https://community.chocolatey.org/packages/keepass-plugin-trayrecent#upgrade) to the [latest release version](https://community.chocolatey.org/packages/keepass-plugin-trayrecent#versionhistory) for enjoying the newest features, run the following command from the command line or from PowerShell: 19 | 20 | ``` 21 | choco upgrade keepass-plugin-trayrecent 22 | ``` 23 | 24 | ## Screenshots 25 | ![KeePassMainWindowOpenRecentFiles](imgs/KeePassMainWindowOpenRecentFiles.png) 26 | 27 | ![KeePassTrayIconOpenRecentFiles](imgs/KeePassTrayIconOpenRecentFiles.png) 28 | 29 | ## Notice 30 | When this plugin was developed, [KeePass](http://keepass.info/) was in version **2.29**. I have followed the [KeePass' recomendations](http://keepass.info/help/v2_dev/plg_index.html#plgx) and provided this plugin as a **PLGX** in order to be able to early detect any future breaking changes. 31 | 32 | ## Thank you 33 | It was a great pleasure to develop this plugin, I had already used KeePass' API, and it was a charm to develop. Having access to KeePass' source code and having already some experience with WinForms made this development relatively easy. 34 | 35 | ## Disclaimer 36 | This plugin is provided AS-IS. I tested it on my own machine, with some of the relevant KeePass' settings and it worked just fine, for my needs. The plugin's source code is available and any recommendation or change is more than welcome. 37 | -------------------------------------------------------------------------------- /TrayRecentFiles.plgx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdbeirao/KeePassTrayRecentFiles/3b8fbd09886a9da8187b036165afd48ec53f82a2/TrayRecentFiles.plgx -------------------------------------------------------------------------------- /TrayRecentFiles.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrayRecentFiles", "TrayRecentFiles\TrayRecentFiles.csproj", "{BD5528F6-3CA5-4D77-80CB-001AE812B46D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BD5528F6-3CA5-4D77-80CB-001AE812B46D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {BD5528F6-3CA5-4D77-80CB-001AE812B46D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {BD5528F6-3CA5-4D77-80CB-001AE812B46D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {BD5528F6-3CA5-4D77-80CB-001AE812B46D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /TrayRecentFiles/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("TrayRecentFiles")] 6 | [assembly: AssemblyDescription("Have your recent databases available from systray")] 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("Fábio Beirão")] 9 | [assembly: AssemblyProduct("KeePass Plugin")] 10 | [assembly: AssemblyCopyright("Copyright © 2015")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | 14 | [assembly: ComVisible(false)] 15 | 16 | [assembly: Guid("ed0352bf-0964-4114-a9a3-9cb15dc1a41f")] 17 | 18 | [assembly: AssemblyVersion("0.0.2")] 19 | [assembly: AssemblyFileVersion("0.0.2")] 20 | -------------------------------------------------------------------------------- /TrayRecentFiles/TrayRecentFiles.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {BD5528F6-3CA5-4D77-80CB-001AE812B46D} 8 | Library 9 | Properties 10 | TrayRecentFiles 11 | TrayRecentFiles 12 | v4.0 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\KeePass.exe 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 58 | -------------------------------------------------------------------------------- /TrayRecentFiles/TrayRecentFilesExt.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using KeePass.Plugins; 3 | using System.Diagnostics; 4 | using System.Windows.Forms; 5 | 6 | namespace TrayRecentFiles { 7 | public sealed class TrayRecentFilesExt : Plugin { 8 | private IPluginHost m_host = null; 9 | private int m_menuFileRecentPreviousIndex = -1; 10 | 11 | private ToolStripMenuItem m_menuFile; 12 | private ToolStripMenuItem m_menuFileRecent; 13 | 14 | public override bool Initialize(IPluginHost host) { 15 | if (host == null) 16 | return false; 17 | 18 | m_host = host; 19 | 20 | var mainWindow = m_host.MainWindow; // Alias for m_host.MainWindow 21 | if (mainWindow == null) return false; 22 | 23 | var mainMenu = mainWindow.MainMenu; // Alias for m_host.MainWindow.MainMenu 24 | if (mainMenu == null) return false; 25 | 26 | var trayContextMenu = mainWindow.TrayContextMenu; // Alias for m_host.MainWindow.TrayContextMenu 27 | if (trayContextMenu == null) return false; 28 | 29 | var menuFile = mainMenu.Items.Find("m_menuFile", searchAllChildren: false); 30 | if (menuFile == null || menuFile.Length != 1 || !(menuFile[0] is ToolStripMenuItem)) return false; 31 | m_menuFile = menuFile[0] as ToolStripMenuItem; 32 | 33 | var recentMenuFileRecent = mainMenu.Items.Find("m_menuFileRecent", searchAllChildren: true); 34 | if (recentMenuFileRecent == null || recentMenuFileRecent.Length != 1 || !(recentMenuFileRecent[0] is ToolStripMenuItem)) return false; 35 | 36 | m_menuFileRecent = recentMenuFileRecent[0] as ToolStripMenuItem; 37 | m_menuFileRecentPreviousIndex = mainMenu.Items.IndexOf(m_menuFileRecent); 38 | if (m_menuFileRecentPreviousIndex < 0) 39 | m_menuFileRecentPreviousIndex = 2; 40 | 41 | m_menuFile.DropDownOpening += m_menuFile_DropDownOpening; 42 | trayContextMenu.Opening += contextMenuStrip_Opening; 43 | m_menuFileRecent.DropDownOpening += m_menuFileRecent_DropDownOpening; 44 | 45 | return true; 46 | } 47 | 48 | void m_menuFile_DropDownOpening(object sender, System.EventArgs e) { 49 | if (m_host == null || m_host.MainWindow == null || m_menuFileRecent == null) 50 | return; 51 | 52 | // A ToolStripMenuItem can only be on one place at once 53 | // The user is opening the "File" menu on Main Window, we will place it there 54 | // (removing it from the systray context menu) 55 | 56 | if (m_menuFile.DropDownItems.Contains(m_menuFileRecent)) 57 | return; 58 | 59 | m_menuFile.DropDownItems.Insert(m_menuFileRecentPreviousIndex, m_menuFileRecent); 60 | } 61 | 62 | void contextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e) { 63 | if (m_host == null || m_host.MainWindow == null || m_menuFileRecent == null) 64 | return; 65 | 66 | // A ToolStripMenuItem can only be on one place at once 67 | // The user is opening the systray context menu, we will place it there 68 | // (removing it from the "File" menu on Main Window) 69 | 70 | var trayContextMenu = m_host.MainWindow.TrayContextMenu; 71 | if (trayContextMenu.Items.Contains(m_menuFileRecent)) 72 | return; 73 | 74 | trayContextMenu.Items.Insert(0, m_menuFileRecent); // On top seems to be as good a location as any other 75 | } 76 | 77 | void m_menuFileRecent_DropDownOpening(object sender, System.EventArgs e) { 78 | if (m_menuFileRecent == null) 79 | return; 80 | 81 | // After the user clicks any recent item, make sure the main window is visible 82 | foreach (var mnuItem in m_menuFileRecent.DropDownItems.OfType()) { 83 | mnuItem.Click -= EnsureMainWindowVisible; 84 | mnuItem.Click += EnsureMainWindowVisible; 85 | } 86 | } 87 | 88 | void EnsureMainWindowVisible(object sender, System.EventArgs e) { 89 | if (m_host != null && m_host.MainWindow != null) 90 | m_host.MainWindow.EnsureVisibleForegroundWindow(bUntray: true, bRestoreWindow: true); 91 | } 92 | 93 | public override void Terminate() { 94 | if (m_host != null) 95 | m_host.MainWindow.TrayContextMenu.Opening -= contextMenuStrip_Opening; 96 | 97 | if (m_menuFile != null) 98 | m_menuFile.DropDownOpening -= m_menuFile_DropDownOpening; 99 | 100 | if (m_menuFileRecent != null) 101 | foreach (ToolStripItem mnuItem in m_menuFileRecent.DropDownItems) 102 | mnuItem.Click -= EnsureMainWindowVisible; 103 | } 104 | 105 | public override string UpdateUrl { 106 | get { 107 | return @"https://raw.githubusercontent.com/fdbeirao/KeePassTrayRecentFiles/master/pluginVersion"; 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /imgs/KeePassMainWindowOpenRecentFiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdbeirao/KeePassTrayRecentFiles/3b8fbd09886a9da8187b036165afd48ec53f82a2/imgs/KeePassMainWindowOpenRecentFiles.png -------------------------------------------------------------------------------- /imgs/KeePassTrayIconOpenRecentFiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdbeirao/KeePassTrayRecentFiles/3b8fbd09886a9da8187b036165afd48ec53f82a2/imgs/KeePassTrayIconOpenRecentFiles.png -------------------------------------------------------------------------------- /pluginVersion: -------------------------------------------------------------------------------- 1 | : 2 | TrayRecentFiles:0.0.2 3 | : --------------------------------------------------------------------------------