2017-01-28 04:49:09 +08:00
|
|
|
#include "pch.h"
|
2016-09-19 11:50:08 +08:00
|
|
|
#include "vcpkg_System.h"
|
|
|
|
|
2017-01-06 04:47:08 +08:00
|
|
|
namespace vcpkg::System
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
|
|
|
fs::path get_exe_path_of_current_process()
|
|
|
|
{
|
|
|
|
wchar_t buf[_MAX_PATH ];
|
|
|
|
int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH);
|
|
|
|
if (bytes == 0)
|
|
|
|
std::abort();
|
|
|
|
return fs::path(buf, buf + bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmd_execute(const wchar_t* cmd_line)
|
|
|
|
{
|
2017-03-04 22:10:59 +08:00
|
|
|
// Flush stdout before launching external process
|
|
|
|
fflush(stdout);
|
2017-02-15 11:09:09 +08:00
|
|
|
|
2016-09-19 11:50:08 +08:00
|
|
|
// Basically we are wrapping it in quotes
|
2016-09-30 10:28:00 +08:00
|
|
|
const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line);
|
2016-09-19 11:50:08 +08:00
|
|
|
int exit_code = _wsystem(actual_cmd_line.c_str());
|
|
|
|
return exit_code;
|
|
|
|
}
|
|
|
|
|
|
|
|
exit_code_and_output cmd_execute_and_capture_output(const wchar_t* cmd_line)
|
|
|
|
{
|
2017-03-04 22:10:59 +08:00
|
|
|
// Flush stdout before launching external process
|
|
|
|
fflush(stdout);
|
2017-02-15 11:09:09 +08:00
|
|
|
|
2016-09-30 10:28:00 +08:00
|
|
|
const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line);
|
2016-09-19 11:50:08 +08:00
|
|
|
|
|
|
|
std::string output;
|
|
|
|
char buf[1024];
|
|
|
|
auto pipe = _wpopen(actual_cmd_line.c_str(), L"r");
|
|
|
|
if (pipe == nullptr)
|
|
|
|
{
|
2017-02-15 05:26:21 +08:00
|
|
|
return { 1, output };
|
2016-09-19 11:50:08 +08:00
|
|
|
}
|
|
|
|
while (fgets(buf, 1024, pipe))
|
|
|
|
{
|
|
|
|
output.append(buf);
|
|
|
|
}
|
|
|
|
if (!feof(pipe))
|
|
|
|
{
|
2017-02-15 05:26:21 +08:00
|
|
|
return { 1, output };
|
2016-09-19 11:50:08 +08:00
|
|
|
}
|
|
|
|
auto ec = _pclose(pipe);
|
2017-02-15 05:26:21 +08:00
|
|
|
return { ec, output };
|
2016-09-19 11:50:08 +08:00
|
|
|
}
|
|
|
|
|
2017-03-07 08:16:56 +08:00
|
|
|
std::wstring create_powershell_script_cmd(const fs::path& script_path)
|
|
|
|
{
|
|
|
|
return create_powershell_script_cmd(script_path, L"");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring create_powershell_script_cmd(const fs::path& script_path, const std::wstring& args)
|
|
|
|
{
|
|
|
|
// TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned
|
|
|
|
return Strings::wformat(LR"(powershell -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args);
|
|
|
|
}
|
|
|
|
|
2016-09-19 11:50:08 +08:00
|
|
|
void print(const char* message)
|
|
|
|
{
|
2017-02-23 21:33:21 +08:00
|
|
|
fputs(message, stdout);
|
2016-09-19 11:50:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void println(const char* message)
|
|
|
|
{
|
|
|
|
print(message);
|
2017-02-23 21:33:21 +08:00
|
|
|
putchar('\n');
|
2016-09-19 11:50:08 +08:00
|
|
|
}
|
|
|
|
|
2016-12-13 07:08:26 +08:00
|
|
|
void print(const color c, const char* message)
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
|
|
|
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo{};
|
|
|
|
GetConsoleScreenBufferInfo(hConsole, &consoleScreenBufferInfo);
|
|
|
|
auto original_color = consoleScreenBufferInfo.wAttributes;
|
|
|
|
|
2017-02-16 10:40:39 +08:00
|
|
|
SetConsoleTextAttribute(hConsole, static_cast<WORD>(c) | (original_color & 0xF0));
|
2017-02-23 21:33:21 +08:00
|
|
|
print(message);
|
2016-09-19 11:50:08 +08:00
|
|
|
SetConsoleTextAttribute(hConsole, original_color);
|
|
|
|
}
|
|
|
|
|
2016-12-13 07:08:26 +08:00
|
|
|
void println(const color c, const char* message)
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
|
|
|
print(c, message);
|
2017-02-23 21:33:21 +08:00
|
|
|
putchar('\n');
|
2016-09-19 11:50:08 +08:00
|
|
|
}
|
|
|
|
|
2017-02-15 07:35:34 +08:00
|
|
|
optional<std::wstring> get_environmental_variable(const wchar_t* varname) noexcept
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
|
|
|
wchar_t* buffer;
|
|
|
|
_wdupenv_s(&buffer, nullptr, varname);
|
2017-02-15 07:35:34 +08:00
|
|
|
|
|
|
|
if (buffer == nullptr)
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
2017-02-15 07:35:34 +08:00
|
|
|
return nullptr;
|
2016-09-19 11:50:08 +08:00
|
|
|
}
|
2017-02-15 10:28:41 +08:00
|
|
|
std::unique_ptr<wchar_t, void(__cdecl *)(void*)> bufptr(buffer, free);
|
|
|
|
return std::make_unique<std::wstring>(buffer);
|
2016-09-19 11:50:08 +08:00
|
|
|
}
|
|
|
|
|
2017-02-15 05:26:21 +08:00
|
|
|
void set_environmental_variable(const wchar_t* varname, const wchar_t* varvalue) noexcept
|
|
|
|
{
|
|
|
|
_wputenv_s(varname, varvalue);
|
|
|
|
}
|
2017-03-11 07:43:54 +08:00
|
|
|
|
|
|
|
static bool is_string_keytype(DWORD hkey_type)
|
|
|
|
{
|
|
|
|
return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ;
|
|
|
|
}
|
|
|
|
|
|
|
|
optional<std::wstring> get_registry_string(HKEY base, const wchar_t* subKey, const wchar_t* valuename)
|
|
|
|
{
|
|
|
|
HKEY k = nullptr;
|
|
|
|
LSTATUS ec = RegOpenKeyExW(base, subKey, NULL, KEY_READ, &k);
|
|
|
|
if (ec != ERROR_SUCCESS)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
DWORD dwBufferSize = 0;
|
|
|
|
DWORD dwType = 0;
|
|
|
|
auto rc = RegQueryValueExW(k, valuename, nullptr, &dwType, nullptr, &dwBufferSize);
|
|
|
|
if (rc != ERROR_SUCCESS || !is_string_keytype(dwType) || dwBufferSize == 0 || dwBufferSize % sizeof(wchar_t) != 0)
|
|
|
|
return nullptr;
|
|
|
|
std::wstring ret;
|
|
|
|
ret.resize(dwBufferSize / sizeof(wchar_t));
|
|
|
|
|
|
|
|
rc = RegQueryValueExW(k, valuename, nullptr, &dwType, reinterpret_cast<LPBYTE>(ret.data()), &dwBufferSize);
|
|
|
|
if (rc != ERROR_SUCCESS || !is_string_keytype(dwType) || dwBufferSize != sizeof(wchar_t) * ret.size())
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
ret.pop_back(); // remove extra trailing null byte
|
|
|
|
return std::make_unique<std::wstring>(std::move(ret));
|
|
|
|
}
|
2017-01-06 04:47:08 +08:00
|
|
|
}
|