A plugin for FulDC++ that adds "Copy directories from this run" to the system log's right-click menu. It puts every directory from the last finished hashing run on the clipboard, one folder name per line, in log order.
See Read-me.txt for what it does and how it is used, and HASHRUN-BRIEF.md for the decisions the implementation is bound by.
The brief refers to an attached hashrun.cpp, a draft of the core logic. It is
in the first commit and nowhere else: everything in it has been rewritten and
split across src/, and three of its assumptions turned out to be wrong against
a real log — the phrases it matched on, its handling of a run still in progress,
and subclassing from the timer thread. Keeping a stale copy at the root only
invites someone to read it as source.
.\build.ps1
Finds Visual Studio through vswhere, configures CMake and builds
build\Release\HashRun-x64.dll. Needs the C++ desktop workload; nothing else.
.\pack.ps1
Packs the DLL, info.xml and Read-me.txt into HashRun.dcext, which installs
through Settings -> Plugins -> Add. It refuses to build the package unless the
version agrees across info.xml, res\HashRun.rc and src\Plugin.cpp.
src/Plugin.cpp plugin lifecycle, hook registration
src/SystemLog.* finds the log window, extends its menu, fills the clipboard
src/LogFile.* works out where the log is and reads the tail of it
src/LogParser.* pulls the run's directories out of the text
src/Settings.* the log path, the client's phrases, the menu wording
(Serialise/Deserialise are the file format, testable)
src/SettingsDialog.* the Configure dialog
src/Guard.* turns an exception at a callback boundary into a log line
src/TextFile.* UTF-8 file read and write
src/PluginDefs.h the DCAPI 8 header, taken from the client
res/HashRun.rc version resource and the dialog
test/main.cpp the parser, without a client
info.xml the .dcext manifest
LogParser touches nothing but strings, which is what lets the harness run it
against real logs:
.\build\Release\hashruntest.exe the checks
.\build\Release\hashruntest.exe <a system.log> what it makes of a real log
The second form is the one to reach for when a user reports an empty clipboard.
Asked for, not assumed. PluginDefs.h documents a magic guid, CoreSetup, that
reads the client's own settings, and that is the first thing tried. It has to
be: DC++ writes out only the settings that differ from their defaults, so a user
who has never moved the log directory has no line in the client's XML to read,
while the host still knows the effective value. After that come
PATH_USER_CONFIG and PATH_USER_LOCAL, each with Logs\ under it, and a
manual override in the settings wins over all of them.
The disk is never searched for *system.log. On the machine this was built
against that turns up AirDC++'s log and one belonging to Civilization VI.
The GUID lives in both info.xml and Plugin.cpp and nothing checks that the
two agree, so they are only ever changed together.
GPL v3. See LICENSE.