Zero03
Zero03

Reputation: 27

C++ Powershell not executing command properly?

So, I have a quick bit of code that should give me the drive serials that are currently installed on the system, however, when I run this, powershell gets an error. I'm not entirely sure what's wrong here, as when I type the command on powershell it works fine. Here is some of the code :

std::string exec(const char* cmd) {
    std::array<char, 128> buffer;
    std::string result;
    std::shared_ptr<FILE> pipe(_popen(cmd, "r"), _pclose);
    if (!pipe) throw std::runtime_error("_popen() failed!");
    while (!feof(pipe.get())) {
        if (fgets(buffer.data(), 128, pipe.get()) != NULL)
            result += buffer.data();
    }
    return result;
};

Later I call this:

std::string test = exec("powershell -ExecutionPolicy Bypass get-ciminstance Win32_LogicalDisk | % VolumeSerialNumber");

If this works correctly, I should have a string with multiple serial numbers on it (as I have multiple drives), however I don't. I get this powershell error that is printed into my console.

'%' is not recognized as an internal or external command,
operable program or batch file.

Anyone have any ideas on how to fix this? I tried adding a \ before the % but that didn't work either. Any help is greatly appreciated!

Upvotes: 1

Views: 578

Answers (1)

spectras
spectras

Reputation: 13542

_popen spawns cmd.exe to run your command.

The _popen function creates a pipe. It then asynchronously executes a spawned copy of the command processor, and uses command as the command line.

Thus the | is being interpreted by cmd, which tries to run % as a command.

Thus the output coming out of cmd:

'%' is not recognized as an internal or external command, operable program or batch file.

To fix it, I believe quoting the powershell program in the command should be enough.

exec("powershell -ExecutionPolicy Bypass \"get-ciminstance Win32_LogicalDisk | % VolumeSerialNumber\"");

Upvotes: 3

Related Questions