search_path.hpp
Go to the documentation of this file.
1// Copyright (c) 2006, 2007 Julio M. Merino Vidal
2// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
3// Copyright (c) 2009 Boris Schaeling
4// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
5// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
10#pragma once
11
12#include <stdlib.h>
13
14#include <filesystem>
15#include <stdexcept>
16#include <string>
17
18#include <boost/array.hpp>
20#include <boost/system/error_code.hpp>
21#include <boost/tokenizer.hpp>
22
23#include <Shellapi.h>
24
26{
27
28#if defined(_UNICODE) || defined(UNICODE)
29 inline std::wstring
30 search_path(const std::wstring& filename, std::wstring path = L"")
31 {
32 if (path.empty())
33 {
34 path = ::_wgetenv(L"PATH");
35 if (path.empty())
36 BOOST_PROCESS_THROW(std::runtime_error("Environment variable PATH not found"));
37 }
38
39 typedef boost::
40 tokenizer<boost::char_separator<wchar_t>, std::wstring::const_iterator, std::wstring>
41 tokenizer;
42 boost::char_separator<wchar_t> sep(L";");
43 tokenizer tok(path, sep);
44 for (tokenizer::iterator it = tok.begin(); it != tok.end(); ++it)
45 {
46 std::filesystem::path p = *it;
47 p /= filename;
48 boost::array<std::wstring, 4> extensions = {L"", L".exe", L".com", L".bat"};
49 for (boost::array<std::wstring, 4>::iterator it2 = extensions.begin();
50 it2 != extensions.end();
51 ++it2)
52 {
53 std::filesystem::path p2 = p;
54 p2 += *it2;
55 boost::system::error_code ec;
56 bool file = std::filesystem::is_regular_file(p2, ec);
57 if (!ec && file && SHGetFileInfoW(p2.c_str(), 0, 0, 0, SHGFI_EXETYPE))
58 {
59 return p2.wstring();
60 }
61 }
62 }
63 return L"";
64 }
65#else
66 inline std::string
67 search_path(const std::string& filename, std::string path = "")
68 {
69 if (path.empty())
70 {
71 path = ::getenv("PATH");
72 if (path.empty())
73 BOOST_PROCESS_THROW(std::runtime_error("Environment variable PATH not found"));
74 }
75
76 using tokenizer = boost::tokenizer<boost::char_separator<char>>;
77 boost::char_separator<char> sep(";");
78 tokenizer tok(path, sep);
79 for (tokenizer::iterator it = tok.begin(); it != tok.end(); ++it)
80 {
81 std::filesystem::path p = *it;
82 p /= filename;
83 boost::array<std::string, 4> extensions = {"", ".exe", ".com", ".bat"};
84 for (boost::array<std::string, 4>::iterator it2 = extensions.begin();
85 it2 != extensions.end();
86 ++it2)
87 {
88 std::filesystem::path p2 = p;
89 p2 += *it2;
90 boost::system::error_code ec;
91 bool file = std::filesystem::is_regular_file(p2, ec);
92 if (!ec && file && SHGetFileInfoA(p2.string().c_str(), 0, 0, 0, SHGFI_EXETYPE))
93 {
94 return p2.string();
95 }
96 }
97 }
98 return "";
99 }
100#endif
101
102} // namespace boost::process::windows
Defines various macros.
#define BOOST_PROCESS_THROW(EX)
Defines how exceptions are thrown.
Definition config.hpp:69
std::string search_path(const std::string &filename, std::string path="")