Here’s a focused audit of the attached files, highlighting key issues—especially around logging—and recommended changes:

  • Corrupted / duplicated code in plugin.cpp
    Starting inside PrintScreenLatentCallback the file abruptly re‑defines ValidatePath, TakeScreenshotLatent, PrintScreenImpl, etc., nested within another function. This not only causes unbalanced braces but will fail to compile.
    Fix: Remove the duplicated blocks so that each function is defined exactly once at the top level, and ensure all {} pairs in PrintScreenLatentCallback match up.

  • Missing SKSE plugin entry points and initialization
    I see no SKSEPlugin_Query or SKSEPlugin_Load in plugin.cpp, nor calls to SKSE::InitLogging, SKSE::InitPapyrus, or registration of your Papyrus functions. Without these, the DLL never gets “hooked” into SKSE and g_pluginHandle remains kInvalidPluginHandle.
    Fix: Implement the standard entry functions, capture and store the plugin handle, call SKSE::InitLogging(...), then register your Papyrus interface in SKSEPlugin_Load.

  • Linkage of spdlog sinks
    You include <spdlog/sinks/basic_file_sink.h> and <spdlog/sinks/rotating_file_sink.h> but CMake never finds or links spdlog.
    Fix: In CMakeLists.txt add:

    find_package(spdlog CONFIG REQUIRED) target_link_libraries(${PROJECT_NAME} PRIVATE spdlog::spdlog)

    This will resolve the spdlog symbols used in InitializeLogging().

  • Logger registration with spdlog
    You test spdlog::get("PrintScreen") but never explicitly register your new logger. While set_default_logger() makes it the global default, it’s safer to also call:

    spdlog::register_logger(log);

    immediately after creating log to guarantee spdlog::get("PrintScreen") returns your logger.

  • FallbackLog path handling

    GetTempPathA(MAX_PATH, tempPath);

    doesn’t check its return value; if the buffer is too small or fails, you’ll write to an uninitialized path.
    Fix: Capture the return, verify it’s ≤ MAX_PATH, and consider using std::filesystem::temp_directory_path() for a more robust fallback path.

  • Use SKSE’s built‑in logging API
    Instead of manually configuring spdlog, you can leverage SKSE’s helper macros: call SKSE::InitLogging(...) in your Query function, then use SKSE::log::info(), SKSE::log::error(), etc. This keeps your plugin consistent with other SKSE mods and avoids reinventing the sink setup.

  • Clean up unused includes
    You include both <spdlog/sinks/basic_file_sink.h> and <spdlog/sinks/rotating_file_sink.h> but only use the rotating sink. Remove the basic‑file include to shorten compile times.

  • Factor out common code
    The “latent” and non‑latent paths in PrintScreenImpl and PrintScreenLatentCallback share large swaths of identical logic. Extract shared steps (texture staging, filename generation, COM init) into helper functions to reduce duplication and risk of drift.

  • PCH naming vs. actual precompile setup
    You’ve named your header PCH.h but haven’t used target_precompile_headers in CMake, so it’s not actually precompiled. Either configure CMake to pre‑compile it or rename it (e.g. Common.h) to avoid confusion.

Implementing these changes will restore build stability, ensure your logging is robust, and align your plugin with SKSE conventions.