在目前的三太子安裝/補綴腳本當中,有這一段:
==
; 安裝前先檢查是否有殘留先前的 Opera 檔案
; 從登錄讀取 Opera 的安裝路徑(如果有的話),讀出來的東西會是類似 "PATH\Opera.exe" "%1" 這樣的字串
RegRead, OperaInstallPathReg, HKLM, SOFTWARE\Classes\Opera.HTML\shell
\open\command
; 祇有 PATH 那串有用,所以用正規表示式切出來
OperaInstallPath := RegExReplace(OperaInstallPathReg, ".(.:.+)\\
[Oo]pera\.exe.+$", "$1")
==
這段正規表示式應該是在我還沒找到 AutoHotKey 逸出字元(`)的時候寫出來的,不過這不是重點,重點是如果這邊讀出來的結果是 C:
\Program Files\ 怎麼辦?目前的腳本僅做了「這個讀出來的路徑是否存在」的檢測:
==
IfExist, %OperaInstallPath%
==
然而,C:\Program Files\ 是一定會存在的,接下來就會發生悲劇,像是把 Opera 直接裝到這裡面,最後並且在 HKLM
\SOFTWARE\Classes\Opera.HTML\shell\open\command 寫入 C:
\PROGRA~1\Opera.exe,導致日後相同的慘劇會再次重演。
==
AskUserOperaInstallPath:
; 檢查此路徑下是否真的有 opera.exe 存在,否則就把 OperaInstallPath 變數設回空白,以便詢問使用者
IfNotExist, %OperaInstallPath%\opera.exe
OperaInstallPath = ""
if (OperaInstallPath = "") {
; 如果讀不到路徑,纔去詢問使用者
FileSelectFolder, OperaInstallPath, ::{20d04fe0-3aea-1069-
a2d8-08002b30309d}, 0, %SelectOperaPath% %ProgramFiles%\Opera
}
if (OperaInstallPath = "") {
; 如果從登錄讀不到路徑,使用者又沒有設定(按了取消),就用預設值
OperaInstallPath = %ProgramFiles%\Opera
}
; 檢查此路徑下是否真的有 Opera.exe 存在,否則就重新詢問使用者
IfNotExist, %OperaInstallPath%\opera.exe
Goto, AskUserOperaInstallPath
==
另外,在 installer.ahk 裡面,原本的這段:
==
; 如果通通都沒有,就回到正常的安裝步驟
Goto, installopera
==
修改為:
==
; 如果通通都沒有,就清掉顯然有誤的登錄資料,然後回到正常的安裝步驟
RegDelete, HKLM, SOFTWARE\Classes\Opera.HTML
Goto, installopera
==
有空的時候會來測測看這樣能不能避開先前發現的瑕疵。
如果可以的話,下一步就是加入判斷是否有正黑體可用,
(這部份的討論則會在 http://groups.google.com/group/operanalakuvara/browse_thread/thread/e565203ae70d1af9
進行)
然後就可以釋出新的安裝套件/補綴套件 (for 10.10) 了。
所以看是要更早檢查,還是要怎麼樣,唔。
> (這部份的討論則會在http://groups.google.com/group/operanalakuvara/browse_thread/thread/e...
installer.ahk 檢查這個的時候,是在 Opera 已經「安裝好」的時候,所以還是沒問題的。
倒是備份前,也還要補上檢查路徑是否與 ProgramFiles 相同。
==
previousfound:
; 詢問是否要移除所有 Opera 留下來的檔案(移到備份目錄去)
MsgBox, 36, %TitleDelete%, %AskDeleteInstall%
IfMsgBox, No
ExitApp
if (OperaInstallPath = "") {
; 如果讀不到路徑,纔詢問使用者
...
}
if (OperaInstallPath = "") {
; 如果從登錄讀不到路徑,使用者又沒有設定(按了取消),就用預設值
...
}
; 取得 Opera 安裝路徑後,接著先建立備份要用的到目錄 %APPDATA%\Opera Nalakuvara Backup\年月日
....
==
改成這樣:
==
previousfound:
; 詢問是否要移除所有 Opera 留下來的檔案(移到備份目錄去)
MsgBox, 36, %TitleDelete%, %AskDeleteInstall%
IfMsgBox, No
ExitApp
AskUserOperaInstallPathForBackup:
if (OperaInstallPath = "") {
; 如果讀不到路徑,纔詢問使用者
...
}
if (OperaInstallPath = "") {
; 如果從登錄讀不到路徑,使用者又沒有設定(按了取消),就用預設值
...
}
; 如果安裝路徑等於 ProgramFiles 則要求使用者重選
if ( OperaInstallPath = ProgramFiles ) {
FileSelectFolder, OperaInstallPath, ::{20d04fe0-3aea-1069-
a2d8-08002b30309d}, 0, %SelectOperaPath% %ProgramFiles%\Opera
Goto, AskUserOperaInstallPathForBackup
}
; 取得 Opera 安裝路徑後,接著先建立備份要用的到目錄 %APPDATA%\Opera Nalakuvara Backup\年月日
....
==
晚一點來測試看看。
AllUsersProfile
AppData
CommonProgramFiles
HomeDrive
SystemDrive
SystemRoot
Temp
UserProfile
WinDir
所以辦法是這樣的,首先指定一個「黑名單」(我是放進 strings.ahk 裡面):
==
; Opera 安裝路徑黑名單
SystemPathCheckList = %AllUsersProfile%,%AppData%,%CommonProgramFiles%,
%HomeDrive%,%ProgramFiles%,%SystemDrive%,%SystemRoot%,%Temp%,
%UserProfile%,%WinDir%
==
請注意項目之間僅有逗號,沒有空格。
然後就可以這樣來檢查:
==
if OperaInstallPath in %SystemPathCheckList%
......
==
不過要注意 if var in list 這樣的寫法,只有下一列會套用,所以無法做很多事,因此目前只好很蠢的這樣寫:
==
; 如果安裝路徑等於任何系統路徑則要求使用者重選
if OperaInstallPath in %SystemPathCheckList%
MsgBox, 16, %TitleError%, %MessageOperaBackupFromPathError%
if OperaInstallPath in %SystemPathCheckList%
FileSelectFolder, OperaInstallPath, ::{20d04fe0-3aea-1069-
a2d8-08002b30309d}, 0, %SelectOperaPath% %ProgramFiles%\Opera
if OperaInstallPath in %SystemPathCheckList%
Goto, AskUserOperaInstallPathForBackup
if (OperaInstallPath = "") {
Goto, AskUserOperaInstallPathForBackup
}
==
希望之後能想到更好的寫法。
所以就可以精簡成這樣了:
==
; 如果安裝路徑等於任何系統路徑則要求使用者重選
if OperaInstallPath in %SystemPathCheckList%
{
MsgBox, 16, %TitleError%, %MessageOperaBackupFromPathError%
FileSelectFolder, OperaInstallPath, ::{20d04fe0-3aea-1069-
a2d8-08002b30309d}, 0, %SelectOperaPath% %ProgramFiles%\Opera
Goto, AskUserOperaInstallPathForBackup
}
==
==
; 檢查指定的使用者 JavaScript 路徑是否安全可用
if UserJSPath in %SystemPathCheckList%,%OperaInstallPath%
{
MsgBox, 16, %TitleError%, %MessageUserJSPathError%
Goto, enableuserjs
}
==
亦即排除各個系統路徑,以及 Opera 本身的路徑(當然,這些路徑內的子目錄則沒有問題)
另外,由於選擇路徑時,如果選擇了磁碟根目錄,AutoHotKey 會自動補上 \,例如 C: 就會變 C:\,
如此就無法與 %HomeDrive% 與 %SystemDrive% 匹配,因此在列出黑名單時,
就要手動把這兩個環境變數後面預先補上 \
即:
==
SystemPathCheckList = %AllUsersProfile%,%AppData%,%CommonProgramFiles%,
%HomeDrive%\,%ProgramFiles%,%SystemDrive%\,%SystemRoot%,%Temp%,
%UserProfile%,%WinDir%
==