取得winamp的NSIS教本的教學
新增 NSIS 指令碼的習慣: 新增一個 include 目錄,用來儲存安裝用的文件, .nsi 文件放在 include 的上級目錄,再在 include 目錄裡新增一個 resource,用來儲存一些資源文件比如圖示、界面圖形、自己修改的 UI 等等。
然後分析一下官方的安裝程序,嗯嗯,先清空臨時資料夾,這是為了為了找東西方便,然後啟動安裝程序,再到臨時目錄裡找一個 nxxx.tmp 這樣的目錄,裡面有一些解壓縮出來的資源 gaydata.ini、modern-header.bmp、classic256.bmp、modern256.bmp、opt2page.ini、 opt3page.ini。那幾個圖形一看就明白,不用解釋,gaydata.ini 呢,裡面有從 sec0 到 sec47 的定義,所以我們可以確定一共有 47 個區段,而且區段的名稱是根據 gaydata.ini 來確定的,如何知道是根據 gaydata.ini 來確定的 的呢,你在安裝程序剛啟動的時候(剛顯示許可頁面的時候)找到臨時的那個目錄(也就是 NSIS 裡的 $PLUGINSDIR 目錄),把一個區段名稱改一下,比如把「Winamp (required)」改為 aaa,等進入元件選項頁面的時候第一個就是 aaa 了,而如果把「Winamp (required)」清空的話,第一個區段就不見了。 opt2page.ini、opt3page.ini 分別是最後兩個頁面用來選項連接方式和外觀的。分析後就可以動手了…… 1.建立基本的結構 首先在指令碼頭部定義一些版本號等值,比如 !define VERSION "5.05" !define VERSION_NUM "505" 這樣版本號變的時候在指令碼頭部改一下就行了,不用在指令碼的每個地方都改 然後定義輸出檔案名,為了方便 full、pro、lite 三個版本切換方便。 !define FILE_NAME "Winamp${VERSION_NUM}_full" 有關定義的說明可以看這裡 再下來就是安裝程序內容的設定了,必須的設定有 Name "Winamp" OutFile "${FILE_NAME}.exe" 當然 SetCompressor lzma 應該也是必須的,LZMA 不止壓縮率大很多,而且不太準確的一個內容是啟動快不少,然後再設定一個區段就構成了主體部分,已經能夠編譯了 Section "主程序" SectionEnd 2. 插入頁面 首先要 !include "MUI.nsh" 這樣才能使用 NSIS 提供的一些巨集來插入頁面,要插入的頁面是 !insertmacro MUI_PAGE_LICENSE ".\resource\License.txt" !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES 最後還要插入語言 !insertmacro MUI_LANGUAGE English 3. 完善安裝程序內容設定 當然安裝程序的內容還要增加一些設定 BrandingText "Nullsoft Install System -- built on ${__DATE__} at ${__TIME__}" 這是設定安裝程序個人標誌的 InstallDir "$PROGRAMFILES\Winamp" 設定一個預設的安裝路徑 InstallDirRegKey HKCU "Software\Winamp" "" 優先讀取註冊表裡儲存的路徑,如果存在就是用註冊表儲存的路徑 4. 設定頁面 圖示的定義 !define MUI_ICON ".\resource\inst.ico" !define MUI_UNICON ".\resource\uninst.ico" 定義了安裝程序圖示和卸載程序圖示 !define MUI_HEADERIMAGE 定義在安裝程序頂端顯示一個圖形 !define MUI_HEADERIMAGE_BITMAP ".\resource\modern-header.bmp" 定義要顯示的圖形,必須是本機電腦上的 !define MUI_COMPONENTSPAGE_NODESC 指定元件選項頁面不使用描述區域 5. 設定頁面文本 !define MUI_LICENSEPAGE_TEXT_TOP "Please read and agree to the license terms below before installing." 指定許可頁面上頂端顯示的文本 !define MUI_COMPONENTSPAGE_TEXT_TOP "This will install Winamp ${VERSION}. This installer contains the full install." 指定元件選項頁面頂端的文本 !define MUI_DIRECTORYPAGE_TEXT_TOP "Setup has determined the optimal location to install. If you would like to change the folder, do so now." 指定目錄選項頁面的文本 !define MUI_ABORTWARNING 定義按取消按鈕時,提示是否真的結束 6. 設定安裝檔案類型,並把補全所有的區段 InstType "Full" InstType "Standard" InstType "Lite" InstType "Minimal" 一共四個安裝檔案類型,還有一個 Custom 檔案類型系統會自動增加,不必干預 然後在新增 46 個區段,一共有 47 個,名稱可以隨便起,因為區段的名稱到後面會由 gaydata.ini 來從命名,比如 Section " " SectionEnd 7. .onInit 函數 這個函數是在安裝程序 GUI 啟動完畢的時候開始執行裡面的程式碼,應該把那些資源文件在這個階段解壓縮到用戶電腦以供使用 InitPluginsDir 啟始化 $PLUGINSDIR 也就是插件目錄 File "/oname=$PLUGINSDIR\gaydata.ini" ".\resource\gaydata.ini" File "/oname=$PLUGINSDIR\opt2page.ini" ".\resource\opt2page.ini" File "/oname=$PLUGINSDIR\opt3page.ini" ".\resource\opt3page.ini" File "/oname=$PLUGINSDIR\classic256.bmp" ".\resource\classic256.bmp" File "/oname=$PLUGINSDIR\modern256.bmp" ".\resource\modern256.bmp" 因為在 .onInit 裡使用 File 會使程序啟動時要搜尋很久,所以還應該使用 ReserveFile,ReserveFile 的說明看這裡。 在 !include "MUI.nsh" 上面增加 ReserveFile ".\resource\gaydata.ini" ReserveFile ".\resource\opt2page.ini" ReserveFile ".\resource\opt3page.ini" ReserveFile ".\resource\classic256.bmp" ReserveFile ".\resource\modern256.bmp" ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll" 因為 InstallOptions.dll 在自訂界面要使用,所以也要加入 8. 元件的隱藏和顯示 細心的朋友都看到了指令碼裡面有兩個 !insertmacro MUI_PAGE_COMPONENTS,那麼元件選項頁面就會出現兩次,察看 gaydata.ini 就知道第一次顯示的是 sec0 到 sec36,第二次顯示的是 sec37 到 sec 47。 關於頁面的說明請看這裡 每個頁面都有三個函數: Pre、Show、Leave,分別是預載入、顯示、離開,在 MUI 界面可以用定義的方法來插入函數,比如在 !insertmacro MUI_PAGE_COMPONENTS 前(插入上一個頁面之後) 定義一個 MUI_PAGE_CUSTOMFUNCTION_PRE 函數就可以插入一個預載入函數。在本次指令碼中在第一個元件選項頁面作如下定義 !define MUI_PAGE_CUSTOMFUNCTION_PRE ComponentPre !define MUI_PAGE_CUSTOMFUNCTION_SHOW ComponentShow 上面定義了 ComponentPre、ComponentShow 函數,當然定義的函數名可以隨便起,但一般來說名字都要表達它的含義,便於閱讀。 在開始新增這兩個函數之前還要定義一些內容 !define SECTION_COMPONENT_END 36 !define SECTION_ASSCOIATION_START 37 !define SECTION_TOTAL 47 上面定義了 36 是要安裝的元件最後的區段索引好,37 是文件關聯等的開始區段索引號,47 是總共的區段數。ComponentPre 函數的內容如下 Function ComponentPre Push $0 Push $1 Call SectionTextReset StrCpy $1 0 loop: ReadINIStr $0 "$PLUGINSDIR\gaydata.ini" "secnames" "sec$1" StrCmp $0 "" 0 +2 SectionSetText $1 "" StrCmp $1 ${SECTION_COMPONENT_END} loop_quit IntOp $1 $1 + 1 Goto loop loop_quit: StrCpy $1 ${SECTION_ASSCOIATION_START} SectionSetText $1 "" StrCmp $1 ${SECTION_TOTAL} +3 IntOp $1 $1 + 1 Goto -3 Pop $1 Pop $0 FunctionEnd 這個函數使用了 SectionTextReset 函數,SectionTextReset 函數如下 Function SectionTextReset Push $R0 StrCpy $R0 0 SectionSetText $R0 " " StrCmp $R0 ${SECTION_TOTAL} +3 IntOp $R0 $R0 + 1 Goto -3 Pop $R0 FunctionEnd SectionTextReset 函數構成一個循環,$R0 從 0 開始遞增,直到等於 ${SECTION_TOTAL} 後跳出循環,這個循環把所有區段的名稱都重置為空格,在兩個 MUI_PAGE_COMPONENTS 頁面的預載入函數都使用一次。這是因為 Show 函數會把一些區段隱藏,即把區段名稱設為空值,在下一個 MUI_PAGE_COMPONENTS 頁面的 Pre 階段必須給它一個名稱,否則它將一直隱藏。 使用了 SectionTextReset 函數之後是一個循環,這個循環讀取 "$PLUGINSDIR\gaydata.ini" 的 sec0 到 ${SECTION_COMPONENT_END} ,如果某個 sec 讀到的值為空,則把該區段隱藏,也就是把區段名設為空值。你可以試試英文原版,剛啟動時把 "$PLUGINSDIR\gaydata.ini" 的 sec0 設為空值,到了元件選項頁面 Winamp (required) 區段就被隱藏了。 再下來也是一個循環,把 ${SECTION_ASSCOIATION_START} 到 ${SECTION_TOTAL} 的區段隱藏,因為第一個 MUI_PAGE_COMPONENTS 只需要顯示 0 到 ${SECTION_COMPONENT_END} 的區段。ComponentShow 函數如下 Function ComponentShow Push $0 Push $1 StrCpy $1 0 loop: ReadINIStr $0 "$PLUGINSDIR\gaydata.ini" "secnames" "sec$1" SectionSetText $1 $0 StrCmp $1 ${SECTION_COMPONENT_END} loop_quit IntOp $1 $1 + 1 Goto loop loop_quit: Pop $1 Pop $0 FunctionEnd 也是一個循環,$1 的值從 0 到 ${SECTION_COMPONENT_END} 遞增,則是依次從 sec0 到 sec36 讀取 gaydata.ini 相應的值,並根據讀取道的值來從命名區段名稱。 第二個元件頁面對應的 AsscoiationPre、AsscoiationShow 與上面的基本一致,只是要隱藏的區段索引不同而已。 9. 隱藏控件 元件頁面第二次顯示的時候,有幾個控件是隱藏的,用 Resource Hacker 開啟 ${NSISDIR}\Contrib\UIs\modern.exe 裡面的 104 對話視窗就是元件顯示頁面,要隱藏的空間 ID 為 1017 (顯示安裝檔案類型) 和 1021 (它左邊顯示的文本) 還有 1023 (磁牒空間顯示的控件)。顯示和隱藏控件的指令為 ShowWindow ,說明請看這裡。 隱藏控件的程式碼需要加在 AsscoiationShow 函數里。 FindWindow $0 "#32770" "" $HWNDPARENT 獲取一個視窗關鍵句儲存在 $0 裡 GetDlgItem $1 $0 1017 獲取 1017 控件的關鍵句 ShowWindow $1 ${SW_HIDE} 隱藏 1017 控件,其他幾個控件的隱藏指令依次為 GetDlgItem $1 $0 1021 ShowWindow $1 ${SW_HIDE} GetDlgItem $1 $0 1023 ShowWindow $1 ${SW_HIDE} 除了控件隱藏之外,還有兩處文本需要更改,由於使用 !define 只能對第一次顯示的元件頁面更改,所以第二次顯示的文本只能自己用 SendMessage 來改了 GetDlgItem $1 $0 1006 SendMessage $1 ${WM_SETTEXT} 0 "STR:Select which icons you want installed, and whether you want files and CDs associated with" GetDlgItem $1 $0 1022 SendMessage $1 ${WM_SETTEXT} 0 "STR:Select icons to install and media associations:" |
哇@@"您好厲害啊..佩服佩服
|
所有時間均為台北時間。現在的時間是 09:40 AM。 |
Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.
『服務條款』
* 有問題不知道該怎麼解決嗎?請聯絡本站的系統管理員 *