简体   繁体   English

Windows 应用程序无法写入远程控制台

[英]Windows application can't write to remote console

I have a simple function to initialize console in application compiled with "/SUBSYSTEM:WINDOWS" option:我有一个简单的函数来初始化使用“/SUBSYSTEM:WINDOWS”选项编译的应用程序中的控制台:

bool InitConsole()
{
    HANDLE consoleHandleOut, consoleHandleErr;

    //we run only in console
    if (!AttachConsole(ATTACH_PARENT_PROCESS))
        return false;

    consoleHandleOut = GetStdHandle(STD_OUTPUT_HANDLE);
    consoleHandleErr = GetStdHandle(STD_ERROR_HANDLE);

    if ((consoleHandleOut != INVALID_HANDLE_VALUE)
    && (consoleHandleErr != INVALID_HANDLE_VALUE))
    {
        freopen_s(&fp, "CONOUT$", "w+", stdout);
        freopen_s(&fp, "CONOUT$", "w+", stderr);
        setvbuf(stderr, NULL, _IONBF, 0);
        setvbuf(stdout, NULL, _IONBF, 0);
    }
    else
        return false;    

    return true;
}

This function works well, when I run an application using PowerShell or CMD on any local computer.当我在任何本地计算机上使用 PowerShell 或 CMD 运行应用程序时,此功能运行良好。 However, I need to run this app using remote PowerShell/Cmd, which has started using this piece of code:但是,我需要使用远程 PowerShell/Cmd 运行这个应用程序,它已经开始使用这段代码:

STARTUPINFO ini_processo;
PROCESS_INFORMATION processo_info;
memset(&ini_processo, 0, sizeof(ini_processo));

ini_processo.cb = sizeof(ini_processo);
ini_processo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
ini_processo.hStdInput = ini_processo.hStdOutput = ini_processo.hStdError = (HANDLE)ConnectSocket;
ini_processo.wShowWindow = SW_HIDE;

if (CreateProcess(NULL, PSPath, NULL, NULL, TRUE, 0, NULL, NULL, &ini_processo, &processo_info))
{
    CloseHandle(processo_info.hThread);
    CloseHandle(processo_info.hProcess);
}

I use ConnectSocket handle to get all output.我使用 ConnectSocket 句柄来获取所有输出。 After closing process handles, program exits immediately to leave powershell with connected socket.关闭进程句柄后,程序立即退出,离开带有连接套接字的 powershell。 So, later I run my app using this powershell and expect to get some output.所以,后来我使用这个 powershell 运行我的应用程序,并期望得到一些输出。

It does work with any application compiled for console subsystem as well it works with any commands like ls, ps, dir, etc. But it does not work with my program.它确实适用于为控制台子系统编译的任何应用程序,也适用于任何命令,如 ls、ps、dir 等。但它不适用于我的程序。 Function InitConsole() always returns TRUE.函数 InitConsole() 总是返回 TRUE。 I can write console like always using "fprintf(stdout, fmt, ## VA_ARGS )", but I have no output at all.我可以像往常一样使用“fprintf(stdout, fmt, ## VA_ARGS )”编写控制台,但我根本没有输出。 I feel like I write to "another" console, because I do not get errors.我觉得我写信给“另一个”控制台,因为我没有收到错误。

Why is my program does not display anything?为什么我的程序不显示任何内容?

I can write console like always using "fprintf(stdout, fmt, ##VA_ARGS)", but I have no output at all.我可以像往常一样使用“fprintf(stdout, fmt, ##VA_ARGS)”编写控制台,但我根本没有输出。 I feel like I write to "another" console, because I do not get errors.我觉得我写信给“另一个”控制台,因为我没有收到错误。

When you launch cmd.exe, you then exit from your app immediately, which closes the socket.当您启动 cmd.exe 时,您会立即退出您的应用程序,从而关闭套接字。 You need to keep the socket open for the lifetime of the cmd.exe process.您需要在 cmd.exe 进程的生命周期内保持套接字打开。

Modify:调整:

CloseHandle(processo_info.hThread);
WaitForSingleObject(processo_info.hProcess, INFINITE);
CloseHandle(processo_info.hProcess);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM