#http://www.ac-promenade.net/text/windowsmobile/ #Scripted by AC-Promenade http://www.ac-promenade.net/ #フォルダ・バックアッパー #FolderBackuper.mscr #指定フォルダ間の内容を バックアップ / 同期 させるMortScript。 #PC、モバイル両方で実行可能です。(当然PCの方が処理が速いです。) #また実処理を行わずに処理結果を確認する"テスト実行"が可能です。 #モバイル側で実行することで、PCから認識できないデバイス本体への #バックアップや同期、条件コピー等Wifi経由で行うのが狙いです。 #プロジェクトは複数登録して、連続実行ができます。 #●使用方法概要 #いくつかの動作は設定により変更できます。 #・バックアップを取りたいフォルダ間の設定を本mscrに記述します。 #・本mscrを実行すると、ダイアログ画面が起動します。 #・設定により、Wifi起動するアプリを実行させることができます。 #・設定により、Wifi終了するアプリを実行させることができます。 #・オプションを実行すると、全体設定を一時的に変更できます。 #・全てテストを実行すると、チェック項目の実行テストをします。 #・全て実行を実行すると、チェック項目を実際に処理します。 #・各プロジェクト項目ごとに単独実行や詳細確認ができます。 #●動作確認デバイス #DesktopPC, Advanced/W-ZERO3[es], WILLCOM 03, HYBRID W-ZERO3 #その他機種はMortScriptが動くならおよそ動くかと思います。 #●必要環境 #・MortScript4.2以上(4.1以下不可)、mscrの関連付け。 # http://www.sto-helit.de/ (PCサイト) #●補足事項 #ファイル操作を行うプログラムです、取扱いには十分ご注意下さい。 #実行は取り返しが付かないので、必ずテストを行って下さい、 #誤って大事なファイルがなくなっても、あくまで自己責任です。 #実行結果と実際の処理が正しいかも、必ず確認して下さい。 #気を付けてはいますが、所詮は馬の骨日曜プログラムです。 #このソースと説明が全て正しいとは限らない事を念頭に置いて下さい。 #なのでバグ等ありましたら是非ご報告頂ければと思います。 #ディレクトリ処理毎にサスペンド回避を送ってますが、 #ひとつのディレクトリ内のフォルダやファイル、又設定条件など #スキャン量が凄く多いと、ディレクトリ一つ分のスキャン完了までに #サスペンド回避が間に合わない場合もあるかもしれません。 #その際はサスペンド時間を長く取るか、機能を切って下さい。 #(ディレクトリ内容取得に1分以上かかる量は稀だとは思いますが。) #・GUI無しに実行だけで無線LANをオンオフできる何らかのソフト。 #WM6.1以前のZERO3系ならwifictrl、CAM起動はWifiPowerMode v0.1。 # http://w03holic.seesaa.net/article/51166074.html # http://blog.tauchi.net/2007/12/lan.html (CAMが必要なら) #WM6.5のHYBRID W-ZERO3ならwifictrl TA-01。 # http://emboss.blog28.fc2.com/blog-entry-110.html #アンインストールの際は、本mscrを削除するだけで大丈夫です。 #必要なければ、ログファイルやそのフォルダパスも削除して下さい。 #その他レジストリの追加等は行っていません。 #本mscrによって生じる不利益に当方は関与しません。 #設定変数値を除く内容に改ざんがない限り、再配布は自由です。 #内容に変更を加えた際の再配布は、必ずその変更前と変更後の #明記を、本文中にて行ってあれば構いません。 #--------------------------------------------------------------- #以下環境設定 #(書き換えの際、文字コードS-JISが変換されないよう御注意下さい。) #■ログの保存フォルダを指定(""空欄だと本mscrと同じ場所に保存) (存在しないフォルダの場合も本mscrと同じ場所になります。) LogDirectory="" #■ログファイル名に日時を加える=1 加えない(同名上書き)=0 LogTmStamp=0 #■Wifi(無線LAN)を有効にするアプリを利用する場合パスを指定 #(利用していなければ、特に変更の必要はありません) #(故意に利用しないのであれば""内を空欄にでもして下さい) #(パスを叩くだけなので、使えそうなら何を指定してもいいです) WifiOnCmd="\Program Files\wifictrl\Wifictrl.exe" #■必要であればWifiOnに与える引数を指定 必要なければ""内空欄 WifiOnArg="on" #■Wifi(無線LAN)を無効にするアプリを利用する場合パスを指定 #(利用していなければ、特に変更の必要はありません) #(故意に利用しないのであれば""内を空欄にでもして下さい) #(パスを叩くだけなので、使えそうなら何を指定してもいいです) WifiOffCmd="\Program Files\wifictrl\Wifictrl.exe" #■必要であればWifiOffに与える引数を指定 必要なければ""内空欄 WifiOffArg="off" #■処理完了後、自動的にWifiOffCmdを実行する=1 しない=0 AutoWifiOff=0 #■処理完了後、そのまま本mscrを終了=1 メニュー画面に戻る=0 AutoExitOut=0 #■指定フォルダ間のバックアップを行うプロジェクト設定を登録。(複数可)※詳細は後述 #サンプルとしてスマートフォン側からWifi経由でPCマイピクチャへカメラ画像を転送 Project[1]="モバイルカメラ画像をPCへ" MasterDir[1]="\microSCカード\DCIM" BackupDir[1]="\\NetworkPC\My Pictures\Camera画像" EqTimeRange[1]=3 ClusterSize[1]=32 #サンプルとしてPCのルートドライブ以下の内容を完全ミラーリングする場合の記述 Project[2]="Xドライブの完全バックアップ" MasterDir[2]="X:\" BackupDir[2]="Y:\Sample" Check[2]=0 SubDirExec[2]=1 SubDirAttr[2]=1 Mirroring[2]=1 OWtoTmLess[2]=1 OWtoTmGreat[2]=1 OWtoDetail[2]=1 OWtoTmEqual[2]=0 EqTimeRange[2]=0 RomFileExec[2]=1 HidFileExec[2]=1 RomDirExec[2]=1 HidDirExec[2]=1 OnlyFile[2]=Array() ExceptFile[2]=Array("pagefile.sys") OnlyDir[2]=Array() ExceptDir[2]=Array("RECYCLER","System Volume Information") RndCopyDel[2]=0 ErrMsgSkip[2]=0 ChkFileSize[2]=1 ClusterSize[2]=4 #※以下、プロジェクト設定の詳細を説明します。 # Project[]="プロジェクト番号の任意名称 (要指定)" # MasterDir[]="マスター側フォルダのパス (実質要指定)" # BackupDir[]="バックアップ側フォルダのパス (実質要指定)" # Check[]=起動時にプロジェクトをチェック状態にする=1 しない=0 # SubDirExec[]=サブフォルダも含めて処理をする=1 しない=0 # SubDirAttr[]=サブフォルダの属性も反映する=1、しない=0 # Mirroring[]=マスター側に無いファイルやフォルダは削除する=1 しない=0 # OWtoTmLess[]=更新日時の古い同名ファイルへの上書きをする=1 しない=0 #OWtoTmGreat[]=更新日時の新しい同名ファイルへの上書きをする=1 しない=0 # OWtoDetail[]=更新日時が同じでも属性や容量が異なれば同名ファイルへの上書きをする=1 しない=0 #OWtoTmEqual[]=更新日時が同じ同名ファイルへの上書きをする=1 しない=0 #EqTimeRange[]=更新日時を同一と見なす+-誤差許容範囲を整数(秒)で指定 (NTFSとFAT間など) #RomFileExec[]=読み取り専用ファイルを処理の対象にする=1 しない=0 #HidFileExec[]=隠しファイルを処理の対象にする=1 しない=0 # RomDirExec[]=読み取り専用フォルダを処理の対象にする=1 しない=0 # HidDirExec[]=隠しフォルダを処理の対象にする=1 しない=0 # OnlyFile[]=Array("処理するファイルを限定する場合ファイル名(ワイルドカード可)を記述 (複数指定可)") # ExceptFile[]=Array("処理しないファイルを指定する場合ファイル名(ワイルドカード可)を記述 (複数指定可)") # OnlyDir[]=Array("処理するサブフォルダを限定する場合フォルダ名(ワイルドカード、\区切り可)を記述 (複数指定可)") # ExceptDir[]=Array("処理しないサブフォルダを限定する場合フォルダ名(ワイルドカード、\区切り可)を記述 (複数指定可)") # RndCopyDel[]=Mirroring有効時、コピーと削除を同時に行う=0 コピー処理を先行する=1 削除処理を先行する=2 # ErrMsgSkip[]=エラー(処理想定内)の際、メッセージ表示をスキップする=1 しない=0 (ログは記載されます) #ChkFileSize[]=容量計算のためにファイル容量を全て取得する=1、しない=0 #ClusterSize[]=容量計算用クラスタサイズを整数(KB)で指定 #パラメータ名[プロジェクト番号]=付与値 という書式になっています。 #Projectの[]内番号は1から連番で並んでいる必要があります。 #なので設定のソートが面倒であれば、変数処理を自前でこしらえるといいです。 #hensu+=1 #Parameter[hensu]=Value #Project以外の項目は省略が可能です。(0や空欄が適用されます) #(動作には実質、MasterDir[]、BackupDir[]の指定も必要です。) #=の後が数値ではない、文字やパス指定の場合、""内に記述して下さい。 #=の後が複数指定可能な項目は,で区切り、単一であってもArray()内に記述して下さい。 #OnlyとExceptは、Exceptが優先されます。例えば、 #OnlyFile[?]=Array("*.txt") #ExceptFile[?]=Array("test.txt") #こう指定するとtest.txtを除いた全てのtxtファイルをバックアップします。 #容量計算はあくまで目安と思って下さい。(32Bit環境による2TBの壁もあります) #尚、条件は少ない方が処理完了までの時間が短縮できます。 #プロジェクトが多い際は、本mscrをコピーして設定分割するのも手段の一つです。 #--------------------------------------------------------------- #バージョン履歴 #1.00 試験公開。 #--------------------------------------------------------------- #Main Script #PPC確認 If(MortScriptType() eq "PPC") MobileDevice=1 Else MobileDevice=0 EndIf #現在のファイル名取得、ウィンドウ名、ログファイル名等に利用 ThisScrName=SystemPath("ScriptName") #メインパラメータ01系配列化 MnParameters=Array(\ "LogTmStamp",\ "AutoWifiOff",\ "AutoExitOut",\ "NotDynaLog",\ "AppDynaLog") #全プロジェクトパラメータ配列化とMax数 Call("AryAllPrPrm") #プロジェクトMAX数取得 MaxProject=MaxIndex(Project) #■デバッグ用 #ログ保存するかを後で確認(エラー含む)=1 動的に記録=0 #1だとログがリアルタイムに残らないので、想定外のエラーに注意。 If(IsEmpty(NotDynaLog)) NotDynaLog=0 EndIf #ログ保存設定ダイアログオプション出現 If(IsEmpty(AppDynaLog)) AppDynaLog=0 EndIf #■ダイアログ初起動準備 DlgTitle=ThisScrName&" / by AC-Promenade" MainMenu=1 NumMain=1 OptMenu=0 SubMenu=0 #チェックリセット用の記憶 PreCheck=Check #オプションリセット用のFix化 Call("OptReset") #▼全処理完了後ダイアログに戻る(インデント省略中) While(1) #■ダイアログ選択画面 Ok=0 While (Not Ok) While (MainMenu and Not OK) #■メインメニュー準備 #ダイアログプロンプト CallFunction("DlgPromptOpt",DlgPromptMain) #ダイアログ選択肢 Clear(DMNIdx) Clear(DlgListMain) If(FileExists(WifiOnCmd)) DMNIdx+=1 DlgListMain[DMNIdx]="無線LAN ON" EndIf If(FileExists(WifiOffCmd)) DMNIdx+=1 DlgListMain[DMNIdx]="無線LAN OFF" EndIf DMNIdx+=1 DlgListMain[DMNIdx]="オプション設定" #プロジェクトがあり、かつチェックが入ってれば項目出現 i=0 While(MaxProject>i) i+=1 If (Check[i]=1) i=MaxProject DMNIdx+=1 DlgListMain[DMNIdx]="チェックを全て テスト" DMNIdx+=1 DlgListMain[DMNIdx]="チェックを全て 実行" EndIf EndWhile DMNIdx+=1 DlgListMain[DMNIdx]="終了" #変動した項目数を控えておく ChoiceOffset=DMNIdx #残りのプロジェクト全部 For i = 1 to MaxProject Step 1 If (Check[i]=1) DefChk="●" Else DefChk="─" Check[i]=0 EndIf DMNIdx+=1 DlgListMain[DMNIdx]=DefChk&"["&i&"] "&Project[i] Next DMNIdx+=1 DlgListMain[DMNIdx]="選択反転" DMNIdx+=1 DlgListMain[DMNIdx]="選択全て" DMNIdx+=1 DlgListMain[DMNIdx]="選択リセット" #チェックトグルして戻ってきた時、項目数増減に合わせる If(PrSel) NumMain=ChoiceOffset+PrSel EndIf PrSel=0 #■メインメニュー処理 NumMain=Choice(DlgTitle,DlgPromptMain,NumMain,0,DlgListMain) If( (NumMain=0) or (DlgListMain[NumMain] eq "終了") ) Exit ElseIf(DlgListMain[NumMain] eq "無線LAN ON") Run (WifiOnCmd,WifiOnArg) ElseIf(DlgListMain[NumMain] eq "無線LAN OFF") Run (WifiOffCmd,WifiOffArg) ElseIf(DlgListMain[NumMain] eq "オプション設定") OptMenu=1 NumOpt=1 While(OptMenu) #■オプション準備 CallFunction("DlgPromptOpt",DlgPromptOption) Clear(DOPIdx) Clear(DlgListOpt) If(AppDynaLogFix) DOPIdx+=1 DlgListOpt[DOPIdx]="ログ: 動的か後でかを切替" EndIf If(Not NotDynaLogFix) DOPIdx+=1 DlgListOpt[DOPIdx]="ログ: 日時名の有無を切替" DOPIdx+=1 DlgListOpt[DOPIdx]="ログ: 保存先フォルダ変更" EndIf If(FileExists(WifiOffCmd)) DOPIdx+=1 DlgListOpt[DOPIdx]="処理後: WifiOffCmd実行を切替" EndIf DOPIdx+=1 DlgListOpt[DOPIdx]="処理後: 終了するかどうか切替" DOPIdx+=1 DlgListOpt[DOPIdx]="リセット" DOPIdx+=1 DlgListOpt[DOPIdx]="戻る" #■オプション処理 NumOpt=Choice ("Option - "&ThisScrName,DlgPromptOption,NumOpt,0,DlgListOpt) If(DlgListOpt[NumOpt] eq "ログ: 動的か後でかを切替") NotDynaLogFix=(NotDynaLogFix-1)*-1 ElseIf(DlgListOpt[NumOpt] eq "ログ: 日時名の有無を切替") LogTmStampFix=(LogTmStampFix-1)*-1 ElseIf(DlgListOpt[NumOpt] eq "ログ: 保存先フォルダ変更") PreLogDirFix=LogDirFix LogDirFix=SelectDirectory("Log out path - "&ThisScrName,"変更前: "&LogDirFix,LogDirFix) ElseIf(DlgListOpt[NumOpt] eq "処理後: WifiOffCmd実行を切替") AutoWifiOffFix=(AutoWifiOffFix-1)*-1 ElseIf(DlgListOpt[NumOpt] eq "処理後: 終了するかどうか切替") AutoExitOutFix=(AutoExitOutFix-1)*-1 ElseIf(DlgListOpt[NumOpt] eq "リセット") If(Question("設定をリセットしますか?","Reset option? - "&ThisScrName)) Call("OptReset") EndIf Else OptMenu=0 EndIf EndWhile ElseIf (Find(DlgListMain[NumMain],"チェックを全て")) If(Find(DlgListMain[NumMain],"テスト")) AllMode="テスト" ModeSwitch=1 Else AllMode="実行" ModeSwitch=0 EndIf If(Question("チェックを全て "&AllMode&" します^NL^よろしいですか?","Execute all? - "&ThisScrName)) Clear(MaxSetPrNum) Clear(SetPrNum) For i = 1 to MaxProject Step 1 If(Check[i]) MaxSetPrNum+=1 SetPrNum[MaxSetPrNum]=i Test[i]=ModeSwitch EndIf Next Ok=1 EndIf ElseIf (DlgListMain[NumMain] eq "選択反転") PrSel=NumMain-ChoiceOffset For i=1 to MaxProject step 1 Check[i]=(Check[i]-1)*-1 Next ElseIf (DlgListMain[NumMain] eq "選択全て") PrSel=NumMain-ChoiceOffset For i=1 to MaxProject step 1 Check[i]=1 Next ElseIf (DlgListMain[NumMain] eq "選択リセット") PrSel=NumMain-ChoiceOffset For i=1 to MaxProject step 1 Check[i]=PreCheck[i] Next Else #プロジェクトサブメニューのループへ PrSel=NumMain-ChoiceOffset MainMenu=0 SubMenu=1 NumSub=1 EndIf EndWhile While(SubMenu and Not OK) #■プロジェクトサブメニュー準備 Clear(DSBIdx) Clear(DlgListSub) If (Check[PrSel]) DSBIdx=1 DlgListSub[DSBIdx]="チェックをはずす" Else DSBIdx=1 DlgListSub[DSBIdx]="チェックを加える" EndIf DSBIdx+=1 DlgListSub[DSBIdx]="内容の詳細確認" DSBIdx+=1 DlgListSub[DSBIdx]="単体テスト" DSBIdx+=1 DlgListSub[DSBIdx]="単体実行" DSBIdx+=1 DlgListSub[DSBIdx]="戻る" If(SubDirExec[PrSel]=1) PlusSub=" Sub+ " Else PlusSub="" EndIf DlgPromptSub=DlgListMain[NumMain]&"^NL^"&PlusSub&MasterDir[PrSel]&"^NL^To: "&BackupDir[PrSel] #■プロジェクトサブメニュー処理 NumSub=Choice ("Project["&PrSel&"]="""&Project[PrSel]&""" - "&ThisScrName,DlgPromptSub,NumSub,0,DlgListSub) If (Find(DlgListSub[NumSub],"チェックを")) #Check[PrSel]のトグル切り替え Check[PrSel]=(Check[PrSel]-1)*-1 MainMenu=1 SubMenu=0 ElseIf(DlgListSub[NumSub] eq "内容の詳細確認") #配列をプレビューするためのCallFunction CallFunction("PrArrConfer",ReOnlyDir,OnlyDir[PrSel]) CallFunction("PrArrConfer",ReExceptDir,ExceptDir[PrSel]) CallFunction("PrArrConfer",ReOnlyFile,OnlyFile[PrSel]) CallFunction("PrArrConfer",ReExceptFile,ExceptFile[PrSel]) PrPrmPreview="" ForEach FEBox in Array(PrParameters) If(FEBox eq "Project") PrPrmPreview=PrPrmPreview&FEBox&"["&PrSel&"]="""&[FEBox&"["&PrSel&"]"]&"""^NL^^NL^" ElseIf( (FEBox eq "MasterDir") or (FEBox eq "BackupDir") ) PrPrmPreview=PrPrmPreview&FEBox&"["&PrSel&"]="""&[FEBox&"["&PrSel&"]"]&"""^NL^" ElseIf(FEBox eq "Check") PrPrmPreview=PrPrmPreview&FEBox&"["&PrSel&"]="&[FEBox&"["&PrSel&"]"]&"^NL^^NL^" ElseIf( Find(FEBox,"Only") or Find(FEBox,"Except") ) PrPrmPreview=PrPrmPreview&FEBox&"["&PrSel&"]="&["Re"&FEBox]&"^NL^" ElseIf(FEBox eq PrParameters[MaxPrParameters]) PrPrmPreview=PrPrmPreview&FEBox&"["&PrSel&"]="&[FEBox&"["&PrSel&"]"] Else PrPrmPreview=PrPrmPreview&FEBox&"["&PrSel&"]="&[FEBox&"["&PrSel&"]"]&"^NL^" EndIf EndForEach BigMessage(PrPrmPreview,"Detail["&PrSel&"] - "&ThisScrName) ElseIf(Find(DlgListSub[NumSub],"単体")) If(Find(DlgListSub[NumSub],"テスト")) AllMode="テスト" ModeSwitch=1 Else AllMode="実行" ModeSwitch=0 EndIf If(Question("["&PrSel&"]="""&Project[PrSel]&"""^NL^を単体"&AllMode&"します^NL^よろしいですか?","Execute one? - "&ThisScrName)) Clear(SetPrNum) SetPrNum[1]=PrSel Test[PrSel]=ModeSwitch Ok=1 EndIf Else #戻る、キャンセル MainMenu=1 SubMenu=0 EndIf EndWhile EndWhile #■ダイアログ完了、処理スタート #ログファイル保存先準備 Call("LogDirChk") If(LogTmStampFix=1) LogFileName=ThisScrName&"_"&FormatTime("Ymd-His",TimeStamp()) Else LogFileName=ThisScrName&"_log" EndIf LogFilePath=LogDirFix\LogFileName&".txt" #ログ保存先メッセージ If(NotDynaLogFix) Call("StatusMsg","ログ保存予定: "&LogFilePath) Else #ログファイル上書き可能か処理 If(FileAttribute(LogFilePath,"readonly")) If(Question("読み取り専用です。^NL^上書きしますか?^NL^"&LogFilePath,"Error! - "&ThisScrName,"OkCancel")=1) SetFileAttribute(LogFilePath,"readonly",0) Else Exit EndIf EndIf WriteFile(LogFilePath,"",0,"jis") Call("StatusMsg","ログ保存開始: "&LogFilePath) EndIf #ステータスウィンドウ準備 StatusTitle="Status - "&ThisScrName StatusInfo(StatusTitle) StatusType(ST_LIST,1,1) If(NotDynaLog) StatusHSize=0 Else StatusHSize=24 StatusHistorySize(StatusHSize) EndIf #処理全体の開始時間メッセージ TimeTotSta=TimeStamp() Call("StatusMsg","処理スタート: "&FormatTime("Y/m/d H:i:s",TimeTotSta)) #ファイル名時間が重ならないよう、必ず1秒経つためのスリープ Sleep(1000) #▼渡された各PrNumを全部ループ処理(インデント省略中) ForEach PrNum in Array (SetPrNum) #今回の総ファイル数、総容量、削除ディレクトリ数、削除ファイルの数、の表示をリセット AllDirs=0 AllFiles=0 MsFileSize=0 WriDir=0 WriFil=0 MsWriteSize=0 MirDir=0 MirFil=0 PrErr=0 PrSkip=0 Clear(CopyAttMsg) Clear(ScSizeMsg) Clear(WrSizeMsg) #■今回プロジェクト内容表示 TimePrStart=TimeStamp() Call("StatusMsg","") If(Test[PrNum]) TestStatus=" Test" Else TestStatus="" EndIf Call("StatusMsg","●Project["&PrNum&"]="""&Project[PrNum]&""""&TestStatus&" Start "&FormatTime("Y/m/d H:i:s",TimePrStart)) #ディレクトリ指定エラーチェック If(DirExists(MasterDir[PrNum])) MsErrChk="Ok: " Else MsErrChk="Error!: " EndIf Call("StatusMsg",MsErrChk&"MasterDir["&PrNum&"]="""&MasterDir[PrNum]&"""") If(DirExists(BackupDir[PrNum])) BuErrChk="Ok: " Else BuErrChk="Error!: " EndIf Call("StatusMsg",BuErrChk&"BackupDir["&PrNum&"]="""&BackupDir[PrNum]&"""") CallFunction("PrArrConfer",ReOnlyDir,OnlyDir[PrNum]) CallFunction("PrArrConfer",ReExceptDir,ExceptDir[PrNum]) CallFunction("PrArrConfer",ReOnlyFile,OnlyFile[PrNum]) CallFunction("PrArrConfer",ReExceptFile,ExceptFile[PrNum]) i=4 While(i <= MaxPrParameters) If(Find(PrParameters[i],"Only") or Find(PrParameters[i],"Except")) Call("StatusMsg","Pr: "&PrParameters[i]&"["&PrNum&"]="&["Re"&["PrParameters["&i&"]"]]) Else Call("StatusMsg","Pr: "&PrParameters[i]&"["&PrNum&"]="&[["PrParameters["&i&"]"]&"["&PrNum&"]"]) EndIf i+=1 EndWhile #▼今回プロジェクト実行するかどうか(インデント省略中) If(MsErrChk&BuErrChk ne "Ok: Ok: ") w="["&PrNum&"]"&Project[PrNum] If(MsErrChk eq "Error!: ") PrErr+=1 w=w&"^NL^マスターディレクトリが無効です^NL^"&MasterDir[PrNum] EndIf If(BuErrChk eq "Error!: ") PrErr+=1 w=w&"^NL^バックアップディレクトリが無効です^NL^"&BackupDir[PrNum] EndIf w=w&"^NL^続行しますか?" PrErr-=1 Call("ErrorMsg",w) Else #■パラメータ整形 #01系パラメータ一括 ForEach FEBox in values(\ "SubDirExec",\ "SubDirAttr",\ "Mirroring",\ "OWtoTmLess",\ "OWtoTmGreat",\ "OWtoDetail",\ "OWtoTmEqual",\ "RomFileExec",\ "HidFileExec",\ "RomDirExec",\ "HidDirExec",\ "ChkFileSize") Call("PrPrmToBitFix",FEBox) EndForEach #イコール・タイム・レンジ If(Not (EqTimeRange[PrNum] >= 1)) EqTimeRangeFix=0 Else EqTimeRangeFix=EqTimeRange[PrNum] EndIf #コピー削除往復指定 If( (RndCopyDel[PrNum]=2) and MirroringFix) #2かつMirroring有りであれば、初めてDelete先行が意味を持つ。 RndDelete=1 RndCopy=0 ElseIf( (RndCopyDel[PrNum]=1) or Not MirroringFix ) #2も0もMirroring無しならコピーだけでいい、1でMirroring有りなら周回してくれる。 RndDelete=0 RndCopy=1 Else #結果Mirroring有りは絶対なので、RndCopyDel指定が不正であっても同時 RndDelete=1 RndCopy=1 EndIf #容量チェックKB表示 If(ChkFileSizeFix) AppKB=" KB " Else AppKB="" EndIf #クラスタ・サイズ If(Not (ClusterSize[PrNum] >= 1)) ClusterSizeFix=1 Else ClusterSizeFix=ClusterSize[PrNum] EndIf #OnlyExcept[PrNum]のパラメータ中身を出して整形、OnlyExceptFixに("Dir\Parameter","File.prm") #OnlyDirFix[1], ExceptDirFix[1], OnlyFileFix[1], ExceptFileFix[1] ForEach OEDF in Values ("OnlyDir","OnlyFile","ExceptDir","ExceptFile") i=0 Clear([OEDF&"Fix"]) Clear([OEDF&"Max"]) Clear([OEDF&"Parts"]) ForEach FEBox in Array ([OEDF&"["&PrNum&"]"]) #指定パラメータ両端に"\"があればカット If(ReverseFind(FEBox,"\")=Length(FEBox)) FEBox=SubStr(FEBox,1,Length(FEBox)-1) EndIf If(Find(FEBox,"\")=1) FEBox=SubStr(FEBox,2) EndIf #例外(無意味な指定内容)を除いて配列化 If(FEBox ne "") If(FEBox ne "*") i+=1 [OEDF&"Fix["&i&"]"]=FEBox #ディレクトリ分割数を記憶 [OEDF&"Parts["&i&"]"]=0 ForEach FixBox in Split (FEBox,"\",0) [OEDF&"Parts["&i&"]"]+=1 EndForEach EndIf EndIf EndForEach #指定パラメータ数を記憶 [OEDF&"Max"]=i EndForEach #SubDirExecFix無効なら、OnlyDirFix配列をクリアしてサブディレクトリ処理しないように。 If(Not SubDirExecFix) Clear(OnlyDirFix) Clear(OnlyDirMax) Clear(OnlyDirParts) #SubDirExecFix有効かつ、OnlyDirに指定が無かったなら、Fix[1]に"*"を与えて全サブディレを処理対象に。 ElseIf(IsEmpty(OnlyDirFix)) OnlyDirFix[1]="*" OnlyDirMax=1 OnlyDirParts[1]=1 EndIf #OnlyFileに指定が無かったなら、Fix[1]に"*"を与えて全カレントファイルを処理対象に。 If(IsEmpty(OnlyFileFix)) OnlyFileFix[1]="*" OnlyFileMax=1 OnlyFileParts[1]=1 EndIf #両ルートDirとベースDir取得 ("\","R:\","\\NetWork\Root\","\Root\","Base\Base") ForEach FEBox in Values ("MasterRoot","MasterBase","MasterPath","BackupRoot","BackupBase","BackupPath") Clear([FEBox]) EndForEach i=0 ForEach FEBox in Values (MasterDir[PrNum],BackupDir[PrNum]) i+=1 #"\"一文字でなければ、末尾"\"除去 If( (ReverseFind(FEBox,"\")=Length(FEBox)) and (FEBox ne "\")) FEBox=SubStr(FEBox,1,Length(FEBox)-1) EndIf #カレントルート指定 If(FEBox eq "\") CheckRoot=FEBox #PCドライブ絶対指定 ElseIf(Find(FEBox,":")=2) CheckRoot=Part(FEBox,"\",1)&"\" #ネットワーク先 ElseIf(Find(FEBox,"\\")=1) CheckRoot="\\"&Part(FEBox,"\",3)&"\"&Part(FEBox,"\",4)&"\" #カレント(モバイル向け)ディレクトリ指定 ElseIf(Find(FEBox,"\")=1) CheckRoot="\"&Part(FEBox,"\",2)&"\" #ルート指定事態が異常、どうせエラー返される。 Else CheckRoot="" EndIf #ベースDirは、ルートDir文字分を除いた残り部分 CheckBase=SubStr(FEBox,Length(CheckRoot)+1) #Root&Base文字数取得(共通ComDir名取得時に、\をまたぐ文字数の差が出る) If(CheckBase eq "") ChYen="" ChRtBsLet=Length(CheckRoot)+1 Else ChYen="\" ChRtBsLet=Length(CheckRoot)+Length(CheckBase)+2 EndIf If(i=1) MasterRoot=CheckRoot MasterBase=CheckBase MasterPath=MasterRoot&MasterBase MsYen=ChYen MsRtBsLet=ChRtBsLet Else BackupRoot=CheckRoot BackupBase=CheckBase BackupPath=BackupRoot&BackupBase BuYen=ChYen BuRtBsLet=ChRtBsLet EndIf EndForEach #▼コピー削除の往復スイッチング(インデント省略中) デリートターンは指定なければ行われないので単純でいいかも #RndDelete-RndCopy+MirroringFix RndCount=0 While( (RndCount < 2) and Not PrSkip ) If (RndCount=1) If (RndDelete=1) RndDelete=0 RndCopy=1 Else RndDelete=1 RndCopy=0 EndIf EndIf #ミラーリング指定が無い場合、削除ターンは不用なので+1-Mirrorという判定 RndCount = RndCount + RndDelete + RndCopy + 1 - MirroringFix #■マスターパス先頭から実処理 MsExpMem="" BuExpMem="" Clear(MsDirList) MsDirList[1]=MasterPath MDLIdx=1 ChkIdx=0 StsInfoMsg="M"&TestStatus&"["&PrNum&"]="&MasterPath&"^NL^B"&TestStatus&"["&PrNum&"]="&BackupPath&"^NL^\" #▼フォルダ階層全走査完了までループ While ( (ChkIdx < MDLIdx) and Not PrSkip ) #カレント処理ディレクトリ移行 ChkIdx+=1 #共通ディレクトリ取得 ComDir=SubStr(MsDirList[ChkIdx],MsRtBsLet) #最初の一回目はComDirが空なのに末尾\が付いて、フォルダ削除の文字数判定を回避する対処。 If(ChkIdx=1) BuDir=BackupPath Else BuDir=BackupPath\ComDir EndIf LengthBuDir=Length(BuDir) #■ウィンドウに現在のマスターバック両処理パスを表示 StatusInfo(StatusTitle,StsInfoMsg&ComDir) #現在処理スキャン中のディレクトリを表示 Call("StatusMsg"," Scan: \"&ComDir) #■MsOFMemファイル処理 (1個ずつ単位処理) If(RndCopy) #1回目マスターだけはディレクトリ作成や属性トレスをしない。 If(ChkIdx<>1) #フォルダ作成エラー(同名ファイル)判定のリセット MdErr=0 #とりあえず1階層分のフォルダがなければ作成 If(Not Test[PrNum]) Call("MakeDirLoop") #テストの場合よく似た別処理 ElseIf(Not DirExists(BuDir)) If(Not DirExists(BackupPath)) Call("BackupError") #もし作成するフォルダと同名のファイルがあったら ElseIf(FileExists(BuChkDir)) Call("ExpFileMakDir",BuDir) EndIf #エラーが無ければフォルダ作成実行風 Call("NDMakDir",MsDirList[ChkIdx],BuDir) EndIf #既存Dirがあった場合相互属性確認 If(SubDirAttrFix) If(Not NewDirAtt) If(Not MdErr) BuDirReadonly=FileAttribute(BuDir,"readonly") BuDirHidden=FileAttribute(BuDir,"hidden") If (Not (BuDirReadonly and Not RomDirExecFix)\ and Not (BuDirHidden and Not HidDirExecFix) ) ToDAtR=BuDirReadonly ToDAtH=BuDirHidden #マスター側が存在してない場合----でトレスするのを回避 If(DirExists(MsDirList[ChkIdx])) Call("DFAttChk",MsDirList[ChkIdx],BuDir,"Dir") EndIf EndIf EndIf EndIf EndIf EndIf #■マスター側、限定、除外、ファイル捜索 CallFunction("OnlyExceptFil",MsOFMem,MsDirList[ChkIdx]) #エラー、マスター自体が無くなってるので、続けると全ファイル消してしまう If(RndDelete) If(Not DirExists(MasterPath)) Call("MasterError") EndIf EndIf If(Not PrSkip) ForEach MsFile,ExecFile in Array (MsOFMem) #■ファイル処理 #今回のマスターファイルパスと、そのコピー先パス(含ファイル名) BuFile=BuDir\ExecFile #スキャンカウント AllFiles+=1 #ファイル容量取得 If(ChkFileSizeFix) Call("FileSizeChk",MsFile,"MsSizeBytes","FDFileSize") MsFileSize+=FDFileSize EndIf #上書き内容メッセージをリセット Clear(OverWrtMsg) #バックアップファイル既存確認、上書可の条件があればOKフラグ立てる CopyOK=0 #内容重複は高速優先のため(ロジック的にはIf(Not FileExists(BuFile)だけでいい) If(Test[PrNum] and NewDirAtt) CopyOK=1 BuFileTime=0 ReadOnlyChk=0 HiddenChk=0 ElseIf(Not FileExists(BuFile)) CopyOK=1 BuFileTime=0 ReadOnlyChk=0 HiddenChk=0 Else #既存属性チェック (フェイクチェック) CallFunction("ReadOnlyChkFake",ReadOnlyChk,BuFile,"File") CallFunction("HiddenChkFake",HiddenChk,BuFile,"File") If (Not (ReadOnlyChk and Not RomFileExecFix)\ and Not (HiddenChk and Not HidFileExecFix) ) #ファイル更新日時取得 FileModifyTime( ファイル ) MsFileTime=FileModifyTime(MsFile) BuFileTime=FileModifyTime(BuFile) #ファイル時間Notイコールチェック If(Not (( (MsFileTime-BuFileTime) <= EqTimeRangeFix )\ and ( (BuFileTime-MsFileTime) <= EqTimeRangeFix )) ) #上書き時間レスチェック If( MsFileTime > (BuFileTime + EqTimeRangeFix) ) If(OWtoTmLessFix) CopyOK=1 Call("OverWrtMsgFmTm") EndIf #上書き時間グレートチェック ElseIf(OWtoTmGreatFix) CopyOK=1 Call("OverWrtMsgFmTm") EndIf Else #上書き時間イコールチェック If(OWtoTmEqualFix) CopyOK=1 Call("OverWrtMsgFmTm") #上書き詳細チェック ElseIf(OWtoDetailFix) #属性の違いをチェック処理オフなら、ここで正確な調査が必要 If(RomFileExecFix) ReadOnlyChk=(FileAttribute(BuFile,"readonly")) EndIf ToDAtR=ReadOnlyChk If(HidFileExecFix) HiddenChk=(FileAttribute(BuFile,"hidden")) EndIf ToDAtH=HiddenChk Call("DFAttChk",MsFile,BuFile,"File") #属性が同じなら、容量の違いをチェック If(Not CopyOK) If(Not ChkFileSizeFix) Call("FileSizeChk",MsFile,"MsSizeBytes","FDFileSize") EndIf BuSizeBytes=FileSize(BuFile,BYTES) #両方2TB以内 If( (MsSizeBytes < 2147483147) and (BuSizeBytes < 2147483147) ) If(MsSizeBytes <> BuSizeBytes) CopyOK=1 OverWrtMsg=BuSizeBytes-MsSizeBytes If(OverWrtMsg > 0) OverWrtMsg="+"&OverWrtMsg EndIf OverWrtMsg="> "&OverWrtMsg&" Byte" EndIf #両方2TB越え ElseIf( (MsSizeBytes > 2147483146) and (BuSizeBytes > 2147483146) ) Call("FileSizeChk",BuFile,"BuSizeBytes","BuSizeKB") If(FDFileSize <> BuSizeKB)) CopyOK=1 OverWrtMsg="> "&BuSizeKB&" KB" EndIf #片方だけ2TB越え Else Call("FileSizeChk",BuFile,"BuSizeBytes","BuSizeKB") CopyOK=1 OverWrtMsg="> "&BuSizeKB&" KB" EndIf EndIf EndIf EndIf EndIf EndIf #ピーコ実行 (元,先,1=上書き) If (CopyOK and Not MdErr) If(OverWrtMsg eq "") OverWrtMsg="> New" EndIf #テストと内容重複は高速優先のため(元来はElse側でTest判定すればいい) If(Test[PrNum]) Call("StatusMsg"," "&FDFileSize&AppKB&ExecFile&" "&OverWrtMsg) WriFil+=1 If(ChkFileSizeFix) MsWriteSize+=FDFileSize EndIf ElseIf(FileExists(MsFile)) #■ファイル1個単位でディレクトリ確認と作成 Call("MakeDirLoop") #読み取り確実チェック、読み取り属性があれば解除してしまう If(RomFileExecFix) ReadOnlyChk=(FileAttribute(BuFile,"readonly")) EndIf If(ReadOnlyChk) SetFileAttribute(BuFile,"readonly",0) EndIf Call("StatusMsg"," "&FDFileSize&AppKB&ExecFile&" "&OverWrtMsg) WriFil+=1 If(ChkFileSizeFix) MsWriteSize+=FDFileSize EndIf Copy(MsFile,BuFile,1) EndIf EndIf #ディテール比較があった際に数値が入るからクリア、コピーはサブルーチンにした方がいいかも。 If(Not IsEmpty(FDFileSize)) Clear(FDFileSize) EndIf EndForEach #マスター側、限定、除外、ファイル捜索 EndIf EndIf #■バックアップ側ミラー削除 #バックアップフォルダ新規作成してたら飛ばす (削除ターンなので任意に置かれたものを消さないよう緩和) If(NewDirAtt) #既存DirがあればCopy側で1度属性チェックをするので、そのフラグにも使われている NewDirAtt=0 ElseIf ( RndDelete and MirroringFix and Not PrSkip ) #■バックアップ側、限定、除外、ファイル捜索 CallFunction("OnlyExceptFil",DFMem,BuDir) #バックアップ側ミラーファイル削除 If(Not RndCopy) #■マスター側、限定、除外、ファイル捜索 CallFunction("OnlyExceptFil",MsOFMem,MsDirList[ChkIdx]) #エラー、マスター自体が無くなってるので、続けると全ファイル消してしまう If(Not DirExists(MasterPath)) Call("MasterError") EndIf EndIf If(Not PrSkip) ForEach BuFile,ExecFile in Array (DFMem) #マスターに無い (MAP配列は大小文字判定無い) If(IsEmpty(MsOFMem[MsDirList[ChkIdx]\ExecFile])) #ファイルがあって、読み専無効なら削除実行 CallFunction("ReadOnlyChkFake",ReadOnlyChk,BuFile,"File") If(Not( ReadOnlyChk and Not RomFileExecFix )) If(Test[PrNum]) Call("StatusMsg"," [MirRF]: "&ExecFile) MirFil+=1 ElseIf(FileExists(BuFile)) #読み取り属性があれば解除してしまう If(RomFileExecFix) ReadOnlyChk=FileAttribute(BuFile,"readonly") EndIf If (ReadOnlyChk) SetFileAttribute(BuFile,"readonly",0) EndIf Call("StatusMsg"," [MirRF]: "&ExecFile) MirFil+=1 Delete(BuFile) EndIf EndIf EndIf EndForEach EndIf #バック側全フォルダ走査とミラーフォルダ削除 If(SubDirExecFix) If(Not PrSkip) #■バック側、限定、除外、カレント内1階層フォルダ捜索 CallFunction("OnlyExceptDir",DDMem,BuDir,"BuExpMem") #■マスター側、限定、除外、カレント内1階層フォルダ捜索 CallFunction("OnlyExceptDir",MsODMem,MsDirList[ChkIdx],"MsExpMem") #エラー、マスター自体が無くなってるので、続けると全ファイル消してしまう If(Not DirExists(MasterPath)) Call("MasterError") Else #ついでにマスター追加 ScannedMsDir=1 ForEach FEKey,FEBox in Array (MsODMem) MDLIdx+=1 MsDirList[MDLIdx]=FEBox EndForEach MaxMrDirList=0 Clear(MrDirList) ForEach FEKey,FEBox in Array (DDMem) #大文字マスターに無い (読み専Dirでも中のファイルを探るのでリストに加える) If(IsEmpty(MsODMem[MasterPath&MsYen&SubStr(FEKey,BuRtBsLet)])) #ミラーDirリストに追加 MaxMrDirList+=1 MrDirList[MaxMrDirList]=FEBox EndIf EndForEach If(MaxMrDirList) #■バック側カレントDirのミラー対象全サブDir内を各探索 #末端から順繰り用 & 末端ルート辿ったかどうかMem Clear(MirEndMem) MChkIdx=0 While(MChkIdx LengthBuDir)\ and Not Find(MirEndMem,"|"&MEDir&"\")\ and Not Find(MirEndMem&"|","|"&MEDir&"|") ) Call("StatusMsg"," ScanMir: "&MEDir) CallFunction("OnlyExceptFil",DFMem,MEDir) #テストなら末端から順繰り別処理 If(Test[PrNum]) #消せないファイル存在チェック FilEmpChk=1 ForEach FEBox in Files (MEDir\"*") CallFunction("ReadOnlyChkFake",ReadOnlyChk,FEBox,"File") If(Not( ReadOnlyChk and Not RomFileExecFix )) If(Not IsEmpty(DFMem[FEBox])) Call("StatusMsg"," [MirRF]: "&DFMem[FEBox]) MirFil+=1 Else FilEmpChk=0 EndIf Else FilEmpChk=0 EndIf EndForEach #消せないフォルダがあるかどうか If(DirEmpChk) ForEach FEBox in Directories(MEDir\"*") If(DirEmpChk) ToUpperFEBox=ToUpper(FEBox) If(Find(CantDelMem,"|"&ToUpperFEBox&"\")\ or Find(CantDelMem&"|","|"&ToUpperFEBox&"|") ) DirEmpChk=0 ElseIf(Not HidDirExecFix) If (FileAttribute(FEBox,"hidden")) CantDelMem=CantDelMem&"|"&ToUpper(MEDir) DirEmpChk=0 EndIf EndIf EndIf EndForEach EndIf #消せないファイルがあったかどうか If(DirEmpChk) If(Not FilEmpChk) CantDelMem=CantDelMem&"|"&ToUpper(MEDir) DirEmpChk=0 EndIf EndIf #自身が消せるフォルダであるかどうか If(DirEmpChk) If(Not RomDirExecFix) If(FileAttribute(MEDir,"readonly")) CantDelMem=CantDelMem&"|"&ToUpper(MEDir) DirEmpChk=0 EndIf EndIf EndIf #結果自身を消せるかどうか If(DirEmpChk) Call("StatusMsg"," [MirRD]: "&MEDir) MirDir+=1 EndIf #本番なら末端から順繰り削除 Else #ファイル削除 ForEach BuFile,FEBox in Array (DFMem) CallFunction("ReadOnlyChkFake",ReadOnlyChk,BuFile,"File") If(Not( ReadOnlyChk and Not RomFileExecFix )) If(FileExists(BuFile)) #読み取り属性があれば解除してしまう If(RomFileExecFix) ReadOnlyChk=FileAttribute(BuFile,"readonly") EndIf If (ReadOnlyChk) SetFileAttribute(BuFile,"readonly",0) EndIf Delete(BuFile) Call("StatusMsg"," [MirRF]: "&FEBox) MirFil+=1 EndIf EndIf EndForEach #カレントフォルダ削除 CallFunction("ReadOnlyChkFake",ReadOnlyChk,MEDir,"Dir") If(Not( ReadOnlyChk and Not RomDirExecFix )) #読み取り属性があれば解除してしまう If(RomDirExecFix) ReadOnlyChk=FileAttribute(MEDir,"readonly") EndIf If(ReadOnlyChk) SetFileAttribute(BuDir\MEDir,"readonly",0) EndIf RmDir(MEDir) EndIf If(Not DirExists(MEDir)) Call("StatusMsg"," [MirRD]: "&MEDir) MirDir+=1 EndIf EndIf #一個上へ MEDir=SubStr(MEDir,1,ReverseFind(MEDir,"\")-1) EndWhile EndForEach EndIf #マスター存在チェック EndIf #バックアップ側全フォルダ走査とミラーフォルダ削除 EndIf EndIf EndIf #■マスター側次のサブディレクトリ発見追加処理 If(ScannedMsDir) ScannedMsDir=0 ElseIf( SubDirExecFix and Not PrSkip) #■マスター側、限定、除外、フォルダ捜索 CallFunction("OnlyExceptDir",MsODMem,MsDirList[ChkIdx],"MsExpMem") #エラー、マスター自体が無くなってるので、コピー続けるとひたすらスキャンだけが続くのを回避 If(RndDelete) If(Not DirExists(MasterPath)) Call("MasterError") EndIf EndIf If(Not PrSkip) ForEach FEKey,FEBox in Array (MsODMem) MDLIdx+=1 MsDirList[MDLIdx]=FEBox EndForEach EndIf EndIf Clear(MsDirList[ChkIdx]) #▼フォルダ階層全走査完了までループ EndWhile #▼コピー削除の往復スイッチング(インデント省略中) EndWhile #スキャンサブディレクトリ数カウント AllDirs=ChkIdx-1 #▼今回プロジェクト実行するかどうか(インデント省略中) EndIf #PrNumまとめ If(ChkFileSizeFix) ScSizeMsg=" "&MsFileSize&" KB" WrSizeMsg=" "&MsWriteSize&" KB" EndIf TimePrEnd=TimeStamp() Call("StatusMsg","Scaned: "&AllFiles&" Files "&AllDirs&" Folders"&ScSizeMsg) Call("StatusMsg","Writed: "&WriFil&" Files "&WriDir&" Folders"&WrSizeMsg) Call("StatusMsg","Erased: "&MirFil&" MirRF "&MirDir&" MirRD") Call("StatusMsg","Error!: "&PrErr&" Err") Call("StatusMsg","Project["&PrNum&"]="""&Project[PrNum]&""""&TestStatus&" End "&FormatTime("Y/m/d H:i:s",TimePrEnd)) Call("StatusMsg","Project Time +"&(TimePrEnd-TimePrStart)/3600&":"&FormatTime("i:s",TimePrEnd-TimePrStart)) #▼渡された各PrNumを全部ループ処理(インデント省略中) EndForEach #トータル実行まとめ StatusInfo(StatusTitle) TimeTotEnd=TimeStamp() Call("StatusMsg","") Call("StatusMsg","処理エンド: "&FormatTime("Y/m/d H:i:s",TimeTotEnd)) Call("StatusMsg","Total Time +"&(TimeTotEnd-TimeTotSta)/3600&":"&FormatTime("i:s",TimeTotEnd-TimeTotSta)) Call("LogOutEnd") #▼全処理完了後ダイアログに戻る(インデント省略中) If(AutoExitOutFix) Exit EndIf #ログ非表示 StatusType(ST_HIDDEN) StatusHistorySize(0) StatusClear() EndWhile #--------------------------------------------------------------- #Sub Script #■Call("AryAllPrPrm") 全プロジェクトパラメータ配列化とMax数 Sub AryAllPrPrm PrParameters=Array(\ "Project",\ "MasterDir",\ "BackupDir",\ "Check",\ "SubDirExec",\ "SubDirAttr",\ "Mirroring",\ "OWtoTmLess",\ "OWtoTmGreat",\ "OWtoDetail",\ "OWtoTmEqual",\ "EqTimeRange",\ "RomFileExec",\ "HidFileExec",\ "RomDirExec",\ "HidDirExec",\ "OnlyFile",\ "ExceptFile",\ "OnlyDir",\ "ExceptDir",\ "RndCopyDel",\ "ErrMsgSkip",\ "ChkFileSize",\ "ClusterSize") #手打ちMaxIndex(PrParameters) MaxPrParameters=24 EndSub #■Call("WinCEIdleEsc") モバイルデバイスの自動スリープ回避 Sub WinCEIdleEsc If(MobileDevice) IdleTimerReset EndIf EndSub #■Call("StatusMsg","ここにステータス表示メッセージ") Sub StatusMsg #Call("WinCEIdleEsc") If(NotDynaLog) StatusHSize+=1 StatusHistorySize(StatusHSize) EndIf StatusMessage(argv[1]) If(Not NotDynaLogFix) WriteFile(LogFilePath,argv[1]&"^NL^",1,"jis") EndIf EndSub #■Call("ErrorMsg","ここにエラー表示メッセージ") Sub ErrorMsg PrErr+=1 If(Not ErrMsgSkipFix) If(Question(argv[1],"Error! - "&ThisScrName,"OkCancel")=2) #任意操作なのでWifiOffを避ける AutoWifiOffFix=0 #ログ出力完了して表示、終了 Call("LogOutEnd") Exit EndIf EndIf EndSub #■Call("MasterError") Sub MasterError PrSkip=1 Call("StatusMsg"," Error!: [MasterDir]: "&MasterPath) Call("ErrorMsg","マスターフォルダ切断によりスキップしました。^NL^次プロジェクト移行しますか?^NL^"&MasterPath) EndSub #■Call("BackupError") Sub BackupError PrSkip=1 MdErr=1 Call("StatusMsg"," Error!: [BackupDir]: "&BackupPath) Call("ErrorMsg","バックアップフォルダ切断によりスキップしました。^NL^次プロジェクト移行しますか?^NL^"&BackupPath) EndSub #■CallFunction("OnlyExceptFil",OFMem受け変数,"ここにOnlyExceptFilをスキャンするディレクトリ") Sub OnlyExceptFil LengthScanDir=Length(argv[1]) LengthScanDir+=(LengthScanDir<>ReverseFind(argv[1],"\"))+1 ForEach FixBox in Array (ExceptFileFix) ForEach PathBox in Files (argv[1]\FixBox) FMem[PathBox]=1 EndForEach EndForEach If(HidFileExecFix) ForEach FixBox in Array (OnlyFileFix) ForEach PathBox in Files (argv[1]\FixBox) If(IsEmpty(FMem[PathBox])) OFMem[PathBox]=SubStr(PathBox,LengthScanDir) EndIf EndForEach EndForEach Else ForEach FixBox in Array (OnlyFileFix) ForEach PathBox in Files (argv[1]\FixBox) If(IsEmpty(FMem[PathBox])) If(Not FileAttribute(PathBox,"hidden")) OFMem[PathBox]=SubStr(PathBox,LengthScanDir) EndIf EndIf EndForEach EndForEach EndIf Return(OFMem) Clear(OFMem) Clear(FMem) If(MobileDevice) IdleTimerReset EndIf EndSub #■CallFunction("OnlyExceptDir",ODMem受け変数,"ここにOnlyExceptDirをスキャンするディレクトリ","除外リストMem名文字列") Sub OnlyExceptDir ForEach FixKey,FixBox in Array (ExceptDirFix) Clear(Nominate) Nominate[argv[1]]=1 DirParts=0 ForEach FixPart in Split (FixBox,"\",0) DirParts+=1 If(DirParts < ExceptDirParts[FixKey]) ForEach NomKey,NomBox in Array (Nominate) ForEach FoundBox in Directories (NomKey\FixPart) NomFound[FoundBox]=1 EndForEach EndForEach Nominate=NomFound Clear(NomFound) Else #除外リストMem更新 ForEach NomKey,NomBox in Array (Nominate) ForEach FoundBox in Directories (NomKey\FixPart) [argv[2]&"["""&FoundBox&"""]"]=1 EndForEach EndForEach EndIf EndForEach EndForEach If(MobileDevice) IdleTimerReset EndIf ForEach FixKey,FixBox in Array (OnlyDirFix) Clear(Nominate) Nominate[argv[1]]=argv[1] DirParts=0 ForEach FixPart in Split (FixBox,"\",0) DirParts+=1 If(DirParts < OnlyDirParts[FixKey]) ForEach NomKey,NomBox in Array (Nominate) ForEach FoundBox in Directories (NomBox\FixPart) NomFound[FoundBox]=FoundBox EndForEach EndForEach Nominate=NomFound Clear(NomFound) ElseIf(HidDirExecFix) ForEach NomKey,NomBox in Array (Nominate) ForEach FoundBox in Directories (NomBox\FixPart) If(Not [argv[2]&"["""&FoundBox&"""]"]) ODMem[FoundBox]=FoundBox EndIf EndForEach EndForEach Else ForEach NomKey,NomBox in Array (Nominate) ForEach FoundBox in Directories (NomBox\FixPart) If(Not [argv[2]&"["""&FoundBox&"""]"]) If(Not FileAttribute(FoundBox,"hidden")) ODMem[FoundBox]=FoundBox EndIf EndIf EndForEach EndForEach EndIf EndForEach EndForEach Return(ODMem) Clear(ODMem) If(MobileDevice) IdleTimerReset EndIf EndSub #■Call("MemCutSplit","検索対象Mem変数名を文字列指定",取り除く文字列) Sub MemCutSplit #"|あ|い|う|"→"| い|う|" "|あ | う|" "|あ|い |" #"|あ|い|" →"| い|" "|あ |" #"|あ|" →"|" [argv[1]]=Replace([argv[1]]&"|","|"&argv[2]&"|","|") #末尾"|"を除いて格納 If([argv[1]] ne "|") [argv[1]]=SubStr([argv[1]],1,Length([argv[1]])-1) Else [argv[1]]="" EndIf EndSub #■Call("OptReset") メインオプションのリセット Sub OptReset #メインオプション整形 ForEach argBox in Array(MnParameters) Call("MnPrmToBitFix",argBox) EndForEach NotDynaLogFix=NotDynaLog PreLogDirFix="" LogDirFix=LogDirectory EndSub #■Call("LogDirChk") LogDirFixの有効をチェック Sub LogDirChk If( Not DirExists(LogDirFix) or (LogDirFix eq "") ) If( Not DirExists(PreLogDirFix) or (PreLogDirFix eq "") ) LogDirFix=SystemPath("ScriptPath") LogDirFix=Replace(LogDirFix,"\\\\","\\") Else LogDirFix=PreLogDirFix EndIf EndIf EndSub #■CallFunction("DlgPromptOpt",戻り値を受け取る変数) ダイアログ表示プロンプト Sub DlgPromptOpt #ダイアログプロンプト ログ保存: 動的 日時付き C:\Project Call("LogDirChk") If(AppDynaLogFix) If(NotDynaLogFix) wDynaLog=" 後で確認" Else wDynaLog=" 動的" EndIf Else wDynaLog="" EndIf If(Not NotDynaLogFix) If(LogTmStampFix) wLogTm=" 日時付き "&LogDirFix Else wLogTm=" "&LogDirFix EndIf Else wLogTm="" EndIf #実行後: Wifi切断 mscr終了 If( AutoWifiOffFix and FileExists(WifiOffCmd) ) wWifi=" WifiOff" Else wWifi="" EndIf If(AutoExitOutFix) wExit=" 終了" Else wExit=" メニューへ" EndIf Return("ログ保存:"&wDynaLog&wLogTm&"^NL^処理後:"&wWifi&wExit) EndSub #■Call("MnPrmToBitFix","ここに01化したいメインパラメータ名を文字指定") Sub MnPrmToBitFix If([argv[1]]<>1) [argv[1]&"Fix"]=0 Else [argv[1]&"Fix"]=1 EndIf EndSub #■Call("PrPrmToBitFix","ここに01化したいプロジェクトパラメータ名を文字指定") Sub PrPrmToBitFix If([argv[1]&"["&PrNum&"]"]<>1) [argv[1]&"Fix"]=0 Else [argv[1]&"Fix"]=1 EndIf EndSub #■CallFunction("PrArrConfer",戻り値を受け取る変数,プレビュー処理する配列) Sub PrArrConfer w="" ForEach argBox in Array (argv[argc]) w=w&""""&argBox&"""," EndForEach Return("Array("&SubStr(w,1,Length(w)-1)&")") EndSub #■Call("MakeDirLoop") Sub MakeDirLoop #一気にパス先のフォルダが作れないので、存在しない階層を辿るループ MsChkDir=MsDirList[ChkIdx] BuChkDir=BuDir BuMakDir="" BuDirExs=0 While(Not BuDirExs and Not MdErr) #チェックディレクトリ無いか有るか If(Not DirExists(BuChkDir)) #チェックするフォルダの階層を一個繰り上げる(BuRtBsLetは+1文字されてる) If(Length(BuChkDir) >= BuRtBsLet) BuMakDir=SubStr(BuChkDir,ReverseFind(BuChkDir,"\"))&BuMakDir #"\"一文字まで遡れるケースを考慮 ForEach MBDirBox in Values ("MsChkDir","BuChkDir") i=ReverseFind([MBDirBox],"\") If(i=1) [MBDirBox]="" Else [MBDirBox]=SubStr([MBDirBox],1,i-1) EndIf EndForEach #大元のバックアップ指定先まで登っても、無いので終了 Else Call("BackupError") EndIf #存在確認Dirが目的のDirなら達成フラグ立てて抜ける ElseIf( Length(BuChkDir) >= LengthBuDir ) BuDirExs=1 #目的以前で存在する階層まで来てたらチェック移行してフォルダ作成する。 Else BuChkDir=BuChkDir&"\"&Part(BuMakDir,"\",2,0) MsChkDir=MsChkDir&"\"&Part(BuMakDir,"\",2,0) BuMakDir=SubStr(BuMakDir,Length(Part(BuMakDir,"\",2,0))+2) #もし作成するフォルダと同名のファイルがあったら If(FileExists(BuChkDir)) Call("ExpFileMakDir",BuChkDir) EndIf #エラーが無ければフォルダ作成実行 Call("NDMakDir",MsChkDir,BuChkDir) EndIf EndWhile EndSub #■Call("ExpFileMakDir","ここに作成試行フォルダと既存ファイルの同名パス") Sub ExpFileMakDir CallFunction("ReadOnlyChkFake",ReadOnlyArg,argv[1],"File") If(Not HidDirExecFix) HiddenArg=FileAttribute(argv[1],"hidden") Else HiddenArg=0 EndIf If (Not (ReadOnlyArg and Not RomFileExecFix)\ and Not (HiddenArg and Not HidDirExecFix) ) Call("StatusMsg"," [MirRF]: "&argv[1]) MirFil+=1 If(Not Test[PrNum]) If(RomFileExecFix) ReadOnlyArg=FileAttribute(argv[1],"readonly") EndIf If(ReadOnlyArg) SetFileAttribute(argv[1],"readonly",0) EndIf Delete(argv[1]) EndIf Else MdErr=1 Call("StatusMsg"," Error!: [RF][MD]: "&argv[1]) Call("ErrorMsg","既存ファイルと同名のフォルダ作成をスキップしました。^NL^続行しますか?^NL^"&argv[1]) EndIf EndSub #■Call("NDMakDir","属性コピー元マスターパス","ここに新規作成するフォルダパス") Sub NDMakDir If(Not MdErr) #目的Dirの新規作成が完了していたら、既存属性を飛ばす為のチェック If( (BuMakDir eq "") or Test[PrNum] ) NewDirAtt=1 EndIf WriDir+=1 If(Not Test[PrNum]) MkDir(argv[2]) EndIf #マスター側のフォルダ属性をバック側にトレース #(新規フォルダなので読み隠し考慮無用) #万が一MsDir存在してない場合、"----"取得になるので構わない If(SubDirAttrFix) Call("NDAttChk",argv[1],argv[2]) endif Call("StatusMsg"," [MD]: "&CopyAttMsg&argv[2]) EndIf EndSub #■Call("NDAttChk",属性トレース元Dir,属性トレース先Dir) 新規フォルダ作成直後に行う属性比較 Sub NDAttChk RdDAtS=FileAttribute(argv[1],"system") RdDAtR=FileAttribute(argv[1],"readonly") RdDAtH=FileAttribute(argv[1],"hidden") RdDAtA=FileAttribute(argv[1],"archive") If(RdDAtS or RdDAtR or RdDAtH or RdDAtA) CopyAttMsg=SubStr("-S",RdDAtS+1,1)\ &SubStr("-R",RdDAtR+1,1)\ &SubStr("-H",RdDAtH+1,1)\ &SubStr("-A",RdDAtA+1,1)\ &" > " If(Not Test[PrNum]) If(RdDAtS) SetFileAttribute(argv[2],"system",RdDAtS) EndIf If( RdDAtR or RdDAtH or RdDAtA ) SetFileAttribs(argv[2],RdDAtR,RdDAtH,RdDAtA) EndIf EndIf Else CopyAttMsg="---- > " EndIf EndSub #■Call("DFAttChk",属性トレース元DF,属性トレース先DF,"Dir or File を文字指定") Sub DFAttChk If(IsEmpty(ToDAtR)) ToDAtR=FileAttribute(argv[2],"readonly") EndIf If(IsEmpty(ToDAtH)) ToDAtH=FileAttribute(argv[2],"hidden") EndIf ToDAtS=FileAttribute(argv[2],"system") ToDAtA=FileAttribute(argv[2],"archive") RdDAtS=FileAttribute(argv[1],"system") RdDAtR=FileAttribute(argv[1],"readonly") RdDAtH=FileAttribute(argv[1],"hidden") RdDAtA=FileAttribute(argv[1],"archive") #何か属性が違うのなら(ForEach回すより打った方が速そう) If( (RdDAtS<>ToDAtS) or (RdDAtR<>ToDAtR) or (RdDAtH<>ToDAtH) or (RdDAtA<>ToDAtA) ) OverWrtMsg=SubStr("-S",RdDAtS+1,1)\ &SubStr("-R",RdDAtR+1,1)\ &SubStr("-H",RdDAtH+1,1)\ &SubStr("-A",RdDAtA+1,1)\ &" > "\ &SubStr("-S",ToDAtS+1,1)\ &SubStr("-R",ToDAtR+1,1)\ &SubStr("-H",ToDAtH+1,1)\ &SubStr("-A",ToDAtA+1,1) If(argv[3] eq "File") CopyOK=1 Else Call("StatusMsg"," [Atrib]: "&OverWrtMsg) WriDir+=1 If(Not Test[PrNum]) If(RdDAtS<>ToDAtS) SetFileAttribute(argv[2],"system",RdDAtS) EndIf If( (RdDAtR<>ToDAtR) or (RdDAtH<>ToDAtH) or (RdDAtA<>ToDAtA) ) SetFileAttribs(argv[2],RdDAtR,RdDAtH,RdDAtA) EndIf EndIf EndIf EndIf Clear(ToDAtR) Clear(ToDAtH) EndSub #■Call("FileSizeChk","ファイルパス","返すBytes変数名を文字で","返すKB変数名を文字で") Sub FileSizeChk #ファイル容量取得 (下桁0KBファイルのときにクラスタKBが余計に加算しないように区別) [argv[2]]=FileSize(argv[1],BYTES) If([argv[2]]) [argv[3]]=FileSize(argv[1],KB) / ClusterSizeFix * ClusterSizeFix #クラスタKB以下の容量があれば1クラスタ追加。(但し2GB(足らず2147483147)越えなら判定不能) If([argv[2]] mod (ClusterSizeFix*1024)) [argv[3]]+=ClusterSizeFix EndIf Else [argv[3]]=0 EndIf EndSub #■Call("LogOutEnd") ログ出力して、Wifi止めて、Message表示 Sub LogOutEnd #ステータスメッセージ中断不能可 StatusType(ST_LIST,0,0) StatusShow() #ログ最後一括なら If(NotDynaLogFix) #自動WifiOff If(AutoWifiOffFix and FileExists(WifiOffCmd)) Run(WifiOffCmd,WifiOffArg) EndIf NextStep=0 While(Not NextStep) Call("LogDirChk") LogFilePath=LogDirFix\LogFileName&".txt" LogOutType=(Question("ログを保存しますか?","Log out? - "&ThisScrName,"YesNo")) If(LogOutType) LogFilePath=SelectFile("Save Log - "&ThisScrName,1,"*.txt","ログファイル(txt)",LogFilePath) If(FileAttribute(LogFilePath,"readonly")) If(Question("読み取り専用です^NL^上書きしますか?^NL^"&LogFilePath,"Error! - "&ThisScrName,"OkCancel")=1) SetFileAttribute(LogFilePath,"readonly",0) Else LogFilePath="" EndIf EndIf If(LogFilePath ne "") Call("StatusMsg","ログ保存処理: "&LogFilePath) TimeLogSta=TimeStamp() ShowWaitCursor WriteStatusHistory(LogFilePath,0,"jis") HideWaitCursor NextStep=1 EndIf Else Call("StatusMsg","ログ保存無効: ") NextStep=1 EndIf EndWhile #ログ逐次平行なら Else LogOutType=1 Call("StatusMsg","ログ保存完了: "&LogFilePath) #自動WifiOff If(AutoWifiOffFix and FileExists(WifiOffCmd)) Run(WifiOffCmd,WifiOffArg) EndIf EndIf #ログメッセージ表示 If(LogOutType) LogMsg="ログ保存完了: " If(NotDynaLogFix) TimeLogEnd=TimeStamp() LogMsg=LogMsg&"Log out time +"&(TimeLogEnd-TimeLogSta)/3600&":"&FormatTime("i:s",TimeLogEnd-TimeLogSta)&"^NL^" WriteFile(LogFilePath,LogMsg,1,"jis") EndIf LogMsg=LogMsg&LogFilePath message(LogMsg,"Log - "&ThisScrName) EndIf EndSub #■Call("OverWrtMsgFmTm") 時間差上書きメッセージ作成 Sub OverWrtMsgFmTm OverWrtMsg=FormatTime("Y/m/d H:i:s",MsFileTime)&" > "&FormatTime("Y/m/d H:i:s",BuFileTime) EndSub #■CallFunction("ReadOnlyChkFake",戻り変数名,読み取り仮調査対象,"DirかFileか文字列で") Sub ReadOnlyChkFake If(["Rom"&argv[2]&"ExecFix"]) Bit=0 Else Bit=FileAttribute(argv[1],"readonly") EndIf Return(Bit) EndSub #■CallFunction("HiddenChkFake",戻り変数名,読み取り仮調査対象,"DirかFileか文字列で") Sub HiddenChkFake If(["Hid"&argv[2]&"ExecFix"]) Bit=0 Else Bit=FileAttribute(argv[1],"hidden") EndIf Return(Bit) EndSub