2009-12-21 4 views
4

J'écris un programme C++ multi-plateforme en utilisant Qt et je veux emballer/incorporer un certain nombre d'exécutables binaires dans le programme. Le programme devrait être capable d'exécuter ces binaires lors de l'exécution. J'ai pensé, j'aurais besoin de QResource et QProcess en utilisant start() et la notation ":/...", mais je ne pense pas que le processus fonctionne. Y a-t-il quelque chose qui me manque? Est-ce que ça devrait fonctionner comme ça? Le binaire doit-il être défini comme exécutable? Contexte: J'écris un outil qui utilise Git et je ne veux pas que l'utilisateur final installe Git manuellement.Comment intégrer un exécutable binaire (à exécuter à l'exécution) dans un programme Qt?

(Essayer ceci sur Mac OS X, BTW.)

Mise à jour:

J'utilise le code suivant (C++, Qt sous Mac OS X):

QString program = ":/git"; 
QStringList arguments; 
arguments << "help" << "commit"; 
myProcess->start(program, arguments); 

L'exécutable Git se trouve dans le chemin du projet, mes ressources.qrc le font comme ceci:

<qresource prefix="/"> 
    <file>git</file> 
</qresource> 

Je n'obtiens pas d'erreur, mais le programme n'est pas exécuté. Le comportement est le même lorsque j'ai défini program sur un fichier inexistant. Remplacer ":/git" par le chemin absolu de git fonctionne parfaitement.

+0

S'il vous plaît, nous fournir le code source. À savoir la partie où vous utilisez QResource et QProcess que vous avez mentionné. – Wildcat

+0

J'ai mis à jour la question avec le code que j'utilise – jan

Répondre

8

Vous ne pouvez pas exécuter un programme directement à partir d'une ressource.

Si vous aviez un programme dans une ressource et que vous vouliez l'exécuter, vous devez d'abord le lire dans la ressource, l'écrire dans un fichier, le rendre exécutable, puis l'exécuter. En outre, lorsque vous dites que vous n'obtenez pas d'erreur, cela signifie probablement que vous ne vérifiez pas correctement les erreurs.

+0

Merci Rohan. "Ne pas avoir d'erreur" était juste paresseux, car "ça échoue silencieusement". Je suppose que j'obtiendrais une erreur si j'ai vérifié correctement :) – jan

+0

Pour Windows: https://www.blackhat.com/presentations/bh-usa-07/Harbour/Whitepaper/bh-usa-07-harbour-WP.pdf –

1

Je ne pense pas que les ressources fonctionneraient. Les processus sont créés par le système d'exploitation et les ressources sont gérées par application.

Une solution possible serait de regrouper des exécutables supplémentaires quelque part dans le répertoire de votre application et de les exécuter à partir de ce chemin.

+0

merci! pouvez-vous indiquer comment les intégrer dans le bundle d'application (osx)? Je voudrais éviter d'avoir un installateur - une image simple dmg devrait être tout l'utilisateur devrait télécharger. – jan

0

Donc le problème ne semble pas extraire l'exécutable git de la ressource autant que l'exécuter?

Le programme git est générer disque disque correctement, pouvez-vous vérifier ses autorisations?

1

Plusieurs années en retard, mais la question est toujours pertinente. J'ai eu le même problème en voulant incorporer rclone.

Dans le fichier .pro, ajoutez

# From http://stackoverflow.com/a/37561981 
defineReplace(copyToDir) { 
    files = $$1 
    DIR = $$2 
    LINK = 

    for(FILE, files) { 
     LINK += $$QMAKE_COPY $$shell_path($$FILE) $$shell_path($$DIR) $$escape_expand(\\n\\t) 
    } 
    return($$LINK) 
} 

defineReplace(copyToBuilddir) { 
    return($$copyToDir($$1, $$OUT_PWD)) 
} 

# Copy the binary files dependent on the system architecture 
win32 { 
    message("Windows") 
    QMAKE_POST_LINK += $$copyToBuilddir($$PWD/rclone/windows/rclone.exe) 
}else: unix:!macx { 
    message("Linux") 
    QMAKE_POST_LINK += $$copyToBuilddir($$PWD/rclone/linux/rclone) 
}else: macx: { 
    # Here we want to place the binaries inside the application bundle, so the 
    # QMAKE_POST_LINK approach will not work because it places them in the same 
    # directory as the bundle and not inside it. Instead, use QMAKE_BUNDLE_DATA. 
    message("macOS") 
    MediaFiles.files += $$PWD/rclone/macOS/rclone 
    MediaFiles.path = Contents/MacOS 
    QMAKE_BUNDLE_DATA += MediaFiles 
} 

Remarquez comment il existe de légères différences pour chaque plate-forme, mais en général l'approche est la même.

qmake va copier ces fichiers dans le répertoire de destination, et ils seront accessibles en faisant simplement l'appel de processus dans le répertoire relatif local.

Dans le code suivant, je l'appelle l'exécutable à partir QML, et il va être très similaire en C++ ainsi:

var rcloneCommand 
if (Qt.platform.os === "windows") { 
    console.log("Windows") 
    rcloneCommand = "rclone.exe" 
} else { 
    console.log("OSX/Linux") 
    rcloneCommand = "./rclone" 
} 
qProcess.start(rcloneCommand, ["--config", "rclone.conf", "-v", "copy", "--stats", "1s", source, destination]); 
Questions connexes