如何使用 CreateProcess 函数正确调用“telnet”?

Posted

技术标签:

【中文标题】如何使用 CreateProcess 函数正确调用“telnet”?【英文标题】:How correctly call "telnet" with CreateProcess function? 【发布时间】:2019-05-04 21:49:48 【问题描述】:

我想通过 cmd.exe 启动“telnet”并将这个命令的执行结果写入文件。当我运行“ipconfig”命令时,我得到了我需要的所有信息,但在运行“telnet”命令后,我得到的只是空文件。

这是我的代码:

#include "windows.h"
#include "iostream"

void SaveResult(const wchar_t *fileName, const wchar_t *commandLine)

    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    HANDLE h = CreateFile(fileName, FILE_WRITE_DATA, FILE_SHARE_WRITE | FILE_SHARE_READ,
        &sa, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (h == INVALID_HANDLE_VALUE)
        return;

    PROCESS_INFORMATION pi =  0 ;
    STARTUPINFO si =  sizeof(si) ;
    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdInput = NULL;
    si.hStdError = h;
    si.hStdOutput = h;

    wchar_t *writable_cmdline = _wcsdup(commandLine);
    BOOL success = CreateProcess(NULL, writable_cmdline,
        NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);

    bool finished = false;

    //wait for 1 second
    for (int i = 0; i < 10; i++)
    
        if (WaitForSingleObject(pi.hProcess, 100) <= 0)
        
            finished = true;
            break;
        
    

    if (success)
    
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    

    CloseHandle(h);
    free(writable_cmdline);

    if (!finished)
        printf("Process didn't finish\n");



int main()

    SaveResult(L"telnet.txt", L"C:\\windows\\system32\\cmd.exe /c telnet test.com");
    SaveResult(L"ipconfig.txt", L"C:\\windows\\system32\\cmd.exe /c ipconfig");
    return 0;

【问题讨论】:

这里有很多非常奇怪的代码。不检查success 的值是一个糟糕的开始。去做。而CreateProcess 失败,请致电GetLastError 找出原因。拨打WaitForSingleObject 10 次毫无意义。调用一次,超时时间长 10 倍。最好希望1s就足够了。如果不是呢?如果CreateProcess 失败,则调用WaitForSingleObject 是错误的。最后,新手程序员最缺乏的技能就是调试。花一些时间学习如何调试您的程序。 你需要这个做什么? WinAPI 提供WinINet 用于直接上网 【参考方案1】:

您是否直接在 cmd 控制台中运行 telnet 命令?有什么输出吗?如果是这样,空文件可能是因为缓冲区尚未刷新到文件。正如@David 指出的那样, 您只需等待 1 秒,但如果连接的时间超过 1 秒,那么您将关闭处理程序而不刷新缓冲区。尝试在CloseHandle(h) 之前添加FlushFileBuffers(h)。 对于WaitForSingleObject,可以试试WaitForSingleObject(pi.hProcess, INFINITE),等到telnet进程退出。

【讨论】:

以上是关于如何使用 CreateProcess 函数正确调用“telnet”?的主要内容,如果未能解决你的问题,请参考以下文章

CreateProcess 函数中的问题!

cmd.exe 在使用 CreateProcess 调用后立即关闭

被粘滞键调用时 CreateProcess 访问被拒绝

CreateProcess 杀死 PC

Hook CreateProcess

如何使用win32 CreateProcess函数等到孩子完成写入文件