2016-05-13 17 views
0

Ich versuche blender.exe aus meinem Programm (FaceModifier.exe) mit QProcess (unter Windows) zu starten. Der Befehl folgt diese Struktur:QProcess starten Prozess (blender.exe) mit mehreren Argumenten

'path-to-Mixer' --background 'path-to-blend-Datei' --python 'path-to-Python-Skript' - ‚Zusatz-Arg- for-python-Skript‘

Ein vollständiges Beispiel

„C würde (das funktioniert, wenn ich es in cmd.exe Typ) sein: \ Programme \ Blender Foundation \ Blender \ blender.exe "--background" C: \ Programme (x86) \ FaceModifier \ Resources \ GenericHeadMesh.blend "--python" C: \ Programme (x86) \ FaceModifier \ python \ local.py "-" C: \ Benutzer \ Gunnar \ Dokumente \ FaceMo difier \ Output \“

nun in meinem Programm entkommen ich die Wege und umgeben sie mit Anführungszeichen, so habe ich so etwas wie dieses

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

Für QProcess ich meine Argumente alle in eine QStringList mit einem Futter Führt /c so wird es als ein einziger Befehl behandelt und es an cmd.exe übergeben.

Mein Problem ist, dass ich dies nicht ausgeführt werden kann. Wenn ich den Befehl (den ich an QProcess übergebe, nicht den von oben) in cmd von Hand auch nicht eintippe.

Meine Funktion, die den Prozess beginnt wie folgt aussieht:

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(); 
} 

ich es so nennen:

// 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 an diese Funktion übergeben wird und aus der Registry in einer anderen Funktion lesen.
Hier sind meine anderen Hilfsfunktionen:

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; 
} 

die args Liste mit qDebug Ergebnisse in diesen Ausgängen Debuggen (diese sind tatsächlich von Debuggen in Visual Studio 2013, daher werden die verschiedenen Pfade):

"/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\\"" 

und die result debug von createSubprocess gibt nur "".

Wenn ich diesen Befehl eingeben in von Hand wie folgt KMD:

cmd/c "C: \ Programme \ Blender Foundation \ Blender \ blender.exe" --background „C: \ Benutzer \ Gunnar \ Dokumente \ Visual Studio 2013 \ Projekte \ FaceModifier \ x64 \ Release \ Ressourcen \ GenericHeadMesh.blend "--python" C: \ Benutzer \ Gunnar \ Dokumente \ Visual Studio 2013 \ Projekte \ FaceModifier \ x64 \ Release \ Python \ global .py "- "C: \ Benutzer Gunnar \ Dokumente \ \ FaceModifier \ Output \"

ich The command "C:\\Program" is either missspelled or couldn't be found. Das Gleiche gilt für verschiedene quotings mit und ohne ähnliche Flucht

cmd"/c \ "C: \ Programme \ Blender Foundation \ Blender \ blender.exe" --Hintergrund \ "C: \ Benutzer \ Gunnar \ Dokumente \ Visual Studio 2013 \ Projekte \ FaceModifier \ x64 \ Release \ Resources \ GenericHeadMesh.blend \ "--python \" C: \ Benutzer \ Gunnar \ Dokumente \ Visual Studio 2013 \ Projekte \ FaceModifier \ x64 \ Release \ python \ global.py \ "- \" C: \ Benutzer \ Gunnar \ Documents \ FaceModifier \ Output \\ ""

Gerade

cmd/c "C: \ Programme \ Blender Foundation \ Blender \ blender.exe" eingeben

funktioniert gut, aber das ist natürlich nicht das, was ich brauche.

Ich kann nicht meinen Kopf darum wickeln, wie ich das bauen muss, damit es funktioniert. Kann mir jemand sagen, was mein Fehler ist?

UPDATE:
Ok, in der Theorie jetzt funktioniert es (dank ahmed), es wirklich depands auf den Pfaden though. Wenn ich die .blend und die .py in ...\Documents\FaceModifier es funktioniert, wenn sie in C:\Program Files (x86)\FaceModifier\ sind (wo mein Programm installiert ist) funktioniert es nicht. Wie kann ich das erreichen? Mir wäre das lieber, also muss ich diese Dateien nicht dorthin kopieren.

Antwort

1

Sie brauchen keine oder doppelte Anführungszeichen Dateipfade zu zitieren, Griff QProccess bereits, Änderung dieser Teil des Codes:

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); 
+0

Ok, das etwas funktioniert. Ich bin davon abhängig, wo diese Dateien (.blend und .py) sind. Wenn sie in den 'Programme (x86) ...' oder den 'documents \ visual studio \ ... \ x64 \ Release's sind, funktioniert das nicht. Ich denke, das hängt mit den Berechtigungen zusammen, aber sie werden nur mit diesem Befehl gelesen/ausgeführt, nicht geschrieben. Gibt es eine Möglichkeit, dies zum Laufen zu bringen, damit ich sie nicht in den 'output'-Ordner verschieben muss? –

+0

haben Sie versucht, 'blender.exe' direkt ohne' cmd.exe' zu ​​starten? – ahmed

+1

Oh Mann, ja! QProcess startet blender direkt und ich habe das '/ c' entfernt, so dass der Rest alles von' --background' geht und es jetzt funktioniert. Vielen Dank! –

Verwandte Themen