對于自建安裝程式,我需要一種在關閉應用程式本身后執行代碼的方法。
應用結構
- 主應用程式:安裝程式在需要時從它啟動,并在此程序中自行關閉。
- 安裝程式:它也位于主應用程式的檔案夾中,因此也可以訪問所有
dll檔案。當有可用更新時,zip首先下載一個檔案,然后將其解壓到temp檔案夾中。之后,所有檔案都從那里移動到共享應用程式目錄。
問題
問題是更新程式在運行時只能更新少數自己不使用的 dll 檔案,因為有些檔案由于安裝程式的訪問而被寫保護。
一個解法
必須在關閉安裝程式后才能將檔案從臨時檔案夾移動到共享應用程式檔案夾。但我不知道如何意識到這一點。
非常感謝!
uj5u.com熱心網友回復:
如果您的問題是安裝程式和主應用程式共享的 DLL,那么您可以這樣做: 在運行安裝程式之前,您的主應用程式可以將所有需要的 DLL 和安裝程式 EXE 從您的主應用程式檔案夾復制到一個臨時檔案夾并運行它從那里。然后,您的安裝程式必須等到主應用程式關閉,然后替換主檔案夾中的所有檔案。更新完成后,洗掉此安裝程式的臨時副本及其 DLL。
請注意,如果您想覆寫 Program Files 檔案夾中的檔案,您的安裝程式必須以提升的權限運行。谷歌搜索“runas”命令......使用QProcess.
但也可能存在其他問題。如果您的第一次安裝是使用普通安裝程式,它通常會在注冊表中創建一些條目,并且還會生成檔案串列以供以后卸載。如果您的新版本將包含與最初安裝版本不同的檔案,那么您隨后的卸載可能會出現故障或可能會在用戶的計算機上留下一些檔案。你當然不想要這個。
還有一個潛在的問題。您可能運行了多個應用程式實體。在這種情況下,退出一個實體仍會使其他實體繼續運行,因此安裝程式無法替換它們的檔案 - 它會失敗。
如您所見,這些都是需要考慮的嚴肅方面。
我如何在我的軟體中做到這一點,我建議你也嘗試一下?我使用 InnoSetup(免費軟體!)準備了一個安裝程式檔案 (.exe)。這可用于首次安裝以及自動更新。然后,如果我創建一個新版本并將其放在服務器上,正在運行的主應用程式會檢測到它,下載新的安裝程式并運行此安裝程式(當然它會詢問用戶是否應該繼續)。然后安裝程式要求提升權限,要求關閉正在運行的應用程式(通常在啟動安裝程式時自動關閉)并覆寫現有安裝。所有這些都是 InnoSetup 創建的安裝程式中內置的標準功能。并正確更新卸載說明...我花了幾天時間才根據我的需要設定所有內容,但效果很好。唯一的“缺點” 是它不是完全靜音,它顯示了一些對話框。但這對我來說不是真正的問題。也許讓用戶看到他們的計算機上發生的事情會更好......
uj5u.com熱心網友回復:
你的問題暗示了 Windows。我將從 Win32 的角度提出建議。
在我們的應用程式中,我們有一個類似的問題。我們的應用程式會定期將更新可執行檔案下載到臨時檔案夾中,然后啟動它。當更新 EXE 運行時,它會確保主應用程式已退出,將檔案解壓縮到應用程式的安裝檔案夾中,然后再次啟動應用程式備份。它實際上比這更復雜,因為它確實將新檔案復制到不同的安裝檔案夾中,但除非您確實需要,否則我會保存這些詳細資訊。
問題是更新程式在運行時只能更新少數自己不使用的 dll 檔案,因為有些檔案由于安裝程式的訪問而被寫保護。
這是你問題的核心。我的建議是讓安裝程式 EXE 靜態鏈接到 VC 運行時和與應用程式共享的其他代碼。也就是說,沒有 DLL 依賴項。如果您確實需要在安裝程式和應用程式之間共享代碼,但仍希望應用程式使用 DLL,則可以執行此操作。將共享代碼構建為 DLL(帶有存根庫)并構建為完整的 LIB。可能需要對構建進行一些小的重構或冗余構建相同的源檔案。安裝程式代碼鏈接到完整的 LIB。應用程式代碼與 DLL 的存根 LIB 鏈接,就像現在一樣。
如果您只是在尋找啟動流程的方法,那么您想要的 API 是CreateProcess。
此外,您是否查看過像Omaha這樣的開源選項——這是 Google Chrome 用于靜默更新的選項?
uj5u.com熱心網友回復:
必須在關閉安裝程式后才能將檔案從臨時檔案夾移動到共享應用程式檔案夾。但我不知道如何意識到這一點。
“Windows 方式”將按照本博客文章中的PendingFileRenameOperations描述使用,并讓 Windows 在下次啟動時執行此操作。當然,這意味著又一條煩人的“請重新啟動以完成安裝”訊息。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/379137.html
