C++ 无法识别创建进程'telnet'



当我将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.exetelnetwuauclt启动吗?

同样在这台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;
}

如果在控制台窗口中键入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 finishn");
}

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

最新更新