如何通过C ++程序运行Windows命令?

时间:2017-06-14 20:35:35

标签: c++

对于一些帮助你们的反馈信息,我正在创建一个小程序,它将使用.SQL文件并使用mysql.exe将其恢复到用户localhost phpMyAdmin。手动导入文件通过MyAdmin本身,因为它必须解压缩和解析信息,这种方法更快,适用于我的同事,因为我们总是将备份和恢复推送到我们的WAMP进行试验。

我面临的一个问题是,无论如何我都无法改变目录。我知道,无论启动可执行文件的是系统将继承的路径,为什么我不能简单地告诉它更改目录?

到目前为止,这是我的代码:

system("cd c:\wamp64\bin\mysql\mysql5.7.14\bin");
system("PAUSE");
system("dir");
system("PAUSE");
system("mysql.exe -u root -p dataBase < tables.sql");

注意:暂停和系统(“dir”)在那里严格用于测试目的,一旦窗口回吐目录的正确内容,然后我知道它工作,我将只有第一个和最后一个程序中留下的行。

UPDATE :我已经收到通知,每次调用系统都会创建一个新的CMD进程,这对于为什么cd不会影响任何内容非常有意义,因为它正在打开一个新进程,更改目录然后在下一行它调用一个新进程并暂停它。这将是什么解决方法?

更新2 :我决定使用&amp;&amp;但这限制了我对可用性和“造型”方面的影响,但这不是一个问题,该程序需要作为一个运行&amp;做完交易。

以下是我的想法:

system("cd c:\\wamp64\\bin\\mysql\\mysql5.7.14\\bin && mysql.exe -u root -p dataBase < table.sql");
cout << "\n" << "The database 'dataBase' has been restored using 'table.sql' successfully!" << "\n\n";
return 0;

创建.cmd文件并使用CreateProcess()运行它有什么好处,或使用我提出的方法的缺点?

注意:数据库名称和.sql文件不会从任何内容中提取,名称将是静态的,因此我不必担心更新它。

2 个答案:

答案 0 :(得分:3)

更好的想法是动态生成批处理文件(.cmd.batthere are slight differences),然后使用cmd.exe /c batchFile.cmd调用该文件:

#include <cstdlib>
#include <cstdio>

ofstream batch_file;
batch_file.open( "commands.cmd", ios::trunc );
batch_file <<
    "cd c:\\wamp64\\bin\\mysql\\mysql5.7.14\\bin" << endl <<
    "PAUSE" << endl <<
    "dir" << endl <<
    "PAUSE" << endl <<
    "mysql.exe -u root -p dataBase < tables.sql" << endl;
batch_file.close();

int batch_exit_code = system( "cmd.exe /c commands.cmd" ); // blocks until the child process is terminated
if( batch_exit_code != 0 ) {
    cout << "Batch file exited with code " << batch_exit_code << endl;
}

remove( "commands.cmd" ); // delete the batch file

这样做的好处是允许您自定义文本和命令,例如执行自己检测MySQL二进制文件和临时文件的位置。

请注意,如果您始终在Windows上运行,则可能需要使用CreateProcess,因为system会产生一些开销:

  

system() and CreateProcess() / CreateProcessW()

     

系统函数将命令传递给命令解释器,命令解释器将字符串作为操作系统命令执行。 system是指定位命令解释程序文件(Windows NT中名为CMD.EXE的文件)的COMSPEC和PATH环境变量。

由于您希望直接运行cmd.exe,这会导致它打开两次。

您可以改为使用CreateProcess

STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;
if( CreateProcess( "cmd.exe", "/c commands.cmd", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo ) )
{
    WaitForSingleObject( processInfo.hProcess, INFINITE );
    CloseHandle( processInfo.hProcess );
    CloseHandle( processInfo.hThread );
}

答案 1 :(得分:1)

这是一种可以通过目录更改执行系统的方法:

// using AND_CMD like an operator to concat commands -- you can also just type it in one string: "edit & shutdown -h"...
// this works in c, too, but no dynamic variables are possible
//#define AND_CMD " & "

// c++
#define AND_CMD +" & "+

system(
    "cd c:\wamp64\bin\mysql\mysql5.7.14\bin" AND_CMD
    "PAUSE" AND_CMD
    "dir" AND_CMD
    "PAUSE" AND_CMD
    "mysql.exe -u root -p dataBase < tables.sql"
);

因此,您只需要使用字符串" & "加入命令。 如果你需要在下次调用system函数时自己/保留目录的条件下运行代码,你应该寻找替代方案或者将命令输入命令提示符(例如,运行你的程序) myprogram.exe | %comspec%并通过输出例如printf来调用命令。