最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Unable to retrieve the WSL output - Stack Overflow

programmeradmin1浏览0评论

I'm trying to execute WSL commands from a C++ program using the CreateProcess function and capture their output through pipes. However, I am encountering an issue where the output is either empty or only one character is returned. I want the whole output to be captured and returned by the executeWSLCommand function.

Any help or suggestions would be greatly appreciated!

Here is my code that executes a WSL command and tries to capture its output:

#include <windows.h>
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
#include <cstring>

std::string executeWSLCommand(const std::string& command) {
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi = { 0 };

    // Create a mutable buffer for the command
    std::wstring fullCommand = L"wsl.exe " + std::wstring(command.begin(), command.end());
    wchar_t cmdBuffer[1024];
    wcscpy_s(cmdBuffer, fullCommand.c_str());

    // Create pipes for STDOUT and STDERR
    HANDLE hRead, hWrite;
    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE }; // Allow pipe handles to be inherited
    if (!CreatePipe(&hRead, &hWrite, &sa, 0)) {
        std::cerr << "Failed to create pipe. Error: " << GetLastError() << std::endl;
        return "";
    }

    // Ensure the read handle to the pipe is not inherited
    SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0);

    // Configure STARTUPINFO to use the pipe for output
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdOutput = hWrite;
    si.hStdError = hWrite;

    // Start the WSL process
    if (!CreateProcess(
        nullptr,           // Application name
        cmdBuffer,         // Command line
        nullptr,           // Process security attributes
        nullptr,           // Thread security attributes
        TRUE,              // Inherit handles
        CREATE_NO_WINDOW,  // Creation flags
        nullptr,           // Environment
        nullptr,           // Current directory
        &si,               // STARTUPINFO pointer
        &pi                // PROCESS_INFORMATION pointer
    )) {
        std::cerr << "Failed to execute command. Error: " << GetLastError() << std::endl;
        CloseHandle(hRead);
        CloseHandle(hWrite);
        return "";
    }

    // Close the write end of the pipe (parent process does not write)
    CloseHandle(hWrite);

    // Read the output from the read end of the pipe
    std::string output;
    char buffer[4096];
    DWORD bytesRead;

    while (ReadFile(hRead, buffer, sizeof(buffer) - 1, &bytesRead, nullptr) && bytesRead > 0) {
        buffer[bytesRead] = '\0';
        output += buffer;
    }

    // Close handles
    CloseHandle(hRead);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return output;
}

int main() {
    // Example: Get the list of WSL distributions
    std::string distributions = executeWSLCommand("--list --quiet");
    std::istringstream iss(distributions);
    std::string distribution;

    // Loop through each distribution and check for /etc/shb-release
    while (std::getline(iss, distribution)) {
        std::string command = "-d " + distribution + " -- ls /etc/shb-release";
        std::string result = executeWSLCommand(command);

        if (result.find("No such file or directory") != std::string::npos) {
            std::cerr << "Error: /etc/shb-release not found in distribution " << distribution << std::endl;
        } else {
            std::cout << "/etc/shb-release found in distribution " << distribution << std::endl;
        }
    }

    return 0;
}
发布评论

评论列表(0)

  1. 暂无评论