diff --git a/.vscode/settings.json b/.vscode/settings.json index 32f0e1c..4bc533a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "files.autoSave": "onFocusChange", "editor.fontSize": 14, - "editor.fontFamily": "'ComicShannsMono Nerd Font', 'ComicShannsMono Nerd Font', 'ComicShannsMono Nerd Font'", + "editor.fontFamily": "'Source Code Pro', 'Courier New', monospace", "cmake.configureOnOpen": true, "cmake.debugConfig": { "console": "integratedTerminal", @@ -20,7 +20,8 @@ ] }, "cmake.configureSettings": { - "CMAKE_TOOLCHAIN_FILE": "${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + "CMAKE_TOOLCHAIN_FILE": "${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "USE_TEST": "ON" }, "cmake.options.statusBarVisibility": "visible", "cmake.generator": "Ninja", @@ -82,6 +83,8 @@ "xmemory0": "cpp", "xstddef": "cpp", "xtr1common": "cpp", - "xutility": "cpp" + "xutility": "cpp", + "unordered_map": "cpp", + "xhash": "cpp" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index ecd1474..4a402fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,17 +8,26 @@ if (MSVC) add_compile_options(/source-charset:utf-8) endif() +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") +endif() + message(STATUS "System: ${CMAKE_SYSTEM_NAME}") message(STATUS "Compiler CXX ID: ${CMAKE_CXX_COMPILER_ID}") -# find_package(GTest CONFIG REQUIRED) - set(SRC_FILES src/of_path.cpp src/of_str.cpp + src/of_win.cpp ) -include_directories(include) -add_subdirectory(test) +include_directories(include) +if(DEFINED USE_TEST) + message(STATUS "USE TEST") + add_subdirectory(test) +endif() + +set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}) add_library(Ofen STATIC ${SRC_FILES}) target_include_directories(Ofen PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) \ No newline at end of file diff --git a/include/of_def.hpp b/include/of_def.hpp index f51be16..49b0bcb 100644 --- a/include/of_def.hpp +++ b/include/of_def.hpp @@ -11,4 +11,12 @@ using ofString = std::string; #define ofT(text) text #endif +enum OfStatus { + STA_SUCESS = 0, + STA_ERROR, + STA_CANOT_OPEN_REG, + STA_CANOT_QUERY_REG, + STA_CANOT_SET_REG +}; + #endif \ No newline at end of file diff --git a/include/of_win.h b/include/of_win.h new file mode 100644 index 0000000..ba101f1 --- /dev/null +++ b/include/of_win.h @@ -0,0 +1,22 @@ +#pragma once +#ifdef _WIN32 + +#include +#include +#include +#include "of_def.hpp" + +class COfWin { +public: + COfWin(); + ~COfWin(); +public: + /// @brief 获取机器上安装的VS安装目录 + /// @return + static OfStatus getVSInstallations(std::map& out); + static OfStatus appendPathVariable(const ofString& path); + static OfStatus removePathVariable(const ofString& path); + static bool isAdminRun(bool& is_admin); +}; + +#endif \ No newline at end of file diff --git a/src/of_win.cpp b/src/of_win.cpp new file mode 100644 index 0000000..05e3342 --- /dev/null +++ b/src/of_win.cpp @@ -0,0 +1,71 @@ +#include "of_win.h" + +constexpr auto g_VSReg = ofT(""); +constexpr auto g_EnvReg = ofT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"); + +COfWin::COfWin() +{ +} + +COfWin::~COfWin() +{ +} + +OfStatus COfWin::getVSInstallations(std::map& out) +{ + return STA_ERROR; +} + +OfStatus COfWin::appendPathVariable(const ofString& path) +{ + HKEY hKey; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_EnvReg, 0, KEY_READ | KEY_WRITE, &hKey) != ERROR_SUCCESS) { + return STA_CANOT_OPEN_REG; + } + DWORD bufferSize = 0; + if (RegQueryValueEx(hKey, "Path", nullptr, nullptr, nullptr, &bufferSize) != ERROR_SUCCESS) { + RegCloseKey(hKey); + return STA_CANOT_QUERY_REG; + } + ofString currentPath(bufferSize, ofT('\0')); + if (RegQueryValueEx(hKey, "Path", nullptr, nullptr, reinterpret_cast(¤tPath[0]), &bufferSize) != ERROR_SUCCESS) { + RegCloseKey(hKey); + return STA_CANOT_QUERY_REG; + } + currentPath.resize(bufferSize - 1); + ofString updatedPath = currentPath + ofT(";") + path; + if (RegSetValueEx(hKey, "Path", 0, REG_EXPAND_SZ, reinterpret_cast(updatedPath.c_str()), updatedPath.size() + 1) != ERROR_SUCCESS) { + RegCloseKey(hKey); + return STA_CANOT_SET_REG; + } + RegCloseKey(hKey); + SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, reinterpret_cast("Environment"), SMTO_ABORTIFHUNG, 5000, nullptr); + return STA_SUCESS; +} + +OfStatus COfWin::removePathVariable(const ofString& path) +{ + return STA_ERROR; +} + +bool COfWin::isAdminRun(bool& is_admin) +{ + BOOL isAdmin = FALSE; + HANDLE tokenHandle = nullptr; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle)) { + // 获取管理员组的 SID + SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY; + PSID adminGroup; + if (AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminGroup)) { + // 检查当前令牌是否属于管理员组 + if (!CheckTokenMembership(nullptr, adminGroup, &isAdmin)) { + isAdmin = FALSE; + } + FreeSid(adminGroup); + } + CloseHandle(tokenHandle); + } + return static_cast(isAdmin); +}