C++ 从另一个进程附加和使用控制台的代码有什么问题?
我有一个服务器进程,它的分配控制台,并将输出和输入重定向到那个控制台。使用ShellExecute这个服务器进程生成一些客户机,这些客户机知道服务器进程ID。因此,我在下一个类中尝试AttachConsole:C++ 从另一个进程附加和使用控制台的代码有什么问题?,c++,winapi,ipc,C++,Winapi,Ipc,我有一个服务器进程,它的分配控制台,并将输出和输入重定向到那个控制台。使用ShellExecute这个服务器进程生成一些客户机,这些客户机知道服务器进程ID。因此,我在下一个类中尝试AttachConsole: Console::Console(DWORD dwProcessId) { if (dwProcessId) { AttachConsole(dwProcessId); } else AllocConsole(); CON
Console::Console(DWORD dwProcessId)
{
if (dwProcessId) {
AttachConsole(dwProcessId);
}
else
AllocConsole();
CONSOLE_SCREEN_BUFFER_INFO coninfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = 500;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
int hConHandle;
long lStdHandle;
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
FILE *fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
std::ios::sync_with_stdio();
}
Console::~Console()
{
FreeConsole();
}
但它不起作用,它甚至从服务器进程中删除到控制台的输出。隐马尔可夫模型。。可能只有一个进程可以输出到控制台。可以从多个进程向控制台发送输出吗?您应该使用
CreateFile
打开CONOUT$
。附加到控制台不会更改进程继承的标准句柄。您应该使用CreateFile
打开CONOUT$
。附加到控制台不会更改进程继承的标准句柄。有人能告诉我为什么接下来的更改会使我的代码正常工作:
Console::Console(DWORD dwProcessId)
{
if (dwProcessId) {
AttachConsole(dwProcessId);
HANDLE consoleHandle = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (consoleHandle == INVALID_HANDLE_VALUE)
throw 1;
if (!SetStdHandle(STD_OUTPUT_HANDLE, consoleHandle))
throw 2;
}
else {
AllocConsole();
CONSOLE_SCREEN_BUFFER_INFO coninfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = 500;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
}
int hConHandle;
long lStdHandle;
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
FILE *fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
}
现在,使用ShellExecute创建的客户端可以写入服务器控制台。有人能告诉我,为什么接下来的更改会使我的代码正常工作:
Console::Console(DWORD dwProcessId)
{
if (dwProcessId) {
AttachConsole(dwProcessId);
HANDLE consoleHandle = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (consoleHandle == INVALID_HANDLE_VALUE)
throw 1;
if (!SetStdHandle(STD_OUTPUT_HANDLE, consoleHandle))
throw 2;
}
else {
AllocConsole();
CONSOLE_SCREEN_BUFFER_INFO coninfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = 500;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
}
int hConHandle;
long lStdHandle;
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
FILE *fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
}
现在,使用ShellExecute创建的客户端可以写入服务器控制台。如果这会擦除控制台,那么它就可以工作了。更改您不拥有的控制台的屏幕缓冲区是不明智的。当拥有控制台的进程也在写入时,写入也是如此。谢谢,我将控制台\屏幕\缓冲区\信息替换到调用AllocConsole的else部分。但它仍然不起作用。如果这抹去了控制台,那么它就起作用了。更改您不拥有的控制台的屏幕缓冲区是不明智的。当拥有控制台的进程也在写入时,写入也是如此。谢谢,我将控制台\屏幕\缓冲区\信息替换到调用AllocConsole的else部分。但它仍然不起作用。下一个代码也不起作用,根本没有输出,即使我只有一个没有客户端的服务器`HANDLE consoleHandle=CreateFileA(“CONOUT$”,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);if(consoleHandle==无效的句柄值)抛出1;如果(!SetStdHandle(标准输出句柄,控制台句柄))抛出2`抱歉,但是从何处继承句柄?我使用ShellExecute启动客户机,但不使用CreateProcess。谢谢。ShellExecute最终调用CreateProcess。如果您将客户端和服务器编译为控制台应用程序,您将不需要处理控制台。下一个代码也不起作用,即使只有没有客户端的服务器`HANDLE consoleHandle=CreateFileA(“CONOUT$”,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);if(consoleHandle==无效的句柄值)抛出1;如果(!SetStdHandle(标准输出句柄,控制台句柄))抛出2`抱歉,但是从何处继承句柄?我使用ShellExecute启动客户机,但不使用CreateProcess。谢谢。ShellExecute最终调用CreateProcess。如果将客户端和服务器编译为控制台应用程序,则无需处理控制台。