SFX的妙用——如何在不安裝軟體的情況下開啟自定義格式檔案?

czwy發表於2023-12-06

前段時間看到群友討論壓縮包能不能執行,想起了n年前用自解壓檔案SFX實現的一個“需求”:在沒有安裝任何應用軟體的Windows(當時還要支援XP)上能雙擊開啟自定義格式的檔案。當時第一反應是這“需求”太奇葩了,簡直是不可能。但思考後認為這個“需求”存在一定的合理性,因為當時的目標使用者群體並不能熟練使用電腦,可能不知道開啟一個檔案需要安裝對應的軟體。

這裡“需求”之所以打上引號,是因為我覺得這不是真正的需求,而是一個解決方案,真正的需求是如何讓不熟悉電腦操作的使用者方便的使用我們自定義格式的檔案。

實施方案

Windows系統的登錄檔中會記錄檔案格式與對應軟體的關聯關係,雙擊檔案時會找到關聯的軟體執行並載入檔案。而這個檔案與軟體的關聯資訊是在安裝應用程式時寫進登錄檔的。正因如此,一開始覺得“需求”簡直是不可能的。經過一番思考,嘗試把自定義格式的檔案和應用程式打包到一起形成一個exe,雙擊exe時釋放應用程式和檔案,並執行應用程式載入檔案。具體到實施上有兩種選擇:用NSIS或者MSI打包工具生成安裝包,用壓縮軟體製作SFX自解壓檔案。考慮到第一種方式依賴項較多且程式碼呼叫不方便,最後選擇了自解壓檔案的方式。

自解壓檔案

自解壓SFX(self extracting)檔案是壓縮檔案的一種,其字尾名是exe。它可以不借助任何壓縮工具,只需雙擊該檔案就可以自動執行解壓,並根據配置執行解壓後的可執行程式(EXE)。WinRAR和7-Zip都可以製作自解壓檔案。這裡以7-Zip為例介紹如何製作自解壓檔案。自解壓安裝包必須包含三個檔案:7z_Archive,SFX_Module, Installer_Config。

  • 7z_Archive:用7z打包歸檔好的檔案(希望放到自解壓檔案中的程式和檔案)
  • SFX_Module:自解壓檔案的核心模組,必須與7z.exe放在同一目錄,主要包含四種型別:
SFX_Module 說明
7z.sfx 帶有GUI的自解壓模組
7zCon.sfx 提供Console視窗互動的自解壓模組
7zS.sfx 允許建立安裝程式的帶GUI的自解壓模組
7zSD.sfx 允許建立安裝程式的帶GUI的自解壓模組(使用MSVCRT.dll)

7z.sfx7zCon.sfx在7-Zip的安裝目錄中能找到,這兩個基本上沒什麼用,僅僅是完成雙擊自解壓功能,解壓完成之後沒有任何操作,即便是在Installer_Config配置檔案中指定了需要執行的程式也沒作用。以下兩個圖分別是7z.sfx7zCon.sfx製作的自解壓檔案解壓過程。
image
image

7zS.sfx7zSD.sfx則需要從官網下載 LZMA SDK包獲取。這兩個製作的自解壓檔案會把打包的檔案釋放到使用者的臨時目錄,然後根據Installer_Config配置檔案執行指定程式,程式結束後會刪除臨時檔案。製作自解壓檔案的命令如下:

copy /b 7zS.sfx + config.txt + archive.7z archive.exe
  • Installer_Config:這個配置檔案包含了自解壓檔案對話方塊的標題,資訊,解壓完成後執行的檔案和引數等資訊。檔案以;!@Install@!UTF-8!開始,並以;!@InstallEnd@!結束,且必須是用UTF-8編碼。具體包含的配置資訊內容參見7-Zip的幫助文件,以下是配置檔案的示例:
;!@Install@!UTF-8!
Title="7-Zip 4.00"
BeginPrompt="自解壓檔案測試,是否繼續?"
RunProgram="7zFM.exe"
;!@InstallEnd@!

下圖是7zS.sfx配置了製作的自解壓檔案解壓過程。雖然實現了雙擊自解壓後執行指定的7zFM.exe,但是自解壓檔案的圖示、檔案說明、公司資訊等檔案屬性不是我們想要的,並且解壓過程的對話方塊樣式和內容也不符合預期。接下來需要美化自解壓檔案。
image

美化自解壓檔案

7z自帶的sfx以及幫助文件提供的資訊有限,可以透過7z SFX Builder實現更多的自定義操作。下載安裝後可以用圖形介面的方式自定義解壓過程對話方塊的樣式,並生成相應的Installer_Config資訊。首先設定解壓檔案覆蓋模式和對話方塊樣式。
image

然後根據實際情況選擇對話方塊具體的樣式資訊。
image

接下來就是設定對話方塊的標題、解壓進度窗體、錯誤窗體、警告窗體的標題資訊。
image

設定完標題資訊後就是設定對話方塊內的各種資訊內容。
image

再然後就是配置解壓後執行檔案以及引數資訊。
image

配置完這些資訊之後,可以在“output”下看到Installer_Config資訊,我們可以複製儲存下來以備後用。需要注意的是,Installer_Config配置檔案以;!@InstallEnd@!結束,從“output”中複製資訊時,;!@InstallEnd@!後邊還有內容就不要複製了。
image

7z SFX Builder也提供了更多的sfx模組供選擇,這些模組儲存在C:\Program Files (x86)\7z SFX Builder\3rdParty\Modules目錄下,
image

選擇了sfx模組後可以設定檔案說明、公司資訊等屬性。這也決定了最終制作的自解壓檔案的檔案屬性。
image

到了這裡,我們離大功告成只剩下修改圖示這一步了。這時需要藉助Resource Hacker來修改圖示資訊,如果上一步中沒有編輯sfx模組的資訊,也可以在這裡透過Resource Hacker修改。我們只需準備好ico檔案,然後在Resource Hacker開啟sfx模組,並替換圖示檔案或編輯版本資訊,完成後儲存sfx模組檔案。至此就完成了自解壓檔案的美化工作。
image

小結

文中只介紹了7z SFX Builder的基本用法,它的幫助文件提供了更多的操作說明以及示例。
自解壓檔案在某些特定的場景給我們提供了便利,但也容易被防毒軟體當成病毒處理。我在實現開篇提到的“需求”時,也飽受防毒軟體困擾。最後分享幾點經驗:

  1. 對自解壓檔案中的可執行程式及依賴檔案進行code review,刪除所有未使用過的變數和屬性;
  2. 避免在系統目錄寫檔案和修改系統檔案,避免寫登錄檔等操作
  3. 對可執行程式以及所有依賴的類庫進行強簽名;
  4. 提交常用防毒軟體白名單;
  5. 最後一點,也是最重要的一點。前邊幾點只能緩解防毒軟體誤報,要想徹底解決,就不要在生產環境使用自解壓檔案。

相關文章