Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;创建流程';telnet';不被承认_C++_Winapi - Fatal编程技术网

C++ C++;创建流程';telnet';不被承认

C++ C++;创建流程';telnet';不被承认,c++,winapi,C++,Winapi,当我将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,

当我将
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);
但是当我通过
wauclt
telnet

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);
我明白了

“wAUCLT”未被识别为内部或外部命令, 可操作的程序或批处理文件。 “telnet”未被识别为内部或外部命令, 可操作的程序或批处理文件

如何解决此问题以及为什么会发生此问题?是否可以通过cmd.exe
telnet
wauclt
启动

同样在这台电脑上,从一开始就像预期的那样打开公共控制台中的
wauclt
telnet

#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;
}

如果您在控制台窗口中键入
ipconfig
,进程将显示IP信息并退出

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

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

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

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

请注意,建议对Unicode程序使用宽字符串。将ANSI推广到UTF16是很好的,但在这种情况下并没有获得多少好处。您还可以将
CreateProcessA
STARTUPINFOA si={sizeof(si)}一起使用接受ANSI字符

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;
}
void SaveResult(常量wchar\u t*文件名,常量wchar\u t*命令行)
{
安全(a);
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;
HANDLE h=CreateFile(文件名、文件写入数据、文件共享写入、文件共享读取、,
&sa,始终打开,文件属性正常,空);
if(h==无效的\u句柄\u值)
返回;
进程信息pi={0};
STARTUPINFO si={sizeof(si)};
si.dwFlags |=STARTF_USESTDHANDLES;
si.hStdInput=NULL;
si.hStdError=h;
si.hst输出=h;
wchar\u t*可写的\u cmdline=\u wcsdup(命令行);
BOOL success=CreateProcess(空,可写\u cmdline,
NULL,NULL,TRUE,创建\u否\u窗口,NULL,NULL,&si,&pi);
bool finished=false;
//等一秒钟
对于(int i=0;i<10;i++)
{

如果(WaitForSingleObject(pi.hProcess,100)在控制台窗口中键入
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;
}
void SaveResult(常量wchar\u t*文件名,常量wchar\u t*命令行)
{
安全(a);
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;
HANDLE h=CreateFile(文件名、文件写入数据、文件共享写入、文件共享读取、,
&sa,始终打开,文件属性正常,空);
if(h==无效的\u句柄\u值)
返回;
进程信息pi={0};
STARTUPINFO si={sizeof(si)};
si.dwFlags |=STARTF_USESTDHANDLES;
si.hStdInput=NULL;
si.hStdError=h;
si.hst输出=h;
wchar\u t*可写的\u cmdline=\u wcsdup(命令行);
BOOL success=CreateProcess(空,可写\u cmdline,
NULL,NULL,TRUE,创建\u否\u窗口,NULL,NULL,&si,&pi);
bool finished=false;
//等一秒钟
对于(int i=0;i<10;i++)
{

if(WaitForSingleObject(pi.hProcess,100)您能在不使用
CreateProcess
的情况下启动telnet或Wauclt吗?@AlgirdasPreidžius,是的,它工作正常。请尝试使用可执行文件的完整路径。@drescherjm,抱歉,不清楚您的意思。您给出了cmd的完整路径。也可以尝试使用telnet的完整路径。您能在不使用
CreateP的情况下启动telnet或Wauclt吗进程
?@AlgirdasPreidžius,是的,它工作正常。请尝试使用可执行文件的完整路径。@drescherjm,很抱歉,不清楚您的意思。您提供了cmd的完整路径。请尝试使用telnet的完整路径。