2009-12-21 84 views
4

我正在編寫一個使用Qt的跨平臺C++程序,我想在程序中打包/嵌入一些二進制可執行文件。該程序應該能夠在運行時執行這些二進制文件。如何在Qt程序中嵌入二進制可執行文件(在運行時執行)?

我想,我需要使用start()和「:/ ...」符號的QResource和QProcess,但我似乎並沒有得到進程的運行。有什麼我失蹤?它應該像這樣工作嗎?該二進制文件是否需要設置爲可執行文件?

背景:我正在編寫一個使用Git的工具,我不想要求最終用戶手動安裝Git。

(在Mac OS X嘗試此,順便說一句。)

更新:

我使用下面的代碼(C++,Qt的在Mac OS X):

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

Git可執行文件位於項目路徑中,我的resources.qrc將其引用爲:

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

我沒有收到錯誤,但程序未執行。當我將program設置爲不存在的文件時,行爲是相同的。用git的絕對路徑代替":/git"完美工作。

+0

請向我們提供源代碼。即您使用QResource和QProcess的部分。 – Wildcat 2009-12-21 19:09:53

+0

我已經使用我使用的代碼更新了問題 – jan 2009-12-21 21:22:02

回答

8

您無法直接從資源執行程序。

如果你有一個資源中的程序,並且你想執行它,你首先必須將它從資源中讀出,寫入文件,使文件可執行,然後執行。

此外,當你說你沒有得到一個錯誤,這可能意味着你沒有正確地檢查錯誤。

+0

謝謝羅漢。 「沒有得到一個錯誤」只是懶惰的說「它默默地失敗」。我想我會得到一個錯誤,如果我檢查正確:) – jan 2009-12-23 11:07:45

+0

對於Windows:https://www.blackhat.com/presentations/bh-usa-07/Harbour/Whitepaper/bh-usa-07-harbour-WP.pdf – 2015-09-25 11:29:23

1

我不認爲資源會起作用。進程由操作系統創建,資源由應用程序處理。

一種可能的解決方案是將其他可執行文件捆綁到應用程序目錄中的某處,並從該路徑執行它們。

+0

謝謝!你能指出如何將它們嵌入到應用程序包(osx)中嗎?我想避免有一個安裝程序 - 一個簡單的dmg圖像應該是所有用戶將不得不下載的。 – jan 2009-12-21 21:04:23

0

所以這個問題似乎不是從資源中提取git可執行文件,而是執行它?

該git程序正確生成唐磁盤,你可以檢查它的權限?

1

幾年遲到了,但問題仍然相關。當想要嵌入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]); 
相關問題