From c88053a5757fa8a1b80fbe60c94ce6956ddea9d4 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sun, 31 Oct 2021 16:28:10 +0100 Subject: [PATCH] windows: Added context menu entry option Closes #333 --- .../libimhex/include/hex/helpers/paths.hpp | 2 + plugins/libimhex/source/helpers/paths.cpp | 30 ++++++-- plugins/windows/CMakeLists.txt | 1 + .../source/content/settings_entries.cpp | 76 +++++++++++++++++++ plugins/windows/source/lang/en_US.cpp | 3 +- plugins/windows/source/lang/zh_CN.cpp | 3 +- plugins/windows/source/plugin_windows.cpp | 2 + 7 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 plugins/windows/source/content/settings_entries.cpp diff --git a/plugins/libimhex/include/hex/helpers/paths.hpp b/plugins/libimhex/include/hex/helpers/paths.hpp index b9e0f7698..0c744b061 100644 --- a/plugins/libimhex/include/hex/helpers/paths.hpp +++ b/plugins/libimhex/include/hex/helpers/paths.hpp @@ -17,6 +17,8 @@ namespace hex { Constants }; + std::string getExecutablePath(); + std::vector getPath(ImHexPath path); } \ No newline at end of file diff --git a/plugins/libimhex/source/helpers/paths.cpp b/plugins/libimhex/source/helpers/paths.cpp index e5883e758..f87b21067 100644 --- a/plugins/libimhex/source/helpers/paths.cpp +++ b/plugins/libimhex/source/helpers/paths.cpp @@ -16,11 +16,28 @@ namespace hex { - std::vector getPath(ImHexPath path) { + std::string getExecutablePath() { #if defined(OS_WINDOWS) std::string exePath(MAX_PATH, '\0'); GetModuleFileName(nullptr, exePath.data(), exePath.length()); - auto parentDir = std::filesystem::path(exePath).parent_path(); + + return exePath; + #elif defined(OS_LINUX) + std::string exePath(PATH_MAX, '\0'); + readlink("/proc/self/exe", executablePath.data(), PATH_MAX); + + return exePath; + #elif defined(OS_MACOS) + return getMacExecutableDirectoryPath(); + #else + return ""; + #endif + } + + std::vector getPath(ImHexPath path) { + #if defined(OS_WINDOWS) + const auto exePath = getExecutablePath(); + const auto parentDir = std::filesystem::path(exePath).parent_path(); std::filesystem::path appDataDir; { @@ -84,10 +101,10 @@ namespace hex { return results; #elif defined(OS_MACOS) // Get path to special directories - const std::filesystem::path exeDir(getMacExecutableDirectoryPath()); + const auto exePath = getExecutablePath(); const std::filesystem::path applicationSupportDir(getMacApplicationSupportDirectoryPath()); - std::vector paths = { exeDir, applicationSupportDir }; + std::vector paths = { exePath, applicationSupportDir }; std::vector results; switch (path) { @@ -126,8 +143,9 @@ namespace hex { for (auto &dir : dataDirs) dir = dir / "imhex"; - std::array executablePath = { 0 }; - if (readlink("/proc/self/exe", executablePath.data(), PATH_MAX) != -1) + const auto exePath = getExecutablePath(); + + if (!exePath.empty()) dataDirs.emplace(dataDirs.begin(), std::filesystem::path(executablePath.data()).parent_path()); std::vector result; diff --git a/plugins/windows/CMakeLists.txt b/plugins/windows/CMakeLists.txt index 9387d5b89..406e473a6 100644 --- a/plugins/windows/CMakeLists.txt +++ b/plugins/windows/CMakeLists.txt @@ -14,6 +14,7 @@ if (WIN32) source/lang/zh_CN.cpp source/content/ui_items.cpp + source/content/settings_entries.cpp ) # Add additional include directories here # diff --git a/plugins/windows/source/content/settings_entries.cpp b/plugins/windows/source/content/settings_entries.cpp new file mode 100644 index 000000000..17e4cd3a4 --- /dev/null +++ b/plugins/windows/source/content/settings_entries.cpp @@ -0,0 +1,76 @@ +#include +#include + +#include +#include +using namespace hex::lang_literals; + +#include + +#include +#include + +namespace hex::plugin::windows { + + namespace { + + constexpr auto ImHexContextMenuKey = R"(Software\Classes\*\shell\ImHex)"; + + void addImHexContextMenuEntry() { + // Create ImHex Root Key + HKEY imHexRootKey; + RegCreateKeyExA(HKEY_CURRENT_USER, ImHexContextMenuKey, 0x00, nullptr, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE , nullptr, &imHexRootKey, nullptr); + RegSetValueA(imHexRootKey, nullptr, REG_SZ, "Open with ImHex", 0x00); + + // Add Icon key to use first icon embedded in exe + std::array imHexPath = { 0 }; + GetModuleFileNameA(nullptr, imHexPath.data(), imHexPath.size()); + auto iconValue = hex::format(R"("{}",0)", imHexPath.data()); + RegSetKeyValueA(imHexRootKey, nullptr, "Icon", REG_SZ, iconValue.c_str(), iconValue.size() + 1); + + // Add command key to pass file path as first argument to ImHex + auto commandValue = hex::format(R"("{}" "%1")", imHexPath.data()); + RegSetValueA(imHexRootKey, "command", REG_SZ, commandValue.c_str(), commandValue.size() + 1); + RegCloseKey(imHexRootKey); + } + + void removeImHexContextMenuEntry() { + RegDeleteTreeA(HKEY_CURRENT_USER, ImHexContextMenuKey); + } + + bool hasImHexContextMenuEntry() { + HKEY key; + bool keyExists = (RegOpenKeyExA(HKEY_CURRENT_USER, ImHexContextMenuKey, 0x00, KEY_SET_VALUE, &key) == ERROR_SUCCESS); + RegCloseKey(key); + + return keyExists; + } + + } + + void registerSettings() { + + /* General */ + + ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.context_menu_entry", 0, [](auto name, nlohmann::json &setting) { + static bool enabled = hasImHexContextMenuEntry(); + + if (ImGui::Checkbox(name.data(), &enabled)) { + + if (enabled) + addImHexContextMenuEntry(); + else + removeImHexContextMenuEntry(); + + enabled = hasImHexContextMenuEntry(); + setting = enabled; + + return true; + } + + return false; + }); + + } + +} \ No newline at end of file diff --git a/plugins/windows/source/lang/en_US.cpp b/plugins/windows/source/lang/en_US.cpp index d44d250e7..2576393b5 100644 --- a/plugins/windows/source/lang/en_US.cpp +++ b/plugins/windows/source/lang/en_US.cpp @@ -23,8 +23,9 @@ namespace hex::plugin::windows { { "hex.windows.view.tty_console.console", "Console" }, { "hex.windows.view.tty_console.send_etx", "Send ETX" }, { "hex.windows.view.tty_console.send_eot", "Send EOT" }, - { "hex.windows.view.tty_console.send_sub", "Send SUB" } + { "hex.windows.view.tty_console.send_sub", "Send SUB" }, + { "hex.builtin.setting.general.context_menu_entry", "Windows context menu entry" }, }); } diff --git a/plugins/windows/source/lang/zh_CN.cpp b/plugins/windows/source/lang/zh_CN.cpp index aff869ff0..c892b0e25 100644 --- a/plugins/windows/source/lang/zh_CN.cpp +++ b/plugins/windows/source/lang/zh_CN.cpp @@ -23,8 +23,9 @@ namespace hex::plugin::windows { { "hex.windows.view.tty_console.console", "控制台" }, { "hex.windows.view.tty_console.send_etx", "发送ETX" }, { "hex.windows.view.tty_console.send_eot", "发送EOT" }, - { "hex.windows.view.tty_console.send_sub", "发送SUB" } + { "hex.windows.view.tty_console.send_sub", "发送SUB" }, + //{ "hex.builtin.setting.general.context_menu_entry", "Windows context menu entry" }, }); } diff --git a/plugins/windows/source/plugin_windows.cpp b/plugins/windows/source/plugin_windows.cpp index 66de1b894..b7a791b45 100644 --- a/plugins/windows/source/plugin_windows.cpp +++ b/plugins/windows/source/plugin_windows.cpp @@ -8,6 +8,7 @@ namespace hex::plugin::windows { void registerLanguageZhCN(); void addFooterItems(); + void registerSettings(); } @@ -20,6 +21,7 @@ IMHEX_PLUGIN_SETUP("Windows", "WerWolv", "Windows-only features") { registerLanguageZhCN(); addFooterItems(); + registerSettings(); }