WL

SKSE Plugin Desktop Screenshot Capture

CMakeLists.txt

189 lines

txt

CMakePresets.json

73 lines

json

logger.h

95 lines

txt

PapyrusInterface.cpp

296 lines

txt

PapyrusInterface.h

39 lines

txt

pch.h

69 lines

txt

plugin.cpp

66 lines

txt

ScreenCapture.cpp

958 lines

txt

ScreenCapture.h

91 lines

txt

WL

I am trying to create a SKSE plugin for SKYRIM which will capture the desktop image in various file formats. The program is based on windows desktop Duplication with WIC fro file saving and directXtk/direcrxTEK for DDS file saving. I an having trouble with compiler errors seemingly related to SKSE. My SKSE is located in C:/CodePackages/SKSE_2_02_06/src/SKSE64 . Please review the attached files and determine the source of the errors and how they can be fixed. Do not present recomended fixes by writing files but rather use artifacts. The compiler errors are listed below: 'MAKE_SKSE_VERSION': identifier not found missing type specifier - int assumed. Note: C++ does not support default-int syntax error: missing ';' before identifier 'TakePhoto' missing type specifier - int assumed. Note: C++ does not support default-int 'int PrintScreenPapyrus::BSFixedString': redefinition syntax error: missing ';' before identifier 'Get_Result' 'StaticFunctionTag': undeclared identifier 'base': undeclared identifier 'StaticFunctionTag': undeclared identifier 'base': undeclared identifier syntax error: missing ')' before identifier 'path' 'RUNTIME_VERSION_1_5_39': undeclared identifier missing type specifier - int assumed. Note: C++ does not support default-int syntax error: missing ';' before identifier 'TakePhoto' missing type specifier - int assumed. Note: C++ does not support default-int 'int PrintScreenPapyrus::BSFixedString': redefinition syntax error: missing ';' before identifier 'Get_Result' 'StaticFunctionTag': undeclared identifier syntax error: ')' 'StaticFunctionTag': undeclared identifier syntax error: ',' missing type specifier - int assumed. Note: C++ does not support default-int 'int PrintScreenPapyrus::BSFixedString': redefinition syntax error: missing ';' before identifier 'TakePhoto' syntax error: missing ';' before '{' '{': missing function header (old-style formal list?) missing type specifier - int assumed. Note: C++ does not support default-int 'int PrintScreenPapyrus::BSFixedString': redefinition syntax error: missing ';' before identifier 'Get_Result' syntax error: missing ';' before '{' '{': missing function header (old-style formal list?) 'PrintScreenPapyrus::Cancel': redefinition; multiple initialization 'bool PrintScreenPapyrus::Cancel': redefinition 'StaticFunctionTag': undeclared identifier syntax error: ')' syntax error: missing ';' before '{' '{': missing function header (old-style formal list?) 'PrintScreenPapyrus::CheckPath': redefinition; multiple initialization 'bool PrintScreenPapyrus::CheckPath': redefinition 'StaticFunctionTag': undeclared identifier syntax error: ',' syntax error: missing ';' before '{' '{': missing function header (old-style formal list?) use of undefined type 'VMClassRegistry' 'StaticFunctionTag': undeclared identifier syntax error: identifier 'NativeFunction1' use of undefined type 'VMClassRegistry' use of undefined type 'VMClassRegistry' 'kFunctionFlag_NoWait': undeclared identifier use of undefined type 'VMClassRegistry' 'StaticFunctionTag': undeclared identifier syntax error: identifier 'NativeFunction0' use of undefined type 'VMClassRegistry' 'StaticFunctionTag': undeclared identifier syntax error: identifier 'NativeFunction0' use of undefined type 'VMClassRegistry' 'StaticFunctionTag': undeclared identifier syntax error: identifier 'NativeFunction1'

Edit

Looking at the compilation errors, the main issue is that your SKSE headers aren't being properly included or found. The errors indicate that fundamental SKSE types like BSFixedStringStaticFunctionTagVMClassRegistry, and macros like MAKE_SKSE_VERSION are not defined.

Let me analyze the issues and provide fixes:

SKSE Plugin Compilation Fixes

Document 

# SKSE Plugin Compilation Issues and Fixes ## Root Cause Analysis The compilation errors stem from several issues: 1. **Incorrect SKSE path in PCH.h**: The path `C:/CodePackages/skse64_2_02_06/src/common/ITypes.h` doesn't match your actual SKSE lo

Now let me provide the corrected files. I'll start with the most critical fixes:

Fixed PCH.h with Correct SKSE Headers

Code 

// PCH.h - Fixed Precompiled Header with correct SKSE paths #pragma once // Windows SDK Headers FIRST #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include <windows.h> // Standard C++ Library Headers (before SKSE) #include <string> #include <string

Fixed plugin.cpp with Correct SKSE Implementation

Code 

// plugin.cpp - Fixed for SKSE 2.02.06 compatibility #include "PCH.h" #include "logger.h" // Plugin information static PluginHandle g_pluginHandle = kPluginHandle_Invalid; static SKSEPapyrusInterface* g_papyrus = nullptr; // Plugin namespace namesp

Fixed CMakeLists.txt with Correct Paths

Code 

cmake_minimum_required(VERSION 3.24) project(PrintScreen VERSION 2.0.0 LANGUAGES CXX) # Ensure we're building for x64 if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) message(FATAL_ERROR "This project requires x64 architecture") endif() # Force static linki

The main issues and their fixes are:

  1. Path corrections: Fixed the SKSE path from C:/CodePackaes/skse64_2_2_6 to C:/CodePackages/SKSE_2_02_06 (correcting both the typo "CodePackaes" and the version format)
  2. Header include fixes: Updated PCH.h to include the correct SKSE headers from your actual SKSE installation directory
  3. Version macro fix: Replaced MAKE_SKSE_VERSION with a manual hex version since this macro may not be available in your SKSE version
  4. Runtime version fix: Replaced RUNTIME_VERSION_1_5_39 with the actual hex value 0x010539F0

Next steps to try compilation:

  1. Replace your PCH.h file with the fixed version
  2. Replace your plugin.cpp file with the fixed version
  3. Replace your CMakeLists.txt file with the fixed version
  4. Ensure your SKSE directory actually exists at C:/CodePackages/SKSE_2_02_06/src/skse64 and contains the expected header files

If you continue to have issues, you might want to consider switching to CommonLibSSE approach (which I outlined in the analysis artifact) as it's more modern and handles SKSE compatibility automatically.

Retry

WL

I agree that we ahould use Commonlibssepng headers instead of the current skse. My concern is that the code may become confused and try to use both systems thus generating spurious errors. I prefer simple code when possible. Can you make these changes?

Edit

You're absolutely right - mixing two different SKSE systems will cause conflicts and confusion. Let me create clean, simple files that use only CommonLibSSE throughout.

Clean PCH.h Using Only CommonLibSSE

Code 

// PCH.h - Clean implementation using only CommonLibSSE #pragma once // Windows SDK Headers FIRST #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include <windows.h> // Standard C++ Library Headers #include <string> #include <string_view> #include <v

Clean plugin.cpp Using Only CommonLibSSE

Code 

// plugin.cpp - Clean implementation using only CommonLibSSE #include "PCH.h" #include "logger.h" // Plugin namespace namespace Plugin { constexpr const char* NAME = "PrintScreen"; constexpr REL::Version VERSION{1, 0, 0}; } // Forward decla

Clean PapyrusInterface.cpp Using Only CommonLibSSE

Code 

#include "PCH.h" #include "PapyrusInterface.h" #include "ScreenCapture.h" #include "logger.h" namespace PrintScreenPapyrus { // Global state std::atomic<bool> g_isRunning{false}; std::atomic<bool> g_cancelFlag{false}; std::atomi

Clean PapyrusInterface.h Using Only CommonLibSSE

Code 

#pragma once #include "PCH.h" #include <string> #include <atomic> #include <mutex> namespace PrintScreenPapyrus { // Function declarations for Papyrus registration - Using CommonLibSSE types RE::BSFixedString TakePhoto( RE::Sta

Simplified CMakeLists.txt for CommonLibSSE Only

Code 

cmake_minimum_required(VERSION 3.24) project(PrintScreen VERSION 2.0.0 LANGUAGES CXX) # Ensure we're building for x64 if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) message(FATAL_ERROR "This project requires x64 architecture") endif() # Force static linki

Perfect! I've created completely clean implementations that use only CommonLibSSE throughout. Here's what I changed:

Key Changes Made:

  1. PCH.h: Removed all raw SKSE includes and paths, using only CommonLibSSE headers (RE/Skyrim.hSKSE/SKSE.hREL/Relocation.h)
  2. plugin.cpp:
    • Uses modern CommonLibSSE plugin structure
    • SKSEPlugin_Version instead of old SKSEPlugin_Query
    • Proper CommonLibSSE initialization with SKSE::Init()
    • All types prefixed with RE:: namespace
  3. PapyrusInterface.cpp & .h:
    • All SKSE types now use RE:: prefix (RE::BSFixedStringRE::StaticFunctionTag)
    • Registration uses RE::BSScript::IVirtualMachine* instead of old VMClassRegistry*
    • Simplified registration syntax
  4. CMakeLists.txt:
    • Removed all SKSE path references
    • Removed SKSE-specific includes
    • Much cleaner and simpler

Benefits:

  • No mixing of systems - purely CommonLibSSE
  • Future-proof - CommonLibSSE handles SKSE compatibility
  • Simpler - fewer manual paths and includes
  • Better type safety - modern C++ features
  • Automatic version handling - no manual runtime version checks

The code is now much cleaner and should compile without the previous SKSE-related errors. CommonLibSSE will handle all the SKSE compatibility details automatically.

Retry

Claude can make mistakes. Please double-check responses.

 

Research

Sonnet 4

Copy

Publish

cmake_minimum_required(VERSION 3.24) project(PrintScreen VERSION 2.0.0 LANGUAGES CXX) # Ensure we're building for x64 if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) message(FATAL_ERROR "This project requires x64 architecture") endif() # Force static linking of runtime libraries set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") # policies... cmake_policy(SET CMP0091 NEW) if(POLICY CMP0135) cmake_policy(SET CMP0135 NEW) endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # C++ standard, build type, CRT set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE) endif() set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") # find all packages find_package(CommonLibSSE CONFIG REQUIRED) find_package(directxtex CONFIG REQUIRED) find_package(directxtk CONFIG REQUIRED) # plugin target add_library(${PROJECT_NAME} SHARED plugin.cpp ScreenCapture.cpp PapyrusInterface.cpp printscreen.rc ) # precompiled headers target_precompile_headers(${PROJECT_NAME} PRIVATE PCH.h) # includes - Only CommonLibSSE needed now target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) # link everything (only _after_ add_library) target_link_libraries(${PROJECT_NAME} PRIVATE CommonLibSSE::CommonLibSSE Microsoft::DirectXTex Microsoft::DirectXTK d3d11 dxgi dxguid windowscodecs ole32 oleaut32 ) # MSVC compiler flags & definitions if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4 /permissive- /Zc:preprocessor /Zc:__cplusplus ) target_compile_definitions(${PROJECT_NAME} PRIVATE _UNICODE UNICODE WINVER=0x0601 _WIN32_WINNT=0x0601 ) endif() # Auto-deployment to mod folder # Debug: Print the environment variable message(STATUS "SKYRIM_MODS_FOLDER environment variable: $ENV{SKYRIM_MODS_FOLDER}") if(DEFINED ENV{SKYRIM_MODS_FOLDER}) message(STATUS "Environment variable is defined") if(IS_DIRECTORY "$ENV{SKYRIM_MODS_FOLDER}") message(STATUS "Directory exists: $ENV{SKYRIM_MODS_FOLDER}") set(OUTPUT_FOLDER "$ENV{SKYRIM_MODS_FOLDER}/${PROJECT_NAME}") set(DLL_FOLDER "${OUTPUT_FOLDER}/SKSE/Plugins") message(STATUS "Will copy to: ${DLL_FOLDER}") add_custom_command( TARGET "${PROJECT_NAME}" POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory "${DLL_FOLDER}" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:${PROJECT_NAME}>" "${DLL_FOLDER}/$<TARGET_FILE_NAME:${PROJECT_NAME}>" COMMAND "${CMAKE_COMMAND}" -E echo "Copied DLL to ${DLL_FOLDER}" VERBATIM ) # Copy PDB files for debug builds if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") add_custom_command( TARGET "${PROJECT_NAME}" POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_PDB_FILE:${PROJECT_NAME}>" "${DLL_FOLDER}/$<TARGET_PDB_FILE_NAME:${PROJECT_NAME}>" COMMAND "${CMAKE_COMMAND}" -E echo "Copied pdb to ${DLL_FOLDER}" VERBATIM ) endif() else() message(STATUS "Directory does not exist: $ENV{SKYRIM_MODS_FOLDER}") endif() else() message(STATUS "SKYRIM_MODS_FOLDER environment variable not defined") # Alternative deployment methods if SKYRIM_MODS_FOLDER is not set message(STATUS "SKYRIM_MODS_FOLDER environment variable not set") # Try common Skyrim installation paths set(POSSIBLE_SKYRIM_PATHS "C:/Program Files (x86)/Steam/steamapps/common/Skyrim Special Edition" "C:/Program Files/Steam/steamapps/common/Skyrim Special Edition" "C:/Games/Steam/steamapps/common/Skyrim Special Edition" "C:/SteamLibrary/steamapps/common/Skyrim Special Edition" ) foreach(SKYRIM_PATH ${POSSIBLE_SKYRIM_PATHS}) if(IS_DIRECTORY "${SKYRIM_PATH}") set(SKYRIM_DATA_FOLDER "${SKYRIM_PATH}/Data") if(IS_DIRECTORY "${SKYRIM_DATA_FOLDER}") set(DLL_FOLDER "${SKYRIM_DATA_FOLDER}/SKSE/Plugins") message(STATUS "Found Skyrim installation: ${SKYRIM_PATH}") message(STATUS "Auto-deploying to: ${DLL_FOLDER}") add_custom_command( TARGET "${PROJECT_NAME}" POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory "${DLL_FOLDER}" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:${PROJECT_NAME}>" "${DLL_FOLDER}/$<TARGET_FILE_NAME:${PROJECT_NAME}>" VERBATIM ) # Copy PDB files for debug builds if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") add_custom_command( TARGET "${PROJECT_NAME}" POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_PDB_FILE:${PROJECT_NAME}>" "${DLL_FOLDER}/$<TARGET_PDB_FILE_NAME:${PROJECT_NAME}>" VERBATIM ) endif() break() endif() endif() endforeach() # Manual deployment instructions if(NOT DEFINED DLL_FOLDER) message(STATUS "") message(STATUS "=== MANUAL DEPLOYMENT REQUIRED ===") message(STATUS "Copy the built DLL to your Skyrim SKSE plugins folder:") message(STATUS "From: ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${PROJECT_NAME}.dll") message(STATUS "To: [Skyrim]/Data/SKSE/Plugins/${PROJECT_NAME}.dll") message(STATUS "") message(STATUS "Or set the SKYRIM_MODS_FOLDER environment variable for automatic deployment") message(STATUS "Example: set SKYRIM_MODS_FOLDER=C:/ModOrganizer2/mods") message(STATUS "") endif() endif() # Print configuration info message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") message(STATUS "C++ standard: ${CMAKE_CXX_STANDARD}") message(STATUS "CommonLibSSE found: ${CommonLibSSE_FOUND}") if(DEFINED OUTPUT_FOLDER) message(STATUS "Output folder: ${OUTPUT_FOLDER}") endif()