我怎样才能使createprocess重定向输入成功,我已经成功地得到了重定向输出结果

     2023-02-16     232

关键词:

【中文标题】我怎样才能使createprocess重定向输入成功,我已经成功地得到了重定向输出结果【英文标题】:How can i make createprocess reindirect input success, I have successully get the reindirect out put result 【发布时间】:2017-04-17 10:11:51 【问题描述】:

我在互联网上搜索了很多,但大多数都在谈论重定向输出。没有人给出任何成功的重定向输入示例。对于下面的代码,当我运行命令“ipconfig”或“192.168.0.10”时它给出了正确的输出,因为子进程在运行这些命令后结束,不需要输入。但是当我运行命令“ftp”而不是“ipconfig”时,控制台的子进程正在等待下一个输入命令。如您所见,在这种情况下,我尝试将 11111 作为控制台的输入。但是控制台没有收到我的输入命令并永远等待输入命令。如何在此程序中成功响应“ftp”命令并保持控制台运行

#include <windows.h>
#include <fstream>
using namespace std;

int WINAPI WinMain(
                   HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpComLine,
                   int nCmdShow)

    SECURITY_ATTRIBUTES secAttr; 
    HANDLE hRead,hWrite;

char command[256];
char testBuf[256] = 0;
    strcpy(command, "ipconfig");
//  strcpy(command, "ping 192.168.0.10")    
//  strcpy(command, "ftp");

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

HANDLE hTxtFile = CreateFile("tmp.txt", GENERIC_ALL, 0, &secAttr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hTxtFile == INVALID_HANDLE_VALUE)

    MessageBox(NULL, "Error createfile", NULL, MB_OK);
    return 0;

HANDLE hWriteFile = CreateFile("Write.txt", GENERIC_WRITE, 0, &secAttr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hWriteFile == INVALID_HANDLE_VALUE)

    MessageBox(NULL, "Error createWritefile", NULL, MB_OK);
    return 0;


STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo; 
startupInfo.cb = sizeof(STARTUPINFO); 
GetStartupInfo(&startupInfo); 
startupInfo.hStdError = hTxtFile;    
startupInfo.hStdOutput = hTxtFile;
startupInfo.hStdInput = hWriteFile;
startupInfo.wShowWindow = SW_SHOW; 
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

char output[10240] = 0;
DWORD bytesRead;

if (!CreateProcess(NULL, command,NULL,NULL,TRUE,NULL,NULL,NULL,&startupInfo,&processInfo)) 
 
    MessageBox(NULL, "Error createprocess", NULL, MB_OK);
    CloseHandle(hWrite); 
    CloseHandle(hRead); 
    return FALSE; 
 

DWORD processExitCode = 0;
strcpy(testBuf, "11111\r\n");
while (GetExitCodeProcess(processInfo.hProcess, &processExitCode))

    WriteFile(hWriteFile, testBuf, 7, &bytesRead, NULL);
    if (processExitCode != STILL_ACTIVE) 
    
        //  MessageBox(NULL, "End process", NULL, MB_OK);
        break;
    
    Sleep(1000);


SetFilePointer(hTxtFile, NULL, NULL, FILE_BEGIN);
ReadFile(hTxtFile, output, 10240, &bytesRead, NULL);
CloseHandle(hTxtFile);

MessageBox(NULL, output, NULL, MB_OK);

return 0;

【问题讨论】:

1) 需要关闭句柄,但您不这样做 2) hStdInput 必须有 FILE_GENERIC_READ 访问权限 3) 大多数程序在查看空输入时(NumberOfBytesRead == 0ZwReadFile return STATUS_END_OF_FILE )简单地退出 - 因此您的代码将无法与文件系统文件一起使用。或者您需要在创建进程之前将数据写入hStdInput 4) 一般说明 - 在使用时使用同步共享文件 - 不正确 - 文件共享 CurrentByteOffset。当您调用 WriteFile 时,您不能从您认为的位置写入,因为子进程可以更改位置(这可以通过在 OVERLAPPED 中使用直接偏移来避免)。您在共享文件对象中的写入更改 CurrentByteOffset 并影响子进程 5)使用 processExitCode != STILL_ACTIVE 不是 100% 可靠的方式 - 如果子调用 ExitProcess(STILL_ACTIVE) 怎么办? 我已经在我的项目中发现了问题,所以基本上当我们使用 STARTF_USESTDHANDLES 属性时。 createprocess 将创建非交互式控制台,这意味着它只能在 createprocess 调用中运行一个命令行。知道我可以使用 createprocess 创建一个交互式重定向控制台,该控制台根据最后一个控制台输出获取用户输入吗?非常感谢 没有“非交互式控制台”之类的东西,由于您正在重定向输入,因此无论如何都不涉及控制台。问题是您试图像使用管道一样使用文件,这是行不通的。 ***.com/questions/26398214/redirect-ftp-pipe-in-c 在这里,我更改了我的代码,它现在可以正常工作,但我遇到了与这个 OP 相同的问题。当我们在真实控制台中输入“ftp”或“wmic”时,我们会收到“ftp>”,而当我们输入像“123”这样的无效命令时,我们会收到“无效命令”。但是这种父进程和子控制台进程之间的交互操作并没有发生在我的代码或我在互联网上找到的所有重定向程序中。所以还没有真正看到一个 VC 控制台像真正的 cmd.exe 控制台一样工作 【参考方案1】:

重定向(不是“重定向”)输入的工作方式与重定向输出相同。当然,数据的流动方向是相反的。这意味着进程从文件中读取。这反过来意味着当您打开一个句柄进行写入时,就像您在示例代码中所做的那样:

HANDLE hWriteFile = CreateFile("Write.txt", GENERIC_WRITE, ...);

进程将无法从中读取。您必须打开文件才能阅读:

HANDLE hWriteFile = CreateFile("Write.txt", GENERIC_READ, ...);

但是,这也意味着您必须提前准备好要发送到流程的输入。 在创建进程之后写入文件没有帮助。

如果您事先不知道必须发送到进程的数据,则不能将文件用于标准输入,但必须使用其他东西,例如(命名或匿名)管道。

【讨论】:

【参考方案2】:

您必须重定向控制台输出,然后将缓冲区写入文件

1)

    /* Create a pipe for the child process's STDOUT */
    if(!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
        BAIL_OUT(-1);

2)

    /* Duplicate the pipe HANDLE */
    if (!DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(), &hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
        BAIL_OUT(-1);

3)

CHAR chBuf[BUFSIZE];
    DWORD dwRead;
    DWORD dwAvail = 0;
    if (!PeekNamedPipe(hChildStdoutRdDup, NULL, 0, NULL, &dwAvail, NULL) || !dwAvail)
        return;
    if (!ReadFile(hChildStdoutRdDup, chBuf, min(BUFSIZE - 1, dwAvail), &dwRead, NULL) || !dwRead)
        return;
    chBuf[dwRead] = 0;

请在此处找到更多详细信息: https://www.codeproject.com/Articles/5531/Redirecting-an-arbitrary-Console-s-Input-Output

【讨论】:

***.com/questions/26398214/redirect-ftp-pipe-in-c 在这里,我更改了我的代码,它现在可以完美运行,但我遇到了与这个 OP 相同的问题。当我们在真实控制台中输入“ftp”或“wmic”时,我们会收到“ftp>”,而当我们输入像“123”这样的无效命令时,我们会收到“无效命令”。但是这种父进程和子控制台进程之间的交互操作并没有发生在我的代码或我在互联网上找到的所有重定向程序中。我下载了这个demo,运行时也出现了同样的问题

我怎样才能使我的应用程序 MS EDGE 兼容

】我怎样才能使我的应用程序MSEDGE兼容【英文标题】:howcanimakemyApplicationMSEDGEcompatible【发布时间】:2021-01-0806:15:42【问题描述】:我目前正在为我的应用程序使用IE11。我的老板提出了使应用程序MSEDGE兼容的新要求。我今天尝试... 查看详情

使用 CreateProcess () 和 CreatePipe() 从 cmd.exe 重定向 I/O

】使用CreateProcess()和CreatePipe()从cmd.exe重定向I/O【英文标题】:RedirectingI/Ofromcmd.exeusingCreateProcess()andCreatePipe()【发布时间】:2020-09-0306:20:28【问题描述】:我的问题是我无法使用管道从命令行获取输出。我的任务:“将命令输入... 查看详情

将输入传递给由 CreateProcess() 创建的进程

】将输入传递给由CreateProcess()创建的进程【英文标题】:PassinganinputtotheprocesscreatedbyCreateProcess()【发布时间】:2011-02-1916:21:11【问题描述】:就像标题一样,我想知道是否可以通过在CreateProcess()中使用重定向运算符来传递输入。... 查看详情

Windows CreateProcess 和输出重定向

】WindowsCreateProcess和输出重定向【英文标题】:WindowsCreateProcessandoutputredirection【发布时间】:2016-03-1611:31:58【问题描述】:我在一个C项目中工作,使用WinAPI的windows环境。我的函数执行作为参数接收的命令(e.g.:"dirC:\\Users")... 查看详情

使用重定向的标准输入处理子进程中的 kbhit

...我编写了一个程序,它启动另一个进程并使用WindowsAPI(CreateProcess、CreatePipe等)将其标准I/O重定向到管道程序应该启动多个不同的控制台程序并使用stdio与它们通信。这一切都运行良好( 查看详情

在输出管道上拒绝重定向访问的 CreateProcess

】在输出管道上拒绝重定向访问的CreateProcess【英文标题】:CreateProcesswithredirectionaccessdeniedontheoutputpipe【发布时间】:2009-12-0900:48:12【问题描述】:我有一个在从MFC应用程序调用的DLL中运行的简单代码。通常,它实现了msdn文章中... 查看详情

如果输入是元组,我怎样才能使我的代码工作?

】如果输入是元组,我怎样才能使我的代码工作?【英文标题】:HowcanImakemycodeworkiftheinputisatuple?【发布时间】:2022-01-1503:03:58【问题描述】:所以我在一些StackOverflow用户的帮助下编写了这段代码......它试图分析我的元组l并查看... 查看详情

c语言编程:createprocess标准输出重定向到文件(代码片段)

说明:  CreateProcess创建进程执行不支持简单的>符号重定向,system之类的函数执行外部进程可以使用>符号直接重定向到文件,但是system这类函数执行命令时,都会弹出控制台窗口,而CreateProcess创建执行进程可... 查看详情

createprocess控制台程序输出重定向

     在Windows编程中,并非每一个应用程序都需要一个图形用户界面(GUI),很多情况下,我们可以编写一个控制台应用程序,这样程序更小,加载更快,传输时间也短,同时也丝毫不牺牲程序应有的功能。这种程序特别... 查看详情

windows:如何使用createprocess停止重定向stdout的缓冲(代码片段)

我正在使用管道从命令行可执行文件中获取重定向的stdout输出。不幸的是,在完成该过程之前,我没有得到任何输出。可执行文件在运行时输出进度状态,这就是我要解析的内容。BOOLRunCmd(char*pCmd,char*pWorkingDir,intnWaitSecs,BOOLfRegImpo... 查看详情

外壳附加重定向替换现有文本?

】外壳附加重定向替换现有文本?【英文标题】:Shellappendredirectionreplacesexistingtext?【发布时间】:2019-06-0112:12:25【问题描述】:对于我们的学校作业,我们必须实现输入/输出重定向。我设法使输入和输出重定向工作,但我面临... 查看详情

如何使输入类型=按钮像超链接一样使用获取请求进行重定向? [复制]

...如何使输入类型=按钮像超链接一样使用获取请求进行重定向?[复制]【英文标题】:Howtomakeaninputtype=buttonactlikeahyperlinkandredirectusingagetrequest?[duplicate]【发布时间】:2011-03-1905:39:10【问题描述】:如何使&lt;inputtype=button&gt;像... 查看详情

通过Vuejs调用时如何使Nodejs重定向工作

】通过Vuejs调用时如何使Nodejs重定向工作【英文标题】:howtomakeNodejsredirectworkwhencalledviaVuejs【发布时间】:2019-01-2600:14:46【问题描述】:我已经在Nodejs中创建并测试了POST和GET请求方法,这样我就可以完美地通过Gocardless注册API发... 查看详情

使其只能通过重定向访问 url

...al付款重定向到register.html,以便您只有在支付订阅费用后才能注册。如何才能使此重定向成为访问页面的唯一方法,而不是简单地将mysite.com/register放入浏览器?我有需要登录的页面,但显然这是在用 查看详情

windows 窗体刷新 - 我怎样才能使它更平滑?

】windows窗体刷新-我怎样才能使它更平滑?【英文标题】:windowsformrefresh-howcanimakeitsmoother?【发布时间】:2020-07-0610:51:36【问题描述】:我在窗口窗体上绘制了一个小迷宫,并在每次按键事件时重新绘制它。我怎样才能使它更顺... 查看详情

linux学习输入输出重定向和管道功能cat命令more命令(代码片段)

目录输入输出重定向输出重定向管道功能cat命令more命令@(输入输出重定向和管道功能)输入输出重定向输入重定向可以让用户将某个文件作为输入设备,输出重定向可以把某个文件作为输出设备,从而使文件更加灵活输入重定向... 查看详情

如何将 gzip 输出重定向到 Popen 标准输入

...结果传递到进程stdin?我发现,Popen构造函数需要stdin参数才能成为具有fileno方法的对象。在python2.7中gzip没有decompress功能。还有,为什么Popen不能接受没有filen 查看详情

如何使弹簧安全重定向

】如何使弹簧安全重定向【英文标题】:Howtomakespringsecurityredirect【发布时间】:2016-09-2909:22:04【问题描述】:我有两个jsp页面:第1页和第2页。默认打开第1页,但要打开它,用户需要有正确的角色。当用户没有正确的角色访问... 查看详情