具有多个参数

时间:2016-05-13 15:25:57

标签: c++ windows qt qprocess

我尝试使用QProcess(在Windows上)从我的程序(FaceModifier.exe)中启动blender.exe。该命令遵循以下结构:

  

'路径到混合器' --background' path-to-blend-file' --python' path-to-python-script' - ' additional-arg-for-python-script'

一个完整的示例(如果我将其键入cmd.exe,则有效)将是

  

" C:\ Program Files \ Blender Foundation \ Blender \ blender.exe" --background" C:\ Program Files(x86)\ FaceModifier \ Resources \ GenericHeadMesh.blend" --python" C:\ Program Files(x86)\ FaceModifier \ python \ local.py" - " C:\ Users \ Gunnar \ Documents \ FaceModifier \ Output \"

现在,在我的程序中,我逃避路径并用引号括起来,所以我有这样的东西

std::string blenderPath := "\"C:\\Program Files\\Blender Foundation\\Blender\\blender.exe\""

对于QProcess,我将所有参数都提供给带有前导/c的QStringList,因此将其视为单个命令并将其传递给cmd.exe

我的问题是我无法执行此操作。如果我手动输入命令(我传递给QProcess,而不是上面的命令)到cmd。

我启动过程的功能如下所示:

void PythonConnector::createSubprocess(const QStringList &args)
{
    QProcess *process = new Process();
    process->start("cmd.exe", args);
    process->waitForFinished(-1);

    QString result(process->readAll());
    qDebug() << "result: " << result;    // this gives just an empty string

    process->close();
}

我称之为:

// for the documents path
CoInitialize(NULL);
TCHAR *myDocuments = 0;
SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &myDocuments);
CString temp(myDocuments);
CT2CA tempConv(temp);
std::string outputFolderPath(tempConv);
outputFolderPath += "\\FaceModifier\\Output\\";
outputFolderPath = pH.ExcapeString(outputFolderPath);
CoTaskMemFree(myDocuments);

blenderPath = pH.EscapeString(blenderPath);

std::string meshGlobalPath = "\"" + pH.GetResourcesPath() + "GenericHeadMesh.blend" + "\"";
std::string pythonGlobalPath = "\"" + pH.GetPythonPath() + "global.py" + "\"";

QStringList args;
args << "/c" << QString::fromStdString(blenderPath) << "--background" << QString::fromStdString(meshGlobalPath) << "--python" << QString::fromStdString(pythonGlobalPath) << "--" << QString::fromStdString("\"" + outputFolderPath "\"");
pC.createSubprocess(args);

blenderPath传递给此函数并从另一个函数的注册表中读取 这些是我的其他辅助函数:

std::string PathHandler::GetResourcesPath()
{
    if(resourcesPath.empty())
        resourcesPath = GetFullPath("Resources\\");
    return resourcesPath;
}

std::string PathHandler::GetPythonPath()
{
    if(pythonPath.empty())
        pythonPath = GetFullPath("python\\");
    return pythonPath;
}

std::string PathHandler::GetFullPath(const std::string &relPath)
{
    char full[_MAX_PATH];
    _fullpath(full, relPath.c_str(), _MAX_PATH);
    return EscapeString(std::string(full));
}

std::string PathHandler::EscapeString(const std::string &input)
{
    std::regex toReplace("\\\\");
    std::string output(input.begin(), input.end());
    output = std::regex_replace(output, toReplace, "\\\\");
    return output;
}

使用qDebug调试args列表导致这些输出(这些实际上来自Visual Studio 2013中的调试,因此是不同的路径):

"/c"  
""C:\\Program Files\\Blender Foundation\\Blender\\blender.exe""  
"--background"  
""C:\\Users\\Gunnar\\documents\\visual studio 2013\\Projects\\FaceModifier\\x64\\Release\\Resources\\GenericHeadMesh.blend""  
"--python"  
""C:\\Users\\Gunnar\\documents\\visual studio 2013\\Projects\\FaceModifier\\x64\\Release\\python\\global.py""  
"--"  
""C:\\Users\\Gunnar\\Documents\\FaceModifier\\Output\\""

来自result的{​​{1}}调试只提供createSubprocess

如果我手动将此命令输入cmd:

  

cmd / c&#34; C:\ Program Files \ Blender Foundation \ Blender \ blender.exe&#34; --background&#34; C:\ Users \ Gunnar \ documents \ visual studio 2013 \ Projects \ FaceModifier \ x64 \ Release \ Resources \ GenericHeadMesh.blend&#34; --python&#34; C:\ Users \ Gunnar \ documents \ visual studio 2013 \ Projects \ FaceModifier \ x64 \ Release \ python \ global.py&#34; - &#34; C:\ Users \ Gunnar \ Documents \ FaceModifier \ Output \&#34;

我得"" 对于各种不同的报价都是一样的,有和没有这样的转义

  

cmd&#34; / c \&#34; C:\ Program Files \ Blender Foundation \ Blender \ blender.exe \&#34; --background \&#34; C:\ Users \ Gunnar \ documents \ visual studio 2013 \ Projects \ FaceModifier \ x64 \ Release \ Resources \ GenericHeadMesh.blend \&#34; --python \&#34; C:\ Users \ Gunnar \ documents \ visual studio 2013 \ Projects \ FaceModifier \ x64 \ Release \ python \ global.py \&#34; - \&#34; C:\ Users \ Gunnar \ Documents \ FaceModifier \ Output \\&#34;&#34;

只需输入

即可
  

cmd / c&#34; C:\ Program Files \ Blender Foundation \ Blender \ blender.exe&#34;

工作正常,但这显然不是我需要的。

我无法理解我必须如何构建它以便它能够正常工作。有人能告诉我我的错误是什么吗?

更新
好吧,从理论上说它现在有效(感谢艾哈迈德),但它确实在路径上黯然失色。如果我在。The command "C:\\Program" is either missspelled or couldn't be found.中有.blend和.py,那么它是有效的,如果它们在...\Documents\FaceModifier(我的程序安装在哪里)它就不起作用。我怎样才能做到这一点?我更喜欢这样,所以我不必在那边复制这些文件。

1 个答案:

答案 0 :(得分:1)

您不需要引用或双引号文件路径,QProccess已经处理过, 将此部分代码更改为:

std::string meshGlobalPath = pH.GetResourcesPath() + "GenericHeadMesh.blend" ;
std::string pythonGlobalPath = pH.GetPythonPath() + "global.py" ;

QStringList args;
args << "/c" << QString::fromStdString(blenderPath) << "--background" 
     << QString::fromStdString(meshGlobalPath) << "--python" 
     << QString::fromStdString(pythonGlobalPath) << "--"
     << QString::fromStdString(outputFolderPath);