我尝试使用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
(我的程序安装在哪里)它就不起作用。我怎样才能做到这一点?我更喜欢这样,所以我不必在那边复制这些文件。
答案 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);