Do not depend on newlines when getting output from powershell
MODIFY
include/vcpkg/base/system.h
include/vcpkg/base/system.h
@@ -22,7 +22,7 @@ namespace vcpkg::System
ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line);
- std::string create_powershell_script_cmd(const fs::path& script_path, const CStringView args = "");
+ ExitCodeAndOutput powershell_execute_and_capture_output(const fs::path& script_path, const CStringView args = "");
enum class Color
{

MODIFY
src/vcpkg/base/system.cpp
src/vcpkg/base/system.cpp
@@ -269,11 +269,23 @@ namespace vcpkg::System
#endif
}
- std::string create_powershell_script_cmd(const fs::path& script_path, const CStringView args)
+ ExitCodeAndOutput powershell_execute_and_capture_output(const fs::path& script_path, const CStringView args)
{
// TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned
- return Strings::format(
+ const std::string cmd = Strings::format(
R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args);
+
+ auto rc = System::cmd_execute_and_capture_output(cmd);
+
+ // Remove newline from all output.
+ // Powershell returns newlines when it hits the column count of the console.
+ // For example, this is 80 in cmd on Windows 7. If the expected output is longer than 80 lines, we get
+ // newlines in-between the data.
+ // To solve this, we design our interaction with powershell to not depend on newlines,
+ // and then strip all newlines here.
+ rc.output = Strings::replace_all(std::move(rc.output), "\n", "");
+
+ return rc;
}
void println() { putchar('\n'); }

MODIFY
src/vcpkg/vcpkgpaths.cpp
src/vcpkg/vcpkgpaths.cpp
@@ -74,9 +74,8 @@ namespace vcpkg
tool_name,
version_as_string);
const fs::path script = scripts_folder / "fetchDependency.ps1";
- const auto install_cmd =
- System::create_powershell_script_cmd(script, Strings::format("-Dependency %s", tool_name));
- const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd);
+ const System::ExitCodeAndOutput rc =
+ System::powershell_execute_and_capture_output(script, Strings::format("-Dependency %s", tool_name));
if (rc.exit_code)
{
System::println(System::Color::error,
@@ -324,14 +323,13 @@ namespace vcpkg
static std::vector<VisualStudioInstance> get_visual_studio_instances(const VcpkgPaths& paths)
{
const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1";
- const std::string cmd = System::create_powershell_script_cmd(script);
- const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd);
+ const System::ExitCodeAndOutput ec_data = System::powershell_execute_and_capture_output(script);
Checks::check_exit(
VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances");
- const std::vector<std::string> instances_as_strings = Strings::split(ec_data.output, "\n");
+ const std::vector<std::string> instances_as_strings = Strings::split(ec_data.output, "::<eol>");
Checks::check_exit(
- VCPKG_LINE_INFO, !instances_as_strings.empty(), "Could not detect any Visual Studio instances");
+ VCPKG_LINE_INFO, !instances_as_strings.empty(), "Could not detect any Visual Studio instances.\n");
std::vector<VisualStudioInstance> output;
for (const std::string& instance_as_string : instances_as_strings)
@@ -341,7 +339,7 @@ namespace vcpkg
split.size() == 4,
"Invalid Visual Studio instance format.\n"
"Expected: PreferenceWeight::ReleaseType::Version::PathToVisualStudio\n"
- "Actual : %s",
+ "Actual : %s\n",
instance_as_string);
output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)});
}

Do not depend on newlines when getting output from powershell