本日のサンプルは、ロックが成功するまで適当に待ち時間を挟みながら繰り返しトライして、ロックできたら編集を実行します。
以下ソース
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<title>lock</title> | |
<body style="text-align:center;overflow:hidden"> | |
<input id=inp style="width:100%;text-align:center"> | |
<button id=btnL>load</button> | |
<button id=btnI>init</button> | |
<table border=1 style="width:100%;"> | |
<tr><td width=1>A</td><td><input id=inpA style="width:100%"></td></tr> | |
<tr><td width=1>B</td><td><input id=inpB style="width:100%"></td></tr> | |
<tr><td width=1>C</td><td><input id=inpC style="width:100%"></td></tr> | |
</table> | |
</body> | |
<script> | |
resizeTo(200,200) | |
fso=function(){ | |
var fs=new ActiveXObject('Scripting.FileSystemObject') | |
return { | |
AXO:fs, | |
gsf2:fs.GetSpecialFolder(2), // Z:\TEMP | |
Read:function(path, swCreate, swUnicode){ | |
if(!fs.FileExists(path)){return} | |
with(fs.OpenTextFile(path, 1, swCreate, swUnicode)){ var str=AtEndOfStream ? '' : ReadAll(); Close() } | |
return str | |
}, | |
Write:function(path,str,swUnicode,sw上書きしない){ with(fs.CreateTextFile(path, !sw上書きしない, swUnicode)){ Write(str); Close() } }, | |
Lock:function(path){ | |
var pathL=path+'.lock', ws, wsn=new ActiveXObject('WScript.Network') | |
try{ | |
ws=fs.CreateTextFile(pathL) | |
ws.Write(wsn.computerName+'\r\n'+wsn.userName) | |
return {Close:function(){ ws.Close(); fs.DeleteFile(pathL) }} | |
} | |
catch(e){ | |
return this.Read(pathL) | |
} | |
} | |
} | |
}() | |
inp.value = fso.gsf2+'\\lockTest.txt' | |
onbeforeunload=function(){ fso.AXO.FileExists(inp.value) && fso.AXO.DeleteFile(inp.value) } | |
obj = null | |
btnL.onclick=function(){ | |
var path=inp.value, o | |
if(!fso.AXO.FileExists(path)){return alert('ファイルがありません')} | |
try{ eval('o = '+fso.Read(path)) } | |
catch(e){ return alert('ファイルが破損しています') } | |
obj = o | |
inpA.value = o.A | |
inpB.value = o.B | |
inpC.value = o.C | |
} | |
btnI.onclick=function(){ | |
wsf.negoWrite(inp.value, function(path){ Write(path, "{A:'', B:'', C:''}") }) | |
} | |
onload=function(){ | |
btnI.onclick() | |
} | |
inpA.onchange=inpB.onchange=inpC.onchange=function(){ | |
wsf.negoWrite(inp.value, (''+function(path){ | |
eval('o = '+Read(path)) | |
o.prop = 'VVV' | |
Write(path, "{A:'"+o.A.replace(/'/g,"\'")+"', B:'"+o.B.replace(/'/g,"\'")+"', C:'"+o.C.replace(/'/g,"\'")+"'}") | |
}).replace(/prop/,this.id.charAt(3)).replace(/VVV/,this.value.replace(/'/g,"\'"))) | |
} | |
wsf=function(){ | |
var pathWSF=fso.gsf2+'\\lock.wsf' | |
fso.Write(pathWSF, (''+function(){/* | |
<-job> | |
<-script> | |
arg = WScript.Arguments | |
path = arg(0) | |
pathF = arg(1) | |
pathL = path+'.lock' | |
AXO = function(name){return new ActiveXObject(name)} | |
fs = AXO('Scripting.FileSystemObject') | |
wsn = AXO('WScript.Network') | |
Read = function(path){with(fs.OpenTextFile(path)){ var str=AtEndOfStream ? '' : ReadAll(); Close() } return str} | |
Write= function(path,str){ with(fs.CreateTextFile(path)){ Write(str); Close() } }, | |
eval('f = '+Read(pathF)) | |
while(true){ | |
try{ | |
lock = fs.CreateTextFile(pathL) | |
lock.Write(wsn.computerName+'\r\n'+wsn.userName) | |
break | |
} | |
catch(e){ WScript.Sleep(1000 * 10 * Math.random()) } // 待ち時間が一定だと永遠にお見合い状態になってしまうので、ばらけさせる。 | |
} | |
f(path) | |
// このスクリプトの動作を分かり易くするための待機時間。実際は不要。 | |
WScript.Sleep(5000) | |
lock.Close() | |
try{ | |
fs.DeleteFile(pathL) | |
fs.DeleteFile(pathF) | |
}catch(e){} | |
<-/script> | |
<-/job> | |
*/}).split('/*')[1].split('*/')[0].replace(/<-/g,'<')) | |
var shell=new ActiveXObject('WScript.Shell') | |
var pathDQ=function(path){return 0<path.indexOf(' ') ? ('"'+path+'"') : path } | |
return { | |
negoWrite:function(path, fun){ | |
var pathF=fso.gsf2+'\\fun'+(new Date()).getTime()+'.js' | |
fso.Write(pathF, fun) | |
shell.run('cmd /C cscript '+pathDQ(pathWSF)+' '+pathDQ(path)+' '+pathDQ(pathF), 0) | |
} | |
} | |
}() | |
</script> | |
</html> |
実行画面

inputエリア内に文字を入力して、

inputエリアからフォーカスを移動しonchangeイベントを発生させるとロックを繰り返しトライするためのwsfファイルが作成されます。

プログラムを一つだけ起動している場合、ファイルへのアクセスが競合することはないのでwsfファイルはすぐにロック成功して自身を削除しますが、プログラムを複数個起動して数秒以内にそれぞれのinputボックスでonchangeイベントを発生させると


onchangeイベントを発生させた数に応じて一時的なスクリプトファイルが作成されて

ロックが成功して処理終了したものから順次削除されていき、最終的には対象のファイルの中身は以下のようになります。

0 件のコメント:
コメントを投稿