You proved my point. Creating an #ifdef mess with polymorphism, virtual methods and indirection is the very definition of going out of one's way to support something that really doesn't need any support.
This is just part of the cost of developing cross-platform, and I'm sorry, but to me, dismissing this as 'going out of one's way' is just being sloppy.
I felt a great disturbance in the source, as if hundreds of BSD users suddenly cried out in terror and were suddenly silenced.
I initially did think of simply letting the build system handle it (CMake can do this excellently, as can Meson, probably) by simply choosing different source files for different target OSs, but when typing out the parent comment, I forgot about it in my train of thought.
Come to think of it, this is far more elegant.
As another sibling commenter wrote, .NET already has a platform-agnostic function to write to a `user program data` folder that nicely maps to the platform-specific directories. Other GC languages (Java, Go, etc) likely have similar abstractions.
As for scripting... A cross-platform project with scripts that also targets Windows should (in my opinion) have PowerShell `.ps1` scripts accompanying any `.sh` scripts. Better still, scripting should be done in a language that's truly platform-agnostic, like Python.