史萊姆論壇

返回   史萊姆論壇 > 教學文件資料庫 > 多媒體影音轉檔燒錄技術文件
忘記密碼?
論壇說明 標記討論區已讀

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


 
 
主題工具 顯示模式
舊 2004-12-13, 01:51 PM   #1
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 取得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:"
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次
舊 2004-12-16, 07:35 AM   #2 (permalink)
jasoncute
榮譽勳章

勳章總數
UID -
在線等級:
文章: n/a
精華:
預設

哇@@"您好厲害啊..佩服佩服
 
送花文章: 0, 收花文章: 0 篇, 收花: 0 次
 


主題工具
顯示模式

發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 06:07 AM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2022, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1