无法识别 C++ CreateProcess 'telnet'

Posted

技术标签:

【中文标题】无法识别 C++ CreateProcess \'telnet\'【英文标题】:C++ CreateProcess 'telnet' is not recognized无法识别 C++ CreateProcess 'telnet' 【发布时间】:2018-10-11 12:24:30 【问题描述】:

当我将ipconfig 命令传递给进程时,它会将正确的结果存储在文件中。

char cmd[] = "C:\\windows\\system32\\cmd.exe /c ipconfig";
SaveResult("ipconfig1.txt", NULL, cmd);

char appName[] = "C:\\windows\\system32\\cmd.exe";
char cmd2[] = "/c ipconfig";
SaveResult("ipconfig2.txt", appName, cmd2);

但是当我通过wuauclttelnet

char cmd1[] = "C:\\windows\\system32\\cmd.exe /c telnet";
SaveResult("telnet1.txt", NULL, cmd1);

char appName3[] = "C:\\windows\\system32\\cmd.exe";
char cmd3[] = "/c telnet";
SaveResult("telnet2.txt", appName3, cmd3);

char cmd4[] = "C:\\windows\\system32\\cmd.exe /c wuauclt";
SaveResult("wuauclt1.txt", NULL, cmd4);

char appName5[] = "C:\\windows\\system32\\cmd.exe";
char cmd5[] = "/c wuauclt";
SaveResult("wuauclt2.txt", appName5, cmd5);

我明白了

'wuauclt' 未被识别为内部或外部命令, 可运行的程序或批处理文件。 'telnet' 未被识别为内部或外部命令, 可运行的程序或批处理文件。

如何解决这个问题,为什么会这样?是否可以通过cmd.exe启动telnetwuauclt

同样在这台 PC 上的 wuauclttelnet 中的通用控制台从开始按预期打开。

#include "stdafx.h"
#include "windows.h"

wchar_t *convertCharArrayToLPCWSTR(const char* charArray)

    wchar_t* wString = new wchar_t[4096];
    MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 4096);
    return wString;


void SaveResult(const char *fileName, const char *appName, const char *commandLine)

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

    HANDLE h = CreateFile(convertCharArrayToLPCWSTR(fileName),
        FILE_APPEND_DATA,
        FILE_SHARE_WRITE | FILE_SHARE_READ,
        &sa,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    BOOL ret = FALSE;
    DWORD flags = CREATE_NO_WINDOW;

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdInput = NULL;
    si.hStdError = h;
    si.hStdOutput = h;

    ret = CreateProcess(appName==NULL ? NULL : convertCharArrayToLPCWSTR(appName), commandLine == NULL ? NULL : convertCharArrayToLPCWSTR(commandLine), NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);

    if (ret)
    
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        CloseHandle(h);
    

int main()

    char cmd[] = "C:\\windows\\system32\\cmd.exe /c ipconfig";
    SaveResult("ipconfig1.txt", NULL, cmd);

    char appName[] = "C:\\windows\\system32\\cmd.exe";
    char cmd2[] = "/c ipconfig";
    SaveResult("ipconfig2.txt", appName, cmd2);

    char cmd1[] = "C:\\windows\\system32\\cmd.exe /c telnet";
    SaveResult("telnet1.txt", NULL, cmd1);

    char appName3[] = "C:\\windows\\system32\\cmd.exe";
    char cmd3[] = "/c telnet";
    SaveResult("telnet2.txt", appName3, cmd3);

    char cmd4[] = "C:\\windows\\system32\\cmd.exe /c wuauclt";
    SaveResult("wuauclt1.txt", NULL, cmd4);

    char appName5[] = "C:\\windows\\system32\\cmd.exe";
    char cmd5[] = "/c wuauclt";
    SaveResult("wuauclt2.txt", appName5, cmd5);

    return -1;

【问题讨论】:

不使用CreateProcess可以启动telnet或wuauclt吗? @AlgirdasPreidžius,是的,它工作正常。 尝试使用可执行文件的完整路径。 @drescherjm,抱歉不清楚你的意思。 您提供了 cmd 的完整路径。也尝试使用 telnet 的完整路径。 【参考方案1】:

如果你在控制台输入ipconfig,进程会显示IP信息并退出。

另一方面,如果您在控制台窗口中输入telnet,该进程将显示提示并等待响应。该过程不会自动完成。

当您使用CreateProcess 运行此命令时,CreateProcess 将立即返回,但该过程尚未完成。然后你尝试关闭telnet仍在使用的文件句柄。

您可以使用WaitForSingleObject 等待该过程完成。在telnet 的情况下,该过程未完成。下面的例子演示了这个问题。

对于CreateProcess,提供整个命令行作为第二个参数。确保字符缓冲区是可写的,并在最后释放。

旁注,建议在 Unicode 程序中使用宽字符串。将 ANSI 提升为 UTF16 很好,但在这种情况下收获不多。您还可以将CreateProcessA 与接受ANSI 字符的STARTUPINFOA si = sizeof(si) ; 一起使用。

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");
    SaveResult(L"ipconfig.txt", L"C:\\windows\\system32\\cmd.exe /c ipconfig");
    return 0;

【讨论】:

以上是关于无法识别 C++ CreateProcess 'telnet'的主要内容,如果未能解决你的问题,请参考以下文章

C++ CreateProcess 无法从 Windows 7 上的套接字接收路径 (64)

在 C++ 中没有提升的语音识别或 msconfig

CreateProcess() C++ 文件未找到

C++ 如何使用 CreateProcess 来处理进程?

SetWinEventHook 与 CreateProcess, C++

带有参数死锁的 C++ CreateProcess