首页 > 解决方案 > 在附加控制台中输入文本时如何避免“不被识别为内部或外部命令、可运行程序或批处理文件”?

问题描述

我附上了现有的控制台表单 C++ 程序。输出工作正常,但是当我尝试在控制台中输入一些输入时,最初在那里运行的终端会尝试处理它。程序代码在这里:

#include <iostream>
#include "windows.h"

int main(int argc, char **argv)
{
    pid_t pid = atoi(argv[1]);
    BOOL fret = FreeConsole();
    if  (!fret)
    {
        std::cerr << "ERR" << GetLastError() << std::endl;
    }

    BOOL aret = AttachConsole(pid);

    if  (!aret)
    {
        std::cerr << "ERR" << GetLastError() << std::endl;
    }

    SetConsoleTitleA("TTTTTTTT");

    for (int ii = 0; ii < 10; ii++)
    {
        std::cout << "ii " << ii << std::endl;
    }

    int kk;
    std::cin >> kk;

    std::cerr << "kk " << kk << std::endl;

    return 0;
}

当我运行 cmd,找出 PID,运行我的程序,然后写例如 12 并输入,这是结果:

C:\>ii 0
ii 1
ii 2
ii 3
ii 4
ii 5
ii 6
ii 7
ii 8
ii 9
12
'12' is not recognized as an internal or external command,
operable program or batch file.

当我再次尝试写 12 时,效果更好(但仍然有 C:>)

C:\>12
kk 12
C:\>

编辑:我需要将标准输入、标准输出和标准错误重定向到控制台,我可以运行其他东西然后 cmd 或向 cmd 发送一些命令。

标签: c++windowswinapicmd

解决方案


“不被识别为内部或外部命令、可运行程序或批处理文件。” 是标准的 cmd.exe 错误消息。当您这样做时,cmd.exe 已经在等待输入,AttachConsole因此第一个输入被发送到 cmd.exe,这就是您收到该错误消息的原因。用类似命令替换第一个数字输入,dir您将看到 cmd.exe 接收到此输入。

第二次它起作用了,但主要是偶然的。cmd.exe 可能正忙于其他事情,因此您的应用程序在 cmd.exe 能够再次“收听”标准输入之前获得输入。cmd.exe 打印提示(“路径” + >),因为这是在执行每个命令后它所做的。

cmd.exe 不希望与其他任何人共享控制台,其正常操作模式是:

  1. 读取并解析stdin.
  2. 执行。如果命令是内部命令或外部控制台应用程序,请等待操作完成。它不等待 GUI 应用程序。
  3. 打印 %PROMPT%。
  4. 转到 1。

即使您可以说服 cmd.exe 与您共存,您所做的也可能是未定义的行为,因为您将低级本机 Windows 控制台函数 ( AttachConsole) 与高级 C++ I/O 函数 ( std::cout& std::cin) 混合在一起。假设您使用的是 Microsoft CRT,您可以使用_open_osfhandle+_dup2来正确分配本机控制台句柄,但您仍然会遇到 cmd.exe 问题,并且无法解决它。


推荐阅读