From 42f986ce4a6f35b59a5d4521c9c662a8d03849c8 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Fri, 14 Jul 2023 20:54:41 +0300 Subject: [PATCH] Add util::executable_path() --- .../include/psemek/util/executable_path.hpp | 10 ++++++ libs/util/source/executable_path.cpp | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 libs/util/include/psemek/util/executable_path.hpp create mode 100644 libs/util/source/executable_path.cpp diff --git a/libs/util/include/psemek/util/executable_path.hpp b/libs/util/include/psemek/util/executable_path.hpp new file mode 100644 index 00000000..9f382d46 --- /dev/null +++ b/libs/util/include/psemek/util/executable_path.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace psemek::util +{ + + std::filesystem::path executable_path(); + +} diff --git a/libs/util/source/executable_path.cpp b/libs/util/source/executable_path.cpp new file mode 100644 index 00000000..b4e92ff7 --- /dev/null +++ b/libs/util/source/executable_path.cpp @@ -0,0 +1,36 @@ +#include +#include + +#ifdef WIN32 +#include +#include +#include +#endif + +namespace psemek::util +{ + + std::filesystem::path executable_path() + { +#if defined WIN32 + std::string result(256, '\0'); + while (true) + { + GetModuleFileNameA(NULL, result.data(), result.size()); + auto error = GetLastError(); + if (error == ERROR_SUCCESS) + break; + else if (error == ERROR_INSUFFICIENT_BUFFER) + result.resize(result.size() * 2); + else + throw std::runtime_error(util::to_string("failed to retrieve executable path: ", std::hex, error)); + } + return std::filesystem::path(result); +#elif defined __linux__ + return std::filesystem::canonical("/proc/self/exe"); +#else + throw std::runtime_error("executable_path() is not implemented for this platform"); +#endif + } + +}