8

我正在使用Qt编写一个跨平台的 C++ 程序,并且我想在程序中打包/嵌入许多二进制可执行文件。该程序应该能够在运行时执行这些二进制文件。

我想,我需要 QResource 和 QProcess 使用 start() 和 ":/..." 符号,但我似乎没有让进程运行。有什么我想念的吗?它应该像这样工作吗?二进制文件是否需要设置为可执行文件?

背景:我正在编写一个使用Git的工具,我不想要求最终用户手动安装 Git。

(在 Mac OS X 上试试这个,顺便说一句。)

更新:

我正在使用以下代码(Mac OS X 上的 C++、Qt):

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

Git 可执行文件位于项目路径中,我的 resources.qrc 像这样引用它:

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

我没有收到错误,但程序没有执行。program当我设置为不存在的文件时,行为是相同的。用 git 的绝对路径替换":/git"效果很好。

4

4 回答 4

10

您不能直接从资源执行程序。

如果您在资源中有一个程序并且想要执行它,您首先必须从资源中读取它,将其写入文件,使文件可执行,然后执行它。

此外,当您说您没有收到错误时,这可能意味着您没有正确检查错误。

于 2009-12-21T23:02:56.107 回答
3

晚了几年,但这个问题仍然是相关的。我想嵌入rclone时遇到了同样的问题。

.pro文件中,添加

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

请注意每个平台的细微差别,但总的来说方法是相同的。

qmake会将这些文件复制到目标目录,并且只需对本地相对目录进行进程调用即可访问它们。

在以下代码中,我从 QML 调用可执行文件,它在 C++ 中也将非常相似:

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]);
于 2017-03-15T13:00:30.550 回答
2

我不认为资源会起作用。进程由操作系统创建,资源由应用程序处理。

一种可能的解决方案是在您的应用程序目录中的某处捆绑其他可执行文件并从该路径执行它们。

于 2009-12-21T19:09:37.767 回答
0

所以问题似乎不在于从资源中提取 git 可执行文件,而在于执行它?

git程序正确生成了don disk,你能检查它的权限吗?

于 2009-12-21T22:45:58.283 回答