blechmusikの日記

キー・カスタマイズ・ソフトウェア "DvorakJ" の覚え書きをはじめとして様々なことを書いています。

DvorakJ の最新版をダウンロードし、既存のファイルを自動的に上書きするスクリプトを作成した

先のエントリーで説明した、 zip ファイルを展開する関数を使用して、表題の機能を実現する AutoHotkey_L (unicode 版) 用スクリプトを作成した。
以下のソースを UTF-8 (BOM付き)で保存し、 DvorakJ\apps フォルダに置いて、このスクリプトを実行するだけでよい*1。DvorakJ を実行中にこのスクリプトを実行すれば、設定ファイル一式を上書き更新した後に、DvorakJ を自動的に再起動する。
問題は、DvorakJ からこのスクリプトを呼び出して様々な処理をしたいが、今のところ、そうはできないことだ。様々な処理をする上では、AutoHotkey の Run コマンドで、プログラムに様々な引数を与えることになろう。この処理がうまくいかないのである。そのような処理が上手くでき次第、このプログラムと DvorakJ を連携させることになるだろう。
別の問題もある。以下のソースを実行ファイルに変換しようとしたら、エラーが表示されるのみだ。どうやら、COM オブジェクトの操作に毎度失敗しているようだ。AutoHotkey_L のスクリプトとしては正常に実行できるので、興味がある方は試してみて下さい。

#SingleInstance force
SetWorkingDir, %A_ScriptDir%

arg1 = %1%
arg2 = %2%

Progress, 50, , 更新情報を取得中, DvorakJ の自動更新

;;; 親ディレクトリを取得する
StringGetPos, pos, A_ScriptDir, \, R1
StringLeft, DvorakJ_Dir, A_ScriptDir, %pos%


;;; あふwのアップデート用スクリプト
;;; http://www.ezinfo.jp/doc/2009/05/22/%E3%81%82%E3%81%B5%EF%BD%97%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E7%94%A8%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88-1171.html


i = 0
While 1
{
    zipdir = %A_Temp%\DvorakJ_update%i%\
    IfNotExist, %zipdir%
    {
        FileCreateDir, %zipdir%
        if ErrorLevel <> 0
            continue
        else
            break
    }

    i++
}


DvorakJ_web_README_path := zipdir . "\DvorakJ_doc_README.txt"
url := "http://blechmusik.xrea.jp/resources/keyboard_layout/DvorakJ/doc/README.txt"

; web 上の README.txt を取得
URLDownloadToFile, %url%, %DvorakJ_web_README_path%

FileReadLine, web_README, %DvorakJ_web_README_path%, 2
FileReadLine, local_README, %DvorakJ_Dir%\doc\README.txt, 2

;; 最新版を使用しているとき
If ( web_README = local_README )
{
    Progress, Off
    MsgBox, 
        , DvorakJ の更新情報
        , 最新版を使用しています
}
else ;; 最新版を使用していないとき
{
    RegExMatch(web_README, "(\d{4}-\d{2}-\d{2})", $)
    web_date := $

    zipurl := "http://blechmusik.xrea.jp/resources/keyboard_layout/DvorakJ/dj_" . web_date . ".zip"

    if (arg1 = "-download")
    {
    	Progress, Off

        msgbox, 4
                , DvorakJ の更新情報
                , 新しい版(%web_date% 版)が公開されています`n`nダウンロードしますか?
        IfMsgBox, Yes
            Run,%zipurl%


        if (arg2 = "-install")
            Progress, 50, , 更新情報を取得中, DvorakJ の自動更新
        else
            return
    }



    tempzip = %zipdir%DvorakJ_temp.zip
    ;;; DvorakJ の最新版を DvorakJ_temp.zip というファイル名でダウンロード
    UrlDownloadToFile, %zipurl%, %tempzip%
    
    Progress, 80, , プログラムを更新中, DvorakJ の自動更新
    
    ;;; 圧縮ファイルを展開する
    Unz(tempzip, zipdir)
    
    ;;; ウィンドウタイトルを完全一致モードで検索する
    SetTitleMatchMode, 3
    
    Loop
    {
        IfWinExist , DvorakJ, , ,
        {
            reboot := 1
            WinClose
        }
        Else
            break
    }
    
    
    FileDelete, %DvorakJ_web_README_path%
    FileDelete, %tempzip%
    ;;; DvorakJ.exe だけは MoveFilesAndFolders() で移動できないので
    ;;; 手動で移動させる
    FileMove, %zipdir%DvorakJ.exe, %DvorakJ_Dir%\, 1
    
    ErrorCount := MoveFilesAndFolders(zipdir . "*.*", DvorakJ_Dir, 1)
    if ErrorCount <> 0
      MsgBox 総計 %ErrorCount% のファイルとフォルダを移動できません
    
    Progress, 100, , 更新完了, DvorakJ の自動更新
    sleep, 500
    Progress, Off

    if ( reboot )
    {
        ;;; DvorakJ を起動する
        Run,%DvorakJ_Dir%\DvorakJ.exe
    }
}

return


;;; FileMove - AutoHotkeyJp
;;; http://sites.google.com/site/autohotkeyjp/reference/commands/FileMove
MoveFilesAndFolders(SourcePattern, DestinationFolder, DoOverwrite = false)
{
    if DoOverwrite = 1
        DoOverwrite = 2     ; See FileMoveDir for description of mode 2 vs. 1.

    ; First move all the files (but not the folders):
    FileMove, %SourcePattern%, %DestinationFolder%, %DoOverwrite%
    ErrorCount := ErrorLevel
    
    ; Now move all the folders:
    Loop, %SourcePattern%, 2    ; 2 means "retrieve folders only".
    {
        FileMoveDir, %A_LoopFileFullPath%, %DestinationFolder%\%A_LoopFileName%,     %DoOverwrite%
        ErrorCount += ErrorLevel
        if ErrorLevel  ; Report each problem folder by name.
          MsgBox %A_LoopFileFullPath% を %DestinationFolder% へと移動できません
    }
    
    return ErrorCount
}

;;; Zip/Unzip using native ZipFolder Feature in XP
;;; http://www.autohotkey.com/forum/post-335359.html#335359


;;; COM Standard Library
;;; http://www.autohotkey.com/forum/viewtopic.php?p=330998#330998
Unz(sZip, sUnz)
{
    psh := ComObjCreate("Shell.Application")
    psh.Namespace( sUnz ).CopyHere( psh.Namespace( sZip ).items, 4|16 )
    return
}

*1:insight さんのコメントを受けて、文字コードの設定を追記した。