Skip to main content
Notice removed Draw attention by CommunityBot
Bounty Ended with no winning answer by CommunityBot
Notice added Draw attention by hoffmale
Bounty Started worth 50 reputation by hoffmale
fixed small bug, `process::terminate` used hardcoded default value in calls instead of the provided parameter
Source Link
hoffmale
  • 6.5k
  • 17
  • 41
#include "process.hpp"

namespace win32
{
    process::process(const std::string& executable_path, const std::string& command_line_args, process_creation_flags flags)
    {
        std::copy(std::begin(command_line_args), std::end(command_line_args), std::back_inserter(cmdline));
        cmdline.push_back('\0');

        STARTUPINFOA startup_info;
        GetStartupInfoA(&startup_info);

        if (!CreateProcessA(executable_path.c_str(), cmdline.data(), nullptr, nullptr, false, static_cast<DWORD>(flags), nullptr, nullptr, &startup_info, &process_info))
        {
            throw std::runtime_error("process creation failed!");
        }
    }

    process::process(process &&other) noexcept : cmdline{ std::move(other.cmdline) }, process_info{ other.process_info }
    {
        other.process_info.hThread = INVALID_HANDLE_VALUE;
        other.process_info.hProcess = INVALID_HANDLE_VALUE;
    }

    process & process::operator=(process &&other) noexcept
    {
        terminate();

        cmdline = std::move(other.cmdline);
        process_info = other.process_info;

        other.process_info.hThread = INVALID_HANDLE_VALUE;
        other.process_info.hProcess = INVALID_HANDLE_VALUE;

        return *this;
    }

    void process::terminate(int exit_code)
    {
        if (process_info.hThread != INVALID_HANDLE_VALUE)
        {
            TerminateThread(process_info.hThread, 0exit_code);
            CloseHandle(process_info.hThread);
            process_info.hThread = INVALID_HANDLE_VALUE;
        }

        if (process_info.hProcess != INVALID_HANDLE_VALUE) {
            TerminateProcess(process_info.hProcess, 0exit_code);
            CloseHandle(process_info.hProcess);
            process_info.hProcess = INVALID_HANDLE_VALUE;
        }
    }

    process::~process() noexcept
    {
        terminate();
    }
}
#include "process.hpp"

namespace win32
{
    process::process(const std::string& executable_path, const std::string& command_line_args, process_creation_flags flags)
    {
        std::copy(std::begin(command_line_args), std::end(command_line_args), std::back_inserter(cmdline));
        cmdline.push_back('\0');

        STARTUPINFOA startup_info;
        GetStartupInfoA(&startup_info);

        if (!CreateProcessA(executable_path.c_str(), cmdline.data(), nullptr, nullptr, false, static_cast<DWORD>(flags), nullptr, nullptr, &startup_info, &process_info))
        {
            throw std::runtime_error("process creation failed!");
        }
    }

    process::process(process &&other) noexcept : cmdline{ std::move(other.cmdline) }, process_info{ other.process_info }
    {
        other.process_info.hThread = INVALID_HANDLE_VALUE;
        other.process_info.hProcess = INVALID_HANDLE_VALUE;
    }

    process & process::operator=(process &&other) noexcept
    {
        terminate();

        cmdline = std::move(other.cmdline);
        process_info = other.process_info;

        other.process_info.hThread = INVALID_HANDLE_VALUE;
        other.process_info.hProcess = INVALID_HANDLE_VALUE;

        return *this;
    }

    void process::terminate(int exit_code)
    {
        if (process_info.hThread != INVALID_HANDLE_VALUE)
        {
            TerminateThread(process_info.hThread, 0);
            CloseHandle(process_info.hThread);
            process_info.hThread = INVALID_HANDLE_VALUE;
        }

        if (process_info.hProcess != INVALID_HANDLE_VALUE) {
            TerminateProcess(process_info.hProcess, 0);
            CloseHandle(process_info.hProcess);
            process_info.hProcess = INVALID_HANDLE_VALUE;
        }
    }

    process::~process() noexcept
    {
        terminate();
    }
}
#include "process.hpp"

namespace win32
{
    process::process(const std::string& executable_path, const std::string& command_line_args, process_creation_flags flags)
    {
        std::copy(std::begin(command_line_args), std::end(command_line_args), std::back_inserter(cmdline));
        cmdline.push_back('\0');

        STARTUPINFOA startup_info;
        GetStartupInfoA(&startup_info);

        if (!CreateProcessA(executable_path.c_str(), cmdline.data(), nullptr, nullptr, false, static_cast<DWORD>(flags), nullptr, nullptr, &startup_info, &process_info))
        {
            throw std::runtime_error("process creation failed!");
        }
    }

    process::process(process &&other) noexcept : cmdline{ std::move(other.cmdline) }, process_info{ other.process_info }
    {
        other.process_info.hThread = INVALID_HANDLE_VALUE;
        other.process_info.hProcess = INVALID_HANDLE_VALUE;
    }

    process & process::operator=(process &&other) noexcept
    {
        terminate();

        cmdline = std::move(other.cmdline);
        process_info = other.process_info;

        other.process_info.hThread = INVALID_HANDLE_VALUE;
        other.process_info.hProcess = INVALID_HANDLE_VALUE;

        return *this;
    }

    void process::terminate(int exit_code)
    {
        if (process_info.hThread != INVALID_HANDLE_VALUE)
        {
            TerminateThread(process_info.hThread, exit_code);
            CloseHandle(process_info.hThread);
            process_info.hThread = INVALID_HANDLE_VALUE;
        }

        if (process_info.hProcess != INVALID_HANDLE_VALUE) {
            TerminateProcess(process_info.hProcess, exit_code);
            CloseHandle(process_info.hProcess);
            process_info.hProcess = INVALID_HANDLE_VALUE;
        }
    }

    process::~process() noexcept
    {
        terminate();
    }
}
deleted 1 character in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

using Using multiple console windows for output

In my current project I found the need to concurrently track the progress of multiple concurrent components, and having all of them output their (debug) information into a single console window made things very unorganised. So I wrote this little library so I can now display each componentscomponent's output in a dedicated console window.

  • As windowsWindows only allows 1 console per process, I need to start a little helper process per additional console. The path is currently hard-coded, but that can easily be changed.
  • The process wrapper is very minimalistic - it only does what is necessary for this library to work and nothing more. (I might extend it in the future, though.)

using multiple console windows for output

In my current project I found the need to concurrently track the progress of multiple concurrent components, and having all of them output their (debug) information into a single console window made things very unorganised. So I wrote this little library so I can now display each components output in a dedicated console window.

  • As windows only allows 1 console per process, I need to start a little helper process per additional console. The path is currently hard-coded, but that can easily be changed.
  • The process wrapper is very minimalistic - it only does what is necessary for this library to work and nothing more. (I might extend it in the future, though.)

Using multiple console windows for output

In my current project I found the need to concurrently track the progress of multiple concurrent components, and having all of them output their (debug) information into a single console window made things very unorganised. So I wrote this little library so I can now display each component's output in a dedicated console window.

  • As Windows only allows 1 console per process, I need to start a little helper process per additional console. The path is currently hard-coded, but that can easily be changed.
  • The process wrapper is very minimalistic - it only does what is necessary for this library to work and nothing more. (I might extend it in the future, though.)
Tweeted twitter.com/StackCodeReview/status/1000008804350726146
fixed include path
Source Link
hoffmale
  • 6.5k
  • 17
  • 41
#include <windows.h>
#include <iostream>
#include "../win32utils/pipe"pipe.hpp"
#include <array>

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        std::cerr << "not enough arguments\n" << "call syntax: console_helper [title] [pipe name]" << std::endl;
        return -1;
    }

    try {
        SetConsoleTitleA(argv[1]);
        auto pipe = win32::pipe::open(argv[2], win32::pipe_mode::read);

        auto buffer = std::array<char, 1024>{};

        for (;;)
        {
            const auto bytes_read = pipe.read(win32::buffer{ buffer.data(), buffer.size() });
            std::cout.write(buffer.data(), bytes_read);
        }
    }
    catch(std::exception& ex)
    {
        std::cerr << "Caught exception: " << ex.what() << std::endl;
        std::cin.get();
    }

    return 0;
}
#include <windows.h>
#include <iostream>
#include "../win32utils/pipe.hpp"
#include <array>

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        std::cerr << "not enough arguments\n" << "call syntax: console_helper [title] [pipe name]" << std::endl;
        return -1;
    }

    try {
        SetConsoleTitleA(argv[1]);
        auto pipe = win32::pipe::open(argv[2], win32::pipe_mode::read);

        auto buffer = std::array<char, 1024>{};

        for (;;)
        {
            const auto bytes_read = pipe.read(win32::buffer{ buffer.data(), buffer.size() });
            std::cout.write(buffer.data(), bytes_read);
        }
    }
    catch(std::exception& ex)
    {
        std::cerr << "Caught exception: " << ex.what() << std::endl;
        std::cin.get();
    }

    return 0;
}
#include <windows.h>
#include <iostream>
#include "pipe.hpp"
#include <array>

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        std::cerr << "not enough arguments\n" << "call syntax: console_helper [title] [pipe name]" << std::endl;
        return -1;
    }

    try {
        SetConsoleTitleA(argv[1]);
        auto pipe = win32::pipe::open(argv[2], win32::pipe_mode::read);

        auto buffer = std::array<char, 1024>{};

        for (;;)
        {
            const auto bytes_read = pipe.read(win32::buffer{ buffer.data(), buffer.size() });
            std::cout.write(buffer.data(), bytes_read);
        }
    }
    catch(std::exception& ex)
    {
        std::cerr << "Caught exception: " << ex.what() << std::endl;
        std::cin.get();
    }

    return 0;
}
Source Link
hoffmale
  • 6.5k
  • 17
  • 41
Loading