Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.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++ 如何使用CreateProcess执行简单的命令行?_C++_Winapi_Command Line - Fatal编程技术网

C++ 如何使用CreateProcess执行简单的命令行?

C++ 如何使用CreateProcess执行简单的命令行?,c++,winapi,command-line,C++,Winapi,Command Line,我想执行一个简单的命令行,但不想让窗口出现。因此,据我所知,我不能使用系统,必须使用CreateProcess。 例如,我有以下代码: //.../ CreateProcess(NULL,input,NULL,NULL,false,NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,NULL,NULL,&startInf,&procInf);//) //.../ 如果输入像“ping www.google.com-n2”这样的行,它似乎可以

我想执行一个简单的命令行,但不想让窗口出现。因此,据我所知,我不能使用系统,必须使用CreateProcess。 例如,我有以下代码:

//.../

CreateProcess(NULL,input,NULL,NULL,false,NORMAL_PRIORITY_CLASS | 
 CREATE_NO_WINDOW,NULL,NULL,&startInf,&procInf);//)

//.../
如果输入像“ping www.google.com-n2”这样的行,它似乎可以工作。 但我需要的是删除功能。 因此,我尝试了很多变化,比如:

input = "rd /S /Q \"D:\\ALEX_DATEN\\PC\\C++\\bla\"";

但是什么也没有发生,函数返回失败:/ 如果我将其作为.bat文件编写(不使用“\”转义字符),删除操作将非常有效

有人知道我做错了什么吗


另外,不,我不是在写破坏性病毒。。如果这是我的目标,我肯定会找到更简单的方法…

一些系统命令,如
rd
del
和。。。不是实际的可执行映像(例如.exe文件),因此您不能使用
CreateProcess
执行/运行它们。它们是
cmd
(windows命令解释器)已知的内置命令,因此您应该创建
cmd
,并将命令传递给它:

wchar_t cmd[ MAX_PATH ];
size_t nSize = _countof(cmd);
_wgetenv_s( &nSize, cmd, L"COMSPEC" );
BOOL b = CreateProcessW( cmd, input, NULL, NULL, FALSE,
    NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &startInf, &procInf );
注意:请参阅
cmd
的参数,您必须使用
/C
来传递命令。因此,您的命令如下:

wchar_t input[] = L"some command";
wchar_t cmd[MAX_PATH] ;
// initialize cmd
wchar_t cmdline[ MAX_PATH + 50 ];
swprintf_s( cmdline, L"%s /c %s", cmd, input );
STARTUPINFOW startInf;
memset( &startInf, 0, sizeof startInf );
startInf.cb = sizeof(startInf);
// If you want to redirect result of command, set startInf.hStdOutput to a file
// or pipe handle that you can read it, otherwise we are done!
PROCESS_INFORMATION procInf;
memset( &procInf, 0, sizeof procInf );
BOOL b = CreateProcessW( NULL, cmdline, NULL, NULL, FALSE,
    NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &startInf, &procInf );
DWORD dwErr = 0;
if( b ) {
    // Wait till cmd do its job
    WaitForSingleObject( procInf.hProcess, INFINITE );
    // Check whether our command succeeded?
    GetExitCodeProcess( procInfo.hProcess, &dwErr );
    // Avoid memory leak by closing process handle
    CloseHandle( procInfo.hProcess );
} else {
    dwErr = GetLastError();
}
if( dwErr ) {
    // deal with error here
}

正如其他人所说,
rd
不能直接使用
CreateProcess()
执行,您必须使用
/C rd…
作为其命令行参数执行
cmd.exe
。与其像这样使用
CreateProcess()
,不如使用
SHFileOperation()

SHFILEOPSTRUCT FileOp = {0};
FilOp.wFunc = FO_DELETE;
FileOp.pFrom = "D:\\ALEX_DATEN\\PC\\C++\\bla\0"; 
FileOp.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI.

int ErrorCode = SHFileOperation(&FileOp);
if (ErrorCode == 0)
{
    if (FileOp.fAnyOperationsAborted)
        // not everything was deleted
    else
        // delete was successful
}
else
{
    // delete failed
    // note that ErrorCode might not be a Win32 error code,
    // so check the SHFileOperation() documentation for
    // possible alternatives
}

嗯,我真的不明白为什么要用这个。就我所知:它想执行一个文件,但我只需要执行一个字符串……我认为cppguy是对的;ShellExecute设计用于运行命令行,而CreateProcess设计用于运行特定的可执行文件。因此,在我看来,您的一些选项是1)使用ShellExecute,2)创建一个虚拟可执行文件包装ShellExecute(或类似的东西)并通过CreateProcess运行虚拟文件,或者3)查看是否可以直接执行实现rd命令的二进制文件。在我看来,ShellExecute是阻力最小的路径。
rd
是内置于shell中的命令,因此您无法使用
CreateProcess
执行它(至少是直接执行)。为此,您需要将
cmd.exe
作为可执行文件执行,并让它执行您的
rd/S…
。哦,好的,很有趣。那么这是否意味着我可以将其作为参数文件,简单地放在命令行中呢。。好吧,这也有道理!哦,好的,我会试试的。使用我还没有遇到的函数,但是谢谢@ChitianK谢谢你的编辑,我不是以英语为母语的人。因此,感谢您的帮助嗯,我需要包括哪些功能才能获得GetProcessExitCode?好像找不到。如何初始化startInf?lpw-startInf;不工作。抱歉,我编辑了我的答案,正确的函数是
GetExitCodeProcess
!!您想从
startInf
中获得什么?它将被设置为零,
startInf.cb=sizeof startInf
,如果需要操作结果,则将
hStdOutput
设置为稍后读取的文件,甚至将其设置为在程序中创建的管道,然后通过管道接收执行结果,如果不需要输出,则忽略它!啊,也谢谢你,但我想做一个表单,可以执行各种命令行,对不起!
SHFILEOPSTRUCT FileOp = {0};
FilOp.wFunc = FO_DELETE;
FileOp.pFrom = "D:\\ALEX_DATEN\\PC\\C++\\bla\0"; 
FileOp.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI.

int ErrorCode = SHFileOperation(&FileOp);
if (ErrorCode == 0)
{
    if (FileOp.fAnyOperationsAborted)
        // not everything was deleted
    else
        // delete was successful
}
else
{
    // delete failed
    // note that ErrorCode might not be a Win32 error code,
    // so check the SHFileOperation() documentation for
    // possible alternatives
}