AutoHotKey_Lで、OperaのRamDisk運用を便利にしたかった……。
前回の更新直後に「コピーのタイミングってWindowsの起動/終了時でいいんじゃ……」と遅まきながら気づいてしまい、レストア/バックアップ機能だけ取り出し強化したのだが、結局、「バッチでXCOPY使えばいい」の域を出られなかった残念なAHKスクリプト。
一応、起動時にOperaをRamDiskにコピーし、Opera終了時/Windows終了時には自動でバックアップしてくれる。――のだが、バックアップ対象を絞らないと30秒ほどかかるので、レジストリで「応答のないアプリケーションを自動で終了する」をONにしてると間に合わない。
グループポリシーが使える環境の人は、シャットダウンスクリプトでXCOPY使うのが正解。でなければ、RamDiskを自動バックアップ対応のものに変えれ。
; --------- --------- --------- --------- ---------
;
; CopyOpera.ahk
;
; ・起動時にOperaをRamDiskにコピー(レストア)する。
; ・常駐中はOperaを監視し、隙あらばHDDにコピー(バックアップ)する。
; ・Operaが終了した時や、Windowsが終了する時など。
; ・指定フォルダの除外コピーが可能(cacheフォルダやmailフォルダなど)
;
; --------- --------- --------- --------- ---------
#Persistent
OperaPath := "C:\Program Files\Opera\Opera" ; Opera.exeの存在するフルパスを指定。
RamPath := "R:\Opera" ; Operaのコピー先となるフルパスを指定。
NGPathR := "profile\cache | profile\icons | profile\mail | profile\opcache | profile\temporary_downloads" ; レストアしないディレクトリをOperaPathからの相対パスで指定
NGPathB := NGPathR ; バックアップしないディレクトリを、RamPathからの相対パスで指定
; --------- --------- --------- --------- ---------
OperaPath := CutLastDelimiter(OperaPath), RamPath := CutLastDelimiter(RamPath)
NGPathR := ConvList(NGPathR), NGPathB := ConvList(NGPathB)
OpBackupSW := 0
gosub, OpRestore
SplashView("OperaReady!")
OnExit, ExitOp
SetTimer, CheckOp, 5000
return
; --------- --------- --------- --------- ---------
ExitOp:
if OpBackupSW {
Process, WaitClose, opera.exe
gosub, OpBackup
SplashView("OperaBackup!")
Sleep, 3000
}
ExitApp
; --------- --------- --------- --------- ---------
CheckOp:
Cnt++
if (30 < Cnt) {
Cnt := 0
FileCopy, %RamPath%\profile\sessions\autosave.win, %OperaPath%\profile\sessions\autosave.win, 1
}
Process, WaitClose, opera.exe, 1
if (0 == ErrorLevel) { ; Operaが動いていなければ
if OpBackupSW { ; まだバックアップされていなければ
gosub, OpBackup
SplashView("OperaBackup!")
OpBackupSW := 0
}
} else{ ; Operaが動いていれば
OpBackupSW := 1
}
return
OpRestore:
DirList := DigDirList(OperaPath, OperaPath, NGPathR)
DirSet(RamPath, DirList)
DirListCopy(DirList, OperaPath, RamPath)
return
OpBackup:
DirList := DigDirList(RamPath, RamPath, NGPathB)
DirSet(OperaPath, DirList)
DirListCopy(DirList, RamPath, OperaPath)
return
; --------- --------- --------- --------- ---------
ConvList(FileList) {
Res := ""
Loop, Parse, FileList, |, %A_Space% \
{
if ("" == A_LoopField)
continue
FieldBuf := CutLastDelimiter(A_LoopField)
result := result FieldBuf "`n"
}
return, CutLastNL(result)
}
GetDirList(TrgDir, RootPath , NGList) {
if ("" == TrgDir)
return
result := ""
LoopPattern := RootPath "\" CutRootPath(TrgDir, RootPath) "\*"
Loop, %LoopPattern%, 2, 0
{
GetDir := CutRootPath(A_LoopFileLongPath, RootPath)
if !NGCheck(GetDir, NGList)
result := result GetDir "`n"
}
return, CutLastNL(result)
}
DigDirList(TrgPath, RootPath, NGList) {
DirList := "`n"
TrgDirList := GetDirList(TrgPath, RootPath, NGList) "`n"
ResDirList := ""
Loop {
Loop, Parse, TrgDirList, `n
{
ResDir := GetDirList(A_LoopField, RootPath, NGList)
if ("" != ResDir)
ResDirList := ResDirlist ResDir "`n"
}
DirList := DirList TrgDirList
TrgDirList := ResDirList
ResDirList := ""
if ("" == TrgDirList)
break
}
return, CutLastNL(DirList)
}
DirSet(TrgPath, DirList) {
Loop, Parse, DirList, `n
FileCreateDir, %TrgPath%\%A_LoopField%
return
}
DirListCopy(DirList, RootPath, SendPath) {
Loop, Parse, DirList, `n
FileCopy, %RootPath%\%A_LoopField%\*, %SendPath%\%A_LoopField%, 1
return
}
NGCheck(Keyword, NGList) {
Loop, Parse, NGList, `n
{
if (1 == RegExMatch(Keyword, "s)^" EscRegEx(A_LoopField)))
return, 1
}
return, "0"
}
CutLastDelimiter(TrgPath) {
StringRight, CharBuf, TrgPath, 1
if ("\" == CharBuf)
StringTrimRight, TrgPath, TrgPath, 1
return, TrgPath
}
CutLastNL(TrgPath) {
result := RegExReplace(TrgPath, "s)[\r\n]+\z", "", $, 1)
return, Result
}
CutRootPath(TrgPath, RootPath) {
return, RegExReplace(TrgPath, "s)^" EscRegEx(RootPath) "(\\)?", "", $, 1)
}
EscRegEx(trg) {
EscList := "\`n.`n*`n?`n+`n[`n]`n{`n}`n|`n(`n)`n^`n$"
Loop, Parse, EscList, `n
StringReplace, trg, trg, %A_LoopField%, \%A_LoopField%, 1
return, trg
}
; --------- --------- --------- --------- ---------
SplashView(TextBuf, Timer = 3000) {
Progress, B1 ZH0 W800, %TextBuf%
SetTimer, SplashClose, %Timer%
}
SplashClose:
SetTimer, SplashClose, Off
Progress, Off
return
下位フォルダをいじるスクリプトに流用できるから、無駄死にではないぞ。ま、負け惜しみじゃないんだからっ。
PCの突然死対策に、2分半に一度、autosave.winだけバックアップするようにしてみた。というか使うだけならバックアップするのこれだけでよさげ。