Last active
May 1, 2020 15:43
-
-
Save ArunTS96/c6bf7d00b8623ebf79776055cf90e775 to your computer and use it in GitHub Desktop.
Where.exe source code. This will return full path to file from filename by checking through system directory, windows directory and path variable. Windows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
std::wstring ProcessHandleToNameW(const HANDLE process) | |
{ | |
DWORD buffSize = page_size; | |
std::wstring ret(page_size, 0); | |
if (!QueryFullProcessImageNameW(process, 0, &ret[0], &buffSize)) | |
{ | |
STANDARD_GET_LAST_ERROR("QueryFullProcessImageNameW"); | |
ret.clear(); | |
} | |
else | |
{ | |
ret.resize(buffSize); //here only buffsize. not buffsize-1 | |
USERMSG("%ws is the path\n", ret.c_str()); | |
} | |
return ret; | |
} | |
std::filesystem::path ProcessHandleToPath(const HANDLE process) | |
{ | |
return std::filesystem::path(ProcessHandleToNameW(process)); | |
} | |
std::filesystem::path GetCurrentProcessImagePath() | |
{ | |
static auto currentModulePath = ProcessHandleToPath(GetCurrentProcess()); | |
return currentModulePath; | |
} | |
std::map<std::wstring, std::wstring> GetEnvAsMap() | |
{ | |
std::map<std::wstring, std::basic_string<wchar_t>> env; | |
auto free = [](wchar_t* p) { FreeEnvironmentStringsW(p); }; | |
const auto envBlock = std::unique_ptr<wchar_t, decltype(free)>{ | |
GetEnvironmentStringsW(), free }; | |
for (auto i = envBlock.get(); *i != L'\0'; ++i) { | |
std::wstring key; | |
std::wstring value; | |
for (; *i != L'='; ++i) | |
key += *i; | |
++i; | |
for (; *i != L'\0'; ++i) | |
value += *i; | |
env[key] = value; | |
} | |
return env; | |
} | |
template <class Char, typename Out> | |
void Split(const std::basic_string<Char>& s, Char delim, Out result) { | |
std::basic_istringstream<Char, std::char_traits<Char>, std::allocator<Char>> iss(s); | |
std::basic_string<Char> item; | |
while (std::getline(iss, item, delim)) { | |
*result++ = item; | |
} | |
} | |
template <class Char> | |
std::vector<std::basic_string<Char>> Split(const std::basic_string<Char>& s, Char delim) | |
{ | |
std::vector<std::basic_string<Char>> elems; | |
Split<Char>(s, delim, std::back_inserter(elems)); | |
return elems; | |
} | |
template <class Char> | |
class Where | |
{ | |
std::vector<std::filesystem::path> paths_; | |
Where() | |
{ | |
paths_.emplace_back(GetCurrentProcessImagePath()); | |
wchar_t curDir[page_size]; | |
if (GetCurrentDirectoryW(page_size, curDir)) | |
paths_.emplace_back(curDir); | |
auto getDirAndEmplace = [&](const decltype(GetSystemDirectoryW) getter) | |
{ | |
wchar_t dir[page_size]; | |
if (getter(dir, page_size)) | |
paths_.emplace_back(dir); | |
}; | |
getDirAndEmplace(GetSystemDirectoryW); | |
getDirAndEmplace(GetWindowsDirectoryW); | |
for (auto& i : Split<Char>(GetEnvAsMap()[L"Path"], L';')) | |
{ | |
if (i.back() == L'\\') | |
{ | |
std::filesystem::path p = i; | |
paths_.emplace_back(i); | |
} | |
else | |
{ | |
paths_.emplace_back(i + L'\\'); | |
} | |
} | |
} | |
~Where() = default; | |
public: | |
static Where& GetInstance() | |
{ | |
static Where instance; | |
return instance; | |
} | |
std::optional<std::filesystem::path> GetFullyFormedPath(const std::basic_string<Char>& file) | |
{ | |
std::filesystem::path fileName(file); | |
if (!fileName.has_extension()) | |
fileName = fileName.native() + L".exe"; | |
for(auto &i : paths_) | |
{ | |
std::filesystem::path fullPath(i.native() + fileName.native()); | |
if (exists(fullPath)) | |
return fullPath; | |
} | |
return {}; | |
} | |
Where& operator=(const Where&) = delete; | |
Where(const Where&) = delete; | |
Where(Where&&) = delete; | |
Where& operator=(Where&&) = delete; | |
}; | |
int main() | |
{ | |
auto wh = &(Where<wchar_t>::GetInstance()); | |
auto path = wh->GetFullyFormedPath(L"ping"); | |
if (path.has_value()) | |
std::wcout << *path << L"\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment