      1 ﻿
      2 /**
      3  * @name	CeL function for Windows job
      4  * @fileoverview
      5  * 本檔案包含了 Windows job 的 functions。
      6  * @since
      7  */
      8
      9 if (typeof CeL === 'function'){
     10
     11 /**
     12  * 本 module 之 name(id)，<span style="text-decoration:line-through;">不設定時會從呼叫時之 path 取得</span>。
     13  * @type	String
     14  * @constant
     15  * @inner
     16  * @ignore
     17  */
     18 var module_name = 'OS.Windows.job';
     19
     20 //===================================================
     21 /**
     22  * 若欲 include 整個 module 時，需囊括之 code。
     23  * @type	Function
     24  * @param	{Function} library_namespace	namespace of library
     25  * @param	load_arguments	呼叫時之 argument(s)
     26  * @return
     27  * @name	CeL.OS.Windows.job
     28  * @constant
     29  * @inner
     30  * @ignore
     31  */
     32 var code_for_including = function(library_namespace, load_arguments) {
     33
     34 //	requires
     35 if (eval(library_namespace.use_function(
     36 		'code.compatibility.is_DOM')))
     37 	return;
     38
     39
     40 /**
     41  * null module constructor
     42  * @class	Windows job 的 functions
     43  */
     44 CeL.OS.Windows.job
     45 = function() {
     46 	//	null module constructor
     47 };
     48
     49 /**
     50  * for JSDT: 有 prototype 才會將之當作 Class
     51  */
     52 CeL.OS.Windows.job
     53 .prototype = {
     54 };
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68 //	有關安裝的部分
     69 function install(dir){//move files: input base dir
     70  var f,d,i=0,s=0,c=0,l=getResource("filelist").split(/[\r\n]+/);//.replace(/[\r\n]+/g,"\n").split('\n')
     71  for(;i<l.length;i++)if(l[i]&&l[i].charAt(0)!='#'&&(f=l[i].split('\t'))){
     72   d=turnToPath(f[1]),f=f[0],d=d?isFolder(d)?(isFolder(d)==2?dir:'')+d+f:d:dir+f;
     73   if(f)if(c++,d=mv(f,d))pErr(d);else s++;
     74   else if(d)pLog('フォルダ '+d+' の作成を'+(isFolder(d,1)?'成功':'失敗')+'した');
     75  }
     76  if(c)pLog(s+"/"+c+"filesの移動に成功した");
     77 }
     78
     79 function rmProg(){
     80  if(typeof getResource=='undefined')return;
     81  var i=0,f,l=getResource("proglist").split(/\r\n/);//.replace(/[\r\n]+/g,"\n").split('\n')
     82  for(;i<l.length;i++)if(l[i]&&(f=l[i].split('\t')[0]))try{fso.DeleteFile(f);}catch(e){}
     83 }
     84
     85
     86 //	先決條件測試@.js主檔，當沒問題時return 0。此函數若使用到function.js之(其他)功能需include入！
     87 //	include:getScriptName(),mergeScript()
     88 function preCheck(argumentCount,ver,mFN){	//	argument數,最低版本,若ver<5.1時合併檔名
     89  var SN=getScriptName(),WshShell=WScript.CreateObject("WScript.Shell");
     90  if(!argumentCount)argumentCount=0;
     91
     92  if(!WScript.Interactive){
     93   WshShell.Popup('This program must run in interactive mode!\n此程式需執行於互動模式！',0,SN,48);
     94   return 5;
     95  }
     96  if(WScript.Arguments.length>argumentCount){
     97   if(typeof WScript.Arguments.ShowUsage=='unknown'||WScript.Arguments.ShowUsage)WScript.Arguments.ShowUsage();
     98   else WshShell.Popup('Error arguments!\n引數錯誤！',0,SN,16);
     99   return 6;
    100  }//else if(2==WshShell.Popup("此程式應用於帳目處理。",0,"確定執行？",1+64))return 4;
    101  //	以上可置於.wsf中。
    102
    103  if(!ver||ver<5)ver=5;if(!mFN)mFN='process';
    104  if(typeof checkVer=='function')checkVer(ver);	//	5.1起才能用.wsf(windows script file)控制
    105  else if(WScript.Version>5){WshShell.Popup('請執行 '+SN+'.wsf 檔！',0,SN+': 不是執行這個檔喔！',48);return 7;}
    106  else if(mergeScript(mFN+'.js')){WshShell.Popup('合併檔案失敗！',0,SN,16);return 8;}
    107  else{
    108   try{fso.CopyFile(SN+'.ini',mFN+'.ini');}catch(e){}	//	copy .ini
    109   WshShell.Popup('請設定好 '+mFN+'.ini，\n之後您可試試 '+mFN+'.js 檔，但並不一定能順利執行。',0,SN+': 使用的版本過舊！',48);return 9;
    110  }
    111
    112  return 0;
    113 }
    114
    115
    116
    117 /*	2009/6/18 20:46:1
    118 	更新功能 update function
    119
    120 可以嘗試將 for_check 合在 install_url 中。
    121
    122 */
    123
    124 Update[generateCode.dLK]='getU,getFN,simpleWrite';	//	,Debug_for_include,gDate
    125
    126 function Update(for_check, install_url) {
    127 	return Update.check(Update.setup(for_check, install_url));
    128 }
    129
    130 //	base function
    131
    132 Update.check=function(force){
    133  if(!this.URL)return;
    134
    135  if(force||!this.version){
    136   var d=this.parse(getU(this.URL)||'');
    137   this.version_get=d;
    138   //sl('Update.check: version get: ['+this.version_get+']');
    139  }
    140  return this.version=[this.version_get,this.version_now,this.URL];
    141 };
    142
    143 Update.set_URL=function(for_check,install_url){
    144  var unchang=1;
    145  if(for_check){
    146   if(unchang)
    147    unchang= this.URL==for_check;
    148
    149   //sl('Update.set_URL: 設定檢測 URL: <a href="'+for_check+'">'+for_check+'</a>');
    150   this.URL=for_check;
    151  }
    152  if(install_url){
    153   if(unchang)
    154    unchang= this.download_URL==install_url;
    155
    156   //sl('Update.set_URL: 設定程式下載 URL: <a href="'+install_url+'">'+install_url+'</a>');
    157   this.download_URL=install_url;
    158  }
    159  return !unchang;
    160 };
    161
    162 /*
    163 TODO:
    164 date 相同時比較大小
    165 */
    166 Update.up_to_date=function(){
    167  return 0>=this.compare(this.version_now,this.version_get);
    168 };
    169
    170 Update.install=function(){
    171  var p=getFN(decodeURI(location.pathname)),t=p+'.new',b=p+'.old',f=this.after_install;
    172  //sl('Update.install: program path: ['+p+']');
    173  if(this.download(t)){
    174   try{fso.DeleteFile(b);}catch(e){}
    175   try{
    176    fso.MoveFile(p,b);
    177    fso.MoveFile(t,p);
    178   }catch(e){f&&f(e,p,t);return;}
    179   f&&f();
    180   return 1;
    181  }
    182 };
    183
    184 Update.check_string='check_string';
    185 Update.download=function(to_where){
    186  //sl('Update.download: download [<a href="'+this.download_URL+'">'+this.download_URL+'</a>] to ['+to_where+']');
    187  var data=getU(this.download_URL),f=this.after_download;
    188  if(data&&(!this.check_string||data.indexOf(this.check_string)!=-1)){
    189   simpleWrite(to_where,data,TristateTrue);
    190   f&&f(0,data);
    191   return data;
    192  }else f&&f(1,data);
    193 };
    194
    195
    196 //	default user function
    197 Update.setup=function(for_check,install_url){
    198  var v=document.getElementById('version');
    199  if(v)v=v.innerHTML.replace(/[\s\n]+$|^[\s\n]+/g,'');
    200  this.version_now=new Date(v||document.lastModified);
    201  //sl('Update.setup: version now: ['+this.version_now+']');
    202
    203  return this.set_URL(for_check,install_url);
    204 };
    205
    206 Update.parse=function(version_data){
    207  return new Date(version_data||0);
    208 };
    209
    210 Update.compare=function(v1,v2){
    211  //sl('Update.compare: ['+v2+'] - ['+v1+'] = '+(v2-v1));
    212  return v2-v1;
    213 };
    214
    215 Update.after_install=function(e,prog,tmp){	//	e: Error object
    216  if(e){err(e);err('Update.install: 無法替換程式檔 ['+prog+']。新的程式檔置於 ['+tmp+']。');}
    217  else sl('更新完畢。'),warn('您需要<b onclick="history.go(0);">重新讀取</b>以完成更新！');
    218 };
    219
    220 Update.after_download=function(e,data){	//	e: error code
    221  if(e)err('Update.download: 下載 [<a href="'+this.download_URL+'">'+this.download_URL+'</a>] 發生錯誤！');
    222 };
    223
    224
    225
    226 /*	讀入單行 item=value 之設定
    227 	!noComment: '#', ';' 起頭、// 之後及 / *..* / 之間將被省略
    228 */
    229 function parseData(s,noComment){
    230  if(!s/*||s.charAt(0)=='#'*/ || !noComment&&!(s=s.replace(/([#;]|\/\/).*$/g,'')))return;	//	去掉單行註解
    231  var t,c,r,i=1;
    232  if(t=s.match(/\s*\[(.*)\]/))return t[1];	//	分區
    233
    234  try{	//	沒合在一起是為了在較低版本中r之設定可能失敗
    235   r=new RegExp('^\\s*([^=]+)\\s*=\\s*([^\\r\\n]*)');
    236   t=s.match(r);
    237  }catch(e){t=s.match(/^\s*([^=]+)\s*=\s*([^\r\n]*)/);}	//	使用此式可能導致某些問題
    238
    239  if(t){//if(t=s.match(/^\s*([^=]+?)\s*=\s*([^\r\n]*)/)){	//	後面的：原先簡潔版
    240   if(!t[1])return;
    241   var set=[];set[0]=t[1].replace(/\s+$|^\s+/g,''),t=set[1]=t[2];
    242   while((c=t.charAt(0))=='"'||c=="'"){
    243    if(!(c=t.match(new RegExp('^'+c+'([^'+c+']*)'+c+'[^\'"]*(.*)$'))))break;
    244    //alert('['+set[0]+']=\n'+t+'\n'+c[1]+'\n['+c[2]+']');
    245    set[i++]=c[1];
    246    t=c[2];//if(c=t.match(/^\s+/))t=t.substr(c.length);
    247    //alert('['+t+']');
    248   }
    249   return set;
    250  }
    251 }
    252
    253 /*	readin .ini file
    254 	http://en.wikipedia.org/wiki/Ini_file
    255 */
    256 parseINI[generateCode.dLK]='initWScriptObj,parseData,ForReading,TristateUseDefault';
    257 function parseINI(FN,format,INIunBlock,noComment){
    258  var INI={},datas;	//	設定值之陣列,未框起（設定區塊）之值
    259  if(!INIunBlock)INIunBlock='[unBlock]';	//	未框起（設定區塊）之值
    260  INI[INIunBlock]={};
    261  try{
    262   datas=fso.OpenTextFile(FN,ForReading,false,format||TristateUseDefault);
    263  }catch(e){}	//	不用openTemplate()：當找不到此.ini檔時pass而不顯示error
    264  if(!datas){
    265   //if(!INI)INI=[],INI[block=INIunBlock]=[];return 1;
    266   //alert('Cannot open:\n'+FN);
    267   return 0;
    268  }
    269
    270  var i,j,index,k,t,block,inC=false;	//	index,temp,區塊,於註解中(in comment)
    271  //INI=[],INI[block=INIunBlock]=[];	//	每次執行即重設
    272  while(!datas.AtEndOfStream)if(t=datas.ReadLine()){
    273   if(!noComment){
    274    t=t.replace(/\/\/.*/,'');	//	處理/*..*/前先處理//
    275    k=1;
    276    while(k){
    277     k=0;	//	.replace(/\/\*.*?\*\//g,'') 在 ver5 前會出現錯誤
    278     //if(!inC&&(i=t.indexOf('/*'))!=-1)if((j=t.indexOf('*/',i+2))==-1){inC=true,t=t.slice(0,i);break;}else k=1,t=t.slice(0,i)+t.substr(j+2);
    279     if(!inC&&(i=t.indexOf('/*'))!=-1){	//	處理註解 /*
    280      j=i+2;
    281      do{j=t.indexOf('*/',j);if(t.charAt(j-1)=='\\')j+=2;else break;}while(j!=-1);	//	預防「\*/」
    282      if(j==-1){inC=true,t=t.slice(0,i);break;}else k=1,t=t.slice(0,i)+t.substr(j+2);
    283     }
    284     //if(inC)if((i=t.indexOf('*/'))==-1)t='';else inC=false,t=t.substr(i+2),k=1;
    285     if(inC){	//	處理*/
    286      i=0;
    287      do{i=t.indexOf('*/',i);if(t.charAt(i-1)=='\\')i+=2;else break;}while(i!=-1);	//	預防「\*/」
    288      if(i==-1)t='';else inC=false,t=t.substr(i+2),k=1;
    289     }
    290    }
    291   }
    292   //if(!t)continue;alert(t);
    293   t=parseData(t,noComment);if(!t)continue;
    294   if(typeof t=='string'&&!INI[block=t])INI[block]={};
    295   else if(t.length==2)INI[block][t[0]]=t[1];
    296   else for(i=1,INI[block][t[0]]=[];i<t.length;i++)INI[block][t[0]].push(t[i]);//,alert(block+','+t[0]+','+t[i])
    297   //if(t[0])alert('INI['+block+']['+t[0]+']='+INI[block][t[0]]);else alert('block='+block);
    298  }
    299
    300  datas.Close();
    301  return INI;
    302 }
    303
    304
    305
    306
    307 /*
    308 	Scriptlet.Typelib 對象的設計用途是幫助您創建“Windows 腳本組件”（實質上，這是一種使您編寫的腳本可以像COM對象那樣工作的方法）。
    309 	http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0221.mspx
    310 	http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/guid.asp
    311 */
    312 function tempGUID(){
    313  var TypeLib=WScript.CreateObject("Scriptlet.TypeLib"),tGUID;
    314
    315  try{tGUID=TypeLib.Guid();}
    316  catch(e){return;}
    317  finally{TypeLib=null;}	//	即使 try 或 catch 區塊中發生傳回陳述式，或從 catch 區塊中擲出錯誤，仍會執行 finallyStatements 內的程式碼。finallyStatments 保證會永遠執行。
    318
    319  return tGUID;
    320 }
    321
    322
    323
    324 return (
    325 	CeL.OS.Windows.job
    326 );
    327 };
    328
    329 //===================================================
    330
    331 CeL.setup_module(module_name, code_for_including);
    332
    333 };
    334