<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-576000796195395635</id><updated>2012-02-17T05:14:20.228+09:00</updated><category term='ウィンドウ'/><category term='機能紹介'/><category term='セキュリティ'/><category term='FTP'/><category term='クリップボード'/><category term='自動化'/><category term='動画'/><category term='Notebook'/><category term='キーボード'/><category term='周辺ツール'/><category term='使用例'/><category term='HTTPD'/><category term='COM'/><category term='Hotstrokes'/><category term='SQLite'/><category term='文字列'/><category term='解説'/><category term='新機能'/><category term='ファイル'/><category term='スクリプト作成補助'/><category term='画像'/><category term='プロセス'/><category term='メール'/><category term='HTTP'/><title type='text'>NILScript</title><subtitle type='html'>JavaScriptベースの汎用スクリプト実行環境「NILScript」の紹介など</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>83</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-3947305832207349719</id><published>2011-06-12T10:36:00.000+09:00</published><updated>2011-06-12T10:36:24.012+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hotstrokes'/><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><category scheme='http://www.blogger.com/atom/ns#' term='クリップボード'/><category scheme='http://www.blogger.com/atom/ns#' term='使用例'/><title type='text'>Android端末のスクリーンショット保存を補助するスクリプト</title><content type='html'>今回は、過去に紹介したいくつかの機能を組み合わせて、Android端末のスクリーンショット撮影を補助するツールを作成する例を紹介します。&lt;br /&gt;Android端末のスクリーンショットを保存する方法としては、Android SDKに同梱のDDMSというプログラムを使用するのが代表的ですが、1枚の画像を保存するために「更新ボタンを押す→保存ボタンを押す→保存ファイル名を指定」という手間が必要で、あまり使い勝手がよくありません。&lt;br /&gt;そこで、特定のキーを押すだけで最新の画面を連番ファイル名で保存出来るようにします。&lt;br /&gt;&lt;pre&gt;var Clipboard=require('Clipboard').Clipboard;&lt;br /&gt;var dir=cwd().directory(&amp;quot;E:\\docs\\work\\NR_android\\ss&amp;quot;);&lt;br /&gt;var prefix=&amp;quot;ss_&amp;quot;, len=3, num=1;&lt;br /&gt;&lt;br /&gt;Main.createNotifyIcon();&lt;br /&gt;Main.process.priority=Process.priority.high;&lt;br /&gt;&lt;br /&gt;require('Hotstrokes').Hotstrokes.defineConditions({&lt;br /&gt;    DDMS:function()(this.activeWindow.title=='Device Screen Capture'),&lt;br /&gt;}).map('DDMS',{&lt;br /&gt;    &amp;quot;NumEnter&amp;quot;:function(){&lt;br /&gt;        Thread.create(function(){&lt;br /&gt;            var fmt=prompt('change prefix / number'), m;&lt;br /&gt;            if(fmt.match(/^\d+$/)){&lt;br /&gt;                num=fmt*1;&lt;br /&gt;            }else if(m=fmt.match(/^(.*?)(\d+)$/)){&lt;br /&gt;                prefix=m[1];&lt;br /&gt;                len=m[2].length;&lt;br /&gt;                num=m[2]*1;&lt;br /&gt;            }else{&lt;br /&gt;                prefix=fmt;&lt;br /&gt;            }&lt;br /&gt;            Main.notifyIcon.showInfo('Next: '+dir.file(prefix+num.format(len)+'.png'));&lt;br /&gt;        });&lt;br /&gt;    },&lt;br /&gt;    &amp;quot;NumMinus&amp;quot;:function(){&lt;br /&gt;        num--;&lt;br /&gt;        Main.notifyIcon.showInfo('Next: '+dir.file(prefix+num.format(len)+'.png'));&lt;br /&gt;    },&lt;br /&gt;    &amp;quot;NumPlus&amp;quot;:function(){&lt;br /&gt;        num++;&lt;br /&gt;        Main.notifyIcon.showInfo('Next: '+dir.file(prefix+num.format(len)+'.png'));&lt;br /&gt;    },&lt;br /&gt;    &amp;quot;Num0&amp;quot;:function(){&lt;br /&gt;        Thread.create(function(w){&lt;br /&gt;            w.control('Button',0).lbuttonClick();&lt;br /&gt;            sleep(800);&lt;br /&gt;            w.control('Button',3).lbuttonClick();&lt;br /&gt;            sleep(500);&lt;br /&gt;            var file=dir.file(prefix+num.format(len)+'.png');&lt;br /&gt;            try{&lt;br /&gt;                var img=Clipboard.image;&lt;br /&gt;                img.save(file);&lt;br /&gt;            }finally{&lt;br /&gt;                free(img);&lt;br /&gt;            }&lt;br /&gt;            Main.notifyIcon.showInfo('Saved: '+file);&lt;br /&gt;            num++;&lt;br /&gt;        },this.activeWindow);&lt;br /&gt;    },&lt;br /&gt;}).register();&lt;br /&gt;&lt;/pre&gt;キーボード操作への割り当てにはHotstrokesを使用します。端末の操作をしながら撮影操作を行なうため、押しやすいテンキーの0に割り当てることにします。&lt;br /&gt;DDMSのキャプチャウィンドウがアクティブな時だけ有効になるように、ウィンドウタイトルで判定する条件を定義して、その条件下への割り当てを行ないます。&lt;br /&gt;&lt;br /&gt;画像の保存は、ウィンドウ上のボタンの自動クリックにより画面の更新とクリップボードへのコピーを実行させた後、Clipboardユニットの画像取得機能で取得した画像を保存することで実現しています。&lt;br /&gt;ボタンを押してからDDMS側で処理が完了するまでにはタイムラグがあるので、適当にsleep()を入れて待機します。&lt;br /&gt;一連の処理には時間がかかるため、キー操作をブロックしないように新規スレッド上で行なうようにしています。&lt;br /&gt;&lt;br /&gt;Clipboard.imageで取得したImageオブジェクトはfree()で解放しなければならないことに注意が必要です。&lt;br /&gt;(Clipboardユニットの開発時点では、取得の度にコピーを生成しなければならないケースを想定していなかったため、このような仕様になっています)&lt;br /&gt;&lt;br /&gt;その他、プレフィクスや番号をプロンプトで指定する機能や、間違えて撮影したときのために連番を巻き戻す機能を用意しました。&lt;br /&gt;保存先ディレクトリは、頻繁に変更するものではないので、スクリプト上にハードコーディングしています。&lt;br /&gt;&lt;br /&gt;簡単なスクリプトですが、通常のスクリーンショット保存手順に比べるとかなり手間が軽減できるはずです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-3947305832207349719?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/3947305832207349719/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/06/android.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3947305832207349719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3947305832207349719'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/06/android.html' title='Android端末のスクリーンショット保存を補助するスクリプト'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8914396519978305743</id><published>2011-05-31T20:31:00.000+09:00</published><updated>2011-05-31T20:31:28.365+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ファイル'/><title type='text'>ZIPファイル内のファイルを解凍したり直接読み込む</title><content type='html'>NILScriptのZLibユニットに用意されているZIPクラスを利用すれば、ZIPファイルの圧縮や解凍を行なえます。&lt;br /&gt;&lt;br /&gt;ZIPファイル内の全てのファイルを指定のディレクトリに解凍するには、以下のようにZIPクラスのextract()メソッドを使用します。&lt;br /&gt;&lt;pre&gt;require('ZLib').ZIP.extract(zipfile, directory);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;extractText()やextractBytes()メソッドでは、ZIPファイル内のファイルをローカルファイルに保存することなく直接変数に読み込むことが出来ます。&lt;br /&gt;extractText()は文字列、extractBytes()はポインタオブジェクトを返します。&lt;br /&gt;以下の例では、ZIPファイル内の「changelog.txt」の内容を表示します。&lt;br /&gt;巨大なZIPファイル内の小さなファイルだけを利用したい場合などには、特に効率化が期待できます。&lt;br /&gt;&lt;pre&gt;println(require('ZLib').ZIP.extractText('F:\\downloads\\nil.zip','changelog.txt'));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ZIPクラスのインスタンスオブジェクトを作成すれば、更新日時や拡張子などの条件に一致するファイルだけを解凍したり、ファイルの解凍や読み込みは行なわずにサイズや更新日時などの情報を取得して利用するなど、様々な処理を行なえます。&lt;br /&gt;以下の例では、ZIPファイル内のファイルとローカルファイルを比較し、ZIPファイルにだけ存在するファイルやZIPファイル内の方が新しいファイルを列挙します。&lt;br /&gt;&lt;pre&gt;var dir=Main.scriptDirectory;&lt;br /&gt;var file="F:\\downloads\\nil.zip";&lt;br /&gt;try{&lt;br /&gt;    var zip=require('ZLib').ZIP.open(file);&lt;br /&gt;    for(let f in zip.descendants){&lt;br /&gt;        var lf=dir.file(f.path);&lt;br /&gt;        if(f.isDirectory){&lt;br /&gt;        }else if(!lf.exists){&lt;br /&gt;            println('[new] '+f.path);&lt;br /&gt;        }else if(f.time&gt;lf.mtime){&lt;br /&gt;            println('[updated] '+f.path);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}finally{&lt;br /&gt;    free(zip);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;ZIPオブジェクトのdescendantsプロパティで、ZIPファイル内の全てのファイルがZIPFile/ZIPDirectoryオブジェクトとして列挙できます。&lt;br /&gt;ZIPDirectoryオブジェクトを判別するために、isDirectoryプロパティが用意されているので、これを利用して除外します。&lt;br /&gt;「Main.scriptDirectory」などのDirectoryオブジェクトのfile()メソッドの引数にZIPFileオブジェクトのpathプロパティを指定すれば、ZIP内のパスに対応するローカルファイルのFileオブジェクトを得られます。&lt;br /&gt;ZIPFileのtimeプロパティでは、更新日時をDateオブジェクトとして得られます。これをFileオブジェクトのmtimeプロパティと比較すれば、ファイルが新しいかどうかが分かります。&lt;br /&gt;&lt;br /&gt;その他、ZIPFile/ZIPDirectoryオブジェクトには、指定のローカルファイルとして解凍するcopy()メソッドなどが用意されています。ZIP関連の機能の詳細は、NILScriptに同梱のdoc\ZLib.txtを参照して下さい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8914396519978305743?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8914396519978305743/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/05/zip_31.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8914396519978305743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8914396519978305743'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/05/zip_31.html' title='ZIPファイル内のファイルを解凍したり直接読み込む'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-3522488219637950292</id><published>2011-05-29T04:41:00.000+09:00</published><updated>2011-05-29T04:41:00.505+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ファイル'/><title type='text'>ファイルをZIP圧縮する</title><content type='html'>ZIPなどのアーカイブファイル形式は、複数のファイル群や巨大な圧縮されていないファイルをネット経由で公開・送受信したい場合に役立ちます。&lt;br /&gt;今回は、NILScriptでZIPファイルを作成する方法について説明します。&lt;br /&gt;&lt;br /&gt;ZIPファイルの読み書きを行なうには、ZLibユニットのZIPクラスを使用します。&lt;br /&gt;単に一つのディレクトリ配下のファイルをZIPファイルにするだけなら、以下のようにZIPクラスのcompress()メソッドをZIPファイルとディレクトリのパスを引数にして呼び出すだけです。&lt;br /&gt;&lt;pre&gt;require('ZLib').ZIP.compress(zipfile, directory);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;以下の例では、正規表現に一致するファイルを除外して、残りのファイルだけを圧縮します。&lt;br /&gt;&lt;pre&gt;var exclude=/\\nil\\(release|test\d*)\.ng|\\nil\\users|\\users\\Owner/;&lt;br /&gt;var src=Main.scriptDirectory;&lt;br /&gt;var dest="E:\\www\\public_html\\nil.zip";&lt;br /&gt;&lt;br /&gt;try{&lt;br /&gt;    var zip=require('ZLib').ZIP.create(dest);&lt;br /&gt;    (function(from,to){&lt;br /&gt;        for(var f in from.children){&lt;br /&gt;            if(!String(f).match(exclude)){&lt;br /&gt;                println(f.path);&lt;br /&gt;                if(f instanceof Directory){&lt;br /&gt;                    arguments.callee(f, to.directory(f.name).create(f.mtime));&lt;br /&gt;                }else{&lt;br /&gt;                    to.add(f);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    })(src,zip);&lt;br /&gt;}finally{&lt;br /&gt;    free(zip);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;まず、ZIPファイルのパスを引数にしてZIP.create()を呼び出し、ZIPオブジェクトを取得します。&lt;br /&gt;次に、Directoryオブジェクトのchildrenプロパティで圧縮対象ディレクトリ内のファイル/ディレクトリを列挙し、条件に一致するファイルをZIPファイルに追加していきます。&lt;br /&gt;&lt;br /&gt;ZIPファイルの直下にファイルを追加するには、追加したいファイルを表すFileオブジェクトを引数として、ZIPオブジェクトのadd()メソッドを呼び出します。&lt;br /&gt;&lt;br /&gt;Directoryオブジェクトを引数にadd()メソッドでを呼び出せば、配下のファイルを全て追加できますが、今回はサブディレクトリ内もフィルタリングしたいので、ZIPファイル内にディレクトリを作成したあと、再帰呼び出しで配下のファイルの処理を行なうことにします。&lt;br /&gt;&lt;br /&gt;ZIPファイル内にディレクトリを作成するには、ZIPオブジェクトのdirectory()メソッドでZIPDirectoryオブジェクトを取得し、そのcreate()メソッドを呼び出します。create()メソッドの返り値は、そのZIPDirectoryオブジェクト自身です。&lt;br /&gt;create()メソッドの引数には、格納するディレクトリの更新日時を表すDateオブジェクトを指定できます。&lt;br /&gt;&lt;br /&gt;ZIPDirectoryオブジェクトも、ZIPオブジェクトと同様に、add()メソッドでディレクトリ内のファイルとしてファイルを追加したり、directory()メソッドで子ディレクトリを表すZIPDirectoryオブジェクトを取得できるので、共通の関数で再帰処理を行なえます。&lt;br /&gt;&lt;br /&gt;処理が完了したら、free()関数でZIPオブジェクトを解放する必要があることに注意して下さい。&lt;br /&gt;&lt;br /&gt;この他のZIPファイル読み書き機能については、NILScriptに同梱のdoc\ZLib.txtを参照して下さい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-3522488219637950292?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/3522488219637950292/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/05/zip.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3522488219637950292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3522488219637950292'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/05/zip.html' title='ファイルをZIP圧縮する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-7712370016783754162</id><published>2011-05-11T20:34:00.001+09:00</published><updated>2011-05-15T21:00:58.504+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='プロセス'/><category scheme='http://www.blogger.com/atom/ns#' term='使用例'/><title type='text'>生成したプロセスの標準入出力を別のプロセスにリダイレクト</title><content type='html'>NILScriptでは、「Process.create()」やそのエイリアスである「run()」で外部プロセスを起動できます。&lt;br /&gt;このメソッドでは、第2引数にオブジェクトとして様々なオプションを指定する事で、標準入出力の扱いなどを柔軟に設定出来ます。&lt;br /&gt;例えば、「stdin」オプションにあらかじめProcess.create()で生成しておいた別のProcessオブジェクトを指定すると、そのプロセスの標準出力を次のプロセスの標準入力にリダイレクト出来ます。&lt;br /&gt;コマンドプロンプトで「|」で複数のコマンドを繋いだときのように、出力と入力を直接繋ぐので、スクリプト側で読み出しと書き込みを行うよりも効率的に動作します。&lt;br /&gt;他にも、ファイルやNULデバイスへのリダイレクトも可能です。これらの機能の詳細は、NILScriptに同梱のdoc\base_task.txtを参照して下さい。&lt;br /&gt;&lt;br /&gt;以下は、この機能の利用例です。&lt;br /&gt;&lt;pre&gt;//プログラムのパスと保存先を指定&lt;br /&gt;var rtmpdump='D:\\bin\\rtmpdump-2.1d\\rtmpdump.exe';&lt;br /&gt;var ffmpeg='D:\\bin\\ffmpeg.exe';&lt;br /&gt;var dir='F:\\downloads';&lt;br /&gt;&lt;br /&gt;var url=prompt('Enter MySpace URL(artist or song)','http://www.myspace.com/astralmess');&lt;br /&gt;var swf='http://lads.myspacecdn.com/videos/MSMusicPlayer.swf';&lt;br /&gt;var http=new (require('HTTP').HTTP)();&lt;br /&gt;&lt;br /&gt;var downloadSong=function(sid){&lt;br /&gt;    var xml=http.getText({&lt;br /&gt;        url:'http://www.myspace.com/music/services/player?songId='+sid&lt;br /&gt;          +'&amp;amp;ptype=4&amp;amp;action=getSong&amp;amp;el='+encodeURIComponent(url)+'&amp;amp;sample=0',&lt;br /&gt;        referer:swf,&lt;br /&gt;    });&lt;br /&gt;    var title=xml.match(/&amp;lt;title&amp;gt;([^&amp;gt;]*)&amp;lt;\/title&amp;gt;/)[1].unescapeHTML();&lt;br /&gt;    var rtmp=xml.match(/&amp;lt;rtmp&amp;gt;([^&amp;gt;]*)&amp;lt;\/rtmp&amp;gt;/)[1].unescapeHTML();&lt;br /&gt;    println('Downloading: '+title);&lt;br /&gt;    var p1=Process.create('&amp;quot;'+rtmpdump+'&amp;quot; -r '+rtmp+' -W '+swf+' -o -',{&lt;br /&gt;        show:0&lt;br /&gt;    });&lt;br /&gt;    var p2=Process.create('&amp;quot;'+ffmpeg+'&amp;quot; -i - -acodec copy -metadata title=&amp;quot;'&lt;br /&gt;                    +title+'&amp;quot; &amp;quot;'+dir+'\\'+title.format('asfE')+'.mp3&amp;quot;',&lt;strong&gt;{&lt;br /&gt;                        stdin:p1,&lt;br /&gt;                        stdout:&amp;quot;&amp;quot;,&lt;br /&gt;                    }&lt;/strong&gt;);&lt;br /&gt;    p2.wait('exit');&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;var m;&lt;br /&gt;if(m=url.match(/^http:\/\/www\.myspace\.com\/[^\/]*\/music\/songs\/.*\-(\d+)$/i)){&lt;br /&gt;    downloadSong(m[1]);&lt;br /&gt;}else if(m=url.match(/^http:\/\/www\.myspace\.com\/[^\/]*\/?$/)){&lt;br /&gt;    var html=http.getText(url);&lt;br /&gt;    m=html.match(/&amp;lt;param[^&amp;gt;]*value=&amp;quot;[^&amp;gt;&amp;quot;]*MSMusicPlayer\.swf&amp;quot;[^&amp;gt;]*&amp;gt;[\s\S]*?&amp;lt;param name=&amp;quot;flashvars&amp;quot; value=&amp;quot;([^&amp;quot;&amp;gt;]*)&amp;quot;/)&lt;br /&gt;    var param={};&lt;br /&gt;    for(let pair in $G(m[1].split(/&amp;amp;/g))){&lt;br /&gt;        var [,name,value]=pair.match(/^(.*?)=(.*)$/);&lt;br /&gt;        param[name]=value;&lt;br /&gt;    }&lt;br /&gt;    http.getText({&lt;br /&gt;        url:'http://www.myspace.com/music/services/player?artistUserId='&lt;br /&gt;            +param.profid+'&amp;amp;playlistId='+param.plid&lt;br /&gt;            +'&amp;amp;action=getArtistPlaylist&amp;amp;artistId='+param.artid,&lt;br /&gt;        referer:swf,&lt;br /&gt;    }).grep(/&amp;lt;song\s(?=[^&amp;gt;]*playType=&amp;quot;FullSong&amp;quot;)[^&amp;gt;]*songId=&amp;quot;(\d+)&amp;quot;/g).map(&amp;quot;1&amp;quot;).execute(downloadSong);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;音楽系SNS「MySpace」の指定したURLのページからプレイリストを抽出し、ストリーミングURLを「rtmpdump」でダウンロードし、「ffmpeg」でFLVからMP3を抽出して保存するというスクリプトですが、rtmpdumpの出力をffmpegにリダイレクトすることで、一時ファイルを作らずに処理を完了しています。&lt;br /&gt;太字になっている部分が、ffmpegの標準入出力を指定している部分です。&lt;br /&gt;「stdout:""」は、NULへのリダイレクトを示します。このようにして進捗などの出力を読み捨てないと、出力バッファが一杯になって処理が止まってしまう可能性があるので、注意が必要です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-7712370016783754162?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/7712370016783754162/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/05/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7712370016783754162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7712370016783754162'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/05/blog-post.html' title='生成したプロセスの標準入出力を別のプロセスにリダイレクト'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8061326771253427004</id><published>2011-04-28T19:54:00.000+09:00</published><updated>2011-04-28T19:54:54.817+09:00</updated><title type='text'>種文字列から一定の乱数列を生成する</title><content type='html'>NILScriptのCipherユニットには、種文字列を指定して乱数列を得るRandomクラスが用意されています。&lt;br /&gt;通常のMath.random()と違うのは、同じ種文字列を指定すると常に同じ乱数列が生成されるという点です。&lt;br /&gt;この機能を利用すれば、ゲームのステージ生成などで、生成されたステージを丸ごと保存しなくても、種文字列を保存しておくだけで過去に生成したステージを再現できるようになります。&lt;br /&gt;&lt;br /&gt;下記の例は、Cipher::Randomを利用して迷路を生成するというスクリプトです。&lt;br /&gt;コマンドライン引数に横の広さ、縦の広さ、種文字列を指定すると、迷路が生成され表示されます。&lt;br /&gt;種文字列が省略された場合は、String.random()で生成したランダムな文字列が使用されます。&lt;br /&gt;&lt;pre&gt;var w=(Main.params[0]||32)*2-1, h=(Main.params[1]||18)*2-1;&lt;br /&gt;var r=new (require('Cipher').Random)(Main.params[2]||String.random(16)); //(1)&lt;br /&gt;var map=[],joints=[];&lt;br /&gt;//周辺の枠の生成&lt;br /&gt;map.push(('-'.times(w-1)+'+').split(''));&lt;br /&gt;for(var x=2,m=w-2;x&amp;lt;m;x+=2){&lt;br /&gt;    joints.push({x:x,y:0});&lt;br /&gt;    joints.push({x:x,y:h-1});&lt;br /&gt;}&lt;br /&gt;for(var y=1;y&amp;lt;(h-1);++y){&lt;br /&gt;    map.push(('|'+' '.times(w-2)+'|').split(''));&lt;br /&gt;    if(!(y&amp;amp;1)){&lt;br /&gt;        joints.push({x:0,y:y});&lt;br /&gt;        joints.push({x:w-1,y:y});&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;map.push(('+'+'-'.times(w-1)).split(''));&lt;br /&gt;&lt;br /&gt;//壁の生成&lt;br /&gt;var j;&lt;br /&gt;while(joints.length){&lt;br /&gt; //新たに生やし始める箇所を選択する&lt;br /&gt;    if(!j){&lt;br /&gt;        j=joints[r.next(joints.length)]; //(3)&lt;br /&gt;    }&lt;br /&gt;    //壁を延ばす方向の候補を列挙&lt;br /&gt;    var c=[];&lt;br /&gt;    if((map[j.y-2]||[])[j.x]==' '){&lt;br /&gt;        c.push({via:{x:j.x  ,y:j.y-1}, next:{x:j.x  ,y:j.y-2}, mark:'|'});&lt;br /&gt;    }&lt;br /&gt;    if((map[j.y+2]||[])[j.x]==' '){&lt;br /&gt;        c.push({via:{x:j.x  ,y:j.y+1}, next:{x:j.x  ,y:j.y+2}, mark:'|'});&lt;br /&gt;    }&lt;br /&gt;    if((map[j.y]||[])[j.x-2]==' '){&lt;br /&gt;        c.push({via:{x:j.x-1,y:j.y  }, next:{x:j.x-2,y:j.y  }, mark:'-'});&lt;br /&gt;    }&lt;br /&gt;    if((map[j.y]||[])[j.x+2]==' '){&lt;br /&gt;        c.push({via:{x:j.x+1,y:j.y  }, next:{x:j.x+2,y:j.y  }, mark:'-'});&lt;br /&gt;    }&lt;br /&gt;    //延ばせる方向があれば、そのうちのどこかに延ばす&lt;br /&gt;    if(c.length){&lt;br /&gt;        var m=c[r.next(c.length)]; //(4)&lt;br /&gt;        map[m.via.y][m.via.x]=map[m.next.y][m.next.x]=m.mark;&lt;br /&gt;        if(map[j.y][j.x]!=m.mark){&lt;br /&gt;            map[j.y][j.x]='+';&lt;br /&gt;        }&lt;br /&gt;        joints.push(j=m.next);&lt;br /&gt;    }else{&lt;br /&gt;        joints.remove(j);&lt;br /&gt;        j=null;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;map[1][0]=map[h-2][w-1]=' ';&lt;br /&gt;//表示&lt;br /&gt;for(var y=0;y&amp;lt;h;++y){&lt;br /&gt;    var l=[];&lt;br /&gt;    for(var x=0;x&amp;lt;w;++x){&lt;br /&gt;        l.push(map[y][x]);&lt;br /&gt;        if(x&amp;amp;1){&lt;br /&gt;            l.push(map[y][x]);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    println(' '+l.join(''));&lt;br /&gt;}&lt;br /&gt;println('Seed='+r.seed);&lt;br /&gt;free(r); //(2)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;最初に「r」変数にRandomオブジェクトを格納します。(1)&lt;br /&gt;Randomオブジェクトは、不要になったら「free()」でリソースを解放する必要があります。(2)&lt;br /&gt;&lt;br /&gt;迷路の生成には、既存の壁から壁を生やして、他の壁にぶつからないように延ばしていくという方式を使用しています。&lt;br /&gt;新たに壁を生やし始める箇所を選択する処理(3)と、壁を延ばす方向を選択する処理(4)で乱数を使用しています。&lt;br /&gt;Randomオブジェクトのnext()メソッドは、Number.random()と同じように、指定した範囲の整数を返します。&lt;br /&gt;&lt;br /&gt;上記のスクリプトを「20 10 XYZ」を引数にして実行すると、以下のような迷路が表示されるはずです。&lt;br /&gt;&lt;pre&gt; ---------------------------------------------------------+&lt;br /&gt;                                                          |&lt;br /&gt; |  ---+  +-----------+  +-----+---  +--------+  +--+  +--+&lt;br /&gt; |     |  |           |  |     |     |        |  |  |  |  |&lt;br /&gt; |  +--+  |  +-----+  |  |  |  +-----+  +--+  |  |  |  |  |&lt;br /&gt; |  |     |  |     |     |  |           |  |  |  |  |  |  |&lt;br /&gt; |  +--+  +--+---  +-----+  +--------+  |  |  +--+  +--+  |&lt;br /&gt; |     |                             |  |  |           |  |&lt;br /&gt; |  +--+  +--------+  +-----+-----+--+  |  +--+  +--+  |  |&lt;br /&gt; |  |     |        |  |     |     |     |     |  |  |     |&lt;br /&gt; |  +-----+  +-----+  +--+  |  +--+  +--+--+  +--+  +--+  |&lt;br /&gt; |           |           |  |  |     |     |           |  |&lt;br /&gt; +--+  ---+  +--------+  |  |  +-----+  +--+  +-----+  |  |&lt;br /&gt; |  |     |           |  |  |           |     |     |  |  |&lt;br /&gt; |  +--+  |  +---  +--+  |  |  |  +-----+  +--+  +--+  |  |&lt;br /&gt; |     |  |  |     |  |     |  |  |        |  |  |     |  |&lt;br /&gt; |  ---+--+  +-----+  +-----+--+  +---  +--+  |  +-----+  |&lt;br /&gt; |                                      |&lt;br /&gt; +--------------------------------------+------------------&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8061326771253427004?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8061326771253427004/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/04/blog-post_28.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8061326771253427004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8061326771253427004'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/04/blog-post_28.html' title='種文字列から一定の乱数列を生成する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5017764537391603963</id><published>2011-04-14T04:13:00.000+09:00</published><updated>2011-04-14T04:13:05.593+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FTP'/><title type='text'>FTPでログファイルなどをレジュームダウンロードする</title><content type='html'>NILScriptのFTPユニットを利用すれば、自分の管理するWebサイトにFTPで接続してアクセスログなどのファイルを定期的に自動ダウンロードさせたりすることも可能です。&lt;br /&gt;&lt;br /&gt;末尾に追記されていくタイプのログファイルの場合、毎回丸ごとダウンロードするのではなく、取得済みのバイト数だけスキップして未取得の部分だけをダウンロードし、ローカルの取得済みファイルに追記するレジュームダウンロードを行うと、無駄な転送を減らせて効率的です。&lt;br /&gt;&lt;br /&gt;NILScriptのFTPユニットでは、下記の例のように、FTPオブジェクトのfile()メソッドで取得したFTPFileオブジェクトのdownload()メソッドを呼び出すとき、第2引数にtrueを指定すれば、第1引数に指定した保存先ファイルが存在した場合にそのファイルにレジュームダウンロードが行われます。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;try{&lt;br /&gt;    var ftp=new (require('FTP').FTP)({&lt;br /&gt;        host:'ftp.example.com',&lt;br /&gt;        user:'aaa',&lt;br /&gt;        password:'bbb',&lt;br /&gt;    });&lt;br /&gt; var f=ftp.file('/public_html/access.log');&lt;br /&gt; f.download('R:\\access.log',true);&lt;br /&gt;}finally{&lt;br /&gt;    free(ftp);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;第2引数を省略したりfalseを指定した場合は、既存の保存先ファイルの内容は上書きされます。&lt;br /&gt;画像などの追記型でないファイルをレジュームダウンロードしてしまうと、ファイル破損などの問題が生じるので注意して下さい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5017764537391603963?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5017764537391603963/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/04/ftp_14.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5017764537391603963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5017764537391603963'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/04/ftp_14.html' title='FTPでログファイルなどをレジュームダウンロードする'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-540484252140695603</id><published>2011-04-14T04:11:00.000+09:00</published><updated>2011-04-14T04:11:21.496+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='新機能'/><category scheme='http://www.blogger.com/atom/ns#' term='FTP'/><title type='text'>FTPでファイルをアップロードする</title><content type='html'>Webサーバへのファイルアップロードなどで用いられているFTPによるファイル転送やファイル情報の取得機能を提供する「FTP」ユニットが新たに追加されました。&lt;br /&gt;この機能を利用すれば、NILScript上でコンテンツを生成してアップロードまで行うことが出来ます。&lt;br /&gt;&lt;br /&gt;以下は、FTPによる基本的なファイルアップロードの例です。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;try{&lt;br /&gt;    var ftp=new (require('FTP').FTP)({&lt;br /&gt;        host:'ftp.example.com',&lt;br /&gt;        user:'aaa',&lt;br /&gt;        password:'bbb',&lt;br /&gt;    });&lt;br /&gt;    var d=ftp.directory('/public_html');&lt;br /&gt;    d.upload('C:\\www\\index.rdf');&lt;br /&gt;}finally{&lt;br /&gt;    free(ftp);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;FTPクラスのコンストラクタに、接続先サーバのホスト名やログインユーザー名、パスワードなどのメンバを持つオブジェクトを引数として与えると、サーバへの接続とログイン処理が行われ、インスタンスが生成されます。&lt;br /&gt;FTPインスタンスオブジェクトの「directory()」メソッドを、サーバ上の絶対パスを引数にして呼び出すと、そのディレクトリに関する操作を提供するFTPDirectoryオブジェクトが得られます。&lt;br /&gt;このFTPDirectoryオブジェクトの「upload()」メソッドをローカルファイルのパスやFileオブジェクトを引数にして呼び出すことで、ファイルのアップロードが行われます。&lt;br /&gt;&lt;br /&gt;FTPDirectoryオブジェクトには、他にもディレクトリ内のファイルやディレクトリを列挙するchildrenメンバなどの機能が用意されています。各機能の説明は、同梱のdoc/FTP.txtを参照して下さい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-540484252140695603?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/540484252140695603/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/04/ftp.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/540484252140695603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/540484252140695603'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/04/ftp.html' title='FTPでファイルをアップロードする'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-6403665883136632343</id><published>2011-04-08T20:19:00.000+09:00</published><updated>2011-04-08T20:19:44.546+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='メール'/><category scheme='http://www.blogger.com/atom/ns#' term='セキュリティ'/><title type='text'>Mailユニットで送受信するメールを暗号化する</title><content type='html'>Mailユニットに用意されているPOP3クラスを使用すれば、定期的に新着メールをチェックして特定の書式のメールがあったときに本文に記述された命令を実行するというスクリプトを起動しておき、外出先からメールで自宅のPCを操作することも可能です。&lt;br /&gt;しかし、何者かに偽の命令メールで勝手に操作されてしまっては困ります。&lt;br /&gt;命令メールの送信をPC上から行うのであれば、送信時に内容を暗号化するようにすればよいでしょう。&lt;br /&gt;&lt;br /&gt;メールを暗号化するには、Cipherユニットを使用し、以下のようにします。&lt;br /&gt;&lt;pre&gt;var subject='NILScript:Command';&lt;br /&gt;var addr='test@example.com';&lt;br /&gt;var msg="HELLO";&lt;br /&gt;var key='password';&lt;br /&gt;var opt={cipher:"AES-128-CFB",salt:true,encoding:"utf8"};&lt;br /&gt;try{&lt;br /&gt;    var smtp=new (require('Mail').SMTP)({&lt;br /&gt;        host:'vm01xp',&lt;br /&gt;        user:'test',&lt;br /&gt;        password:'asdf',&lt;br /&gt;        pop:true,&lt;br /&gt;    });&lt;br /&gt;    smtp.send({&lt;br /&gt;        subject:subject,&lt;br /&gt;        from:addr,&lt;br /&gt;        to:addr,&lt;br /&gt;        message: require('Cipher').Cipher.encode(JSON.stringify(&lt;br /&gt;            {time:now().getTime(),text:msg}&lt;br /&gt;        ),key,opt),&lt;br /&gt;    });&lt;br /&gt;}finally{&lt;br /&gt;    free(smtp,cp);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Cipherクラスのencode()メソッドを、平文データとパスワード、暗号化オプションを引数にして呼び出すことで、暗号化されたBASE64文字列を取得できます。&lt;br /&gt;これをSMTPオブジェクトのsend()メソッドの引数オブジェクトのmessageメンバに指定して、メール本文として送信します。&lt;br /&gt;なお、BASE64文字列ではなくバイト列へのPointerオブジェクトを返すCipher.encodeToBytes()などのメソッドも用意されています。&lt;br /&gt;&lt;br /&gt;受信側では、以下のようにスレッドを生成して定期的にPOP3サーバに接続し、規定の件名のメールがあったときに、本文をCipher.decode()で復号化します。&lt;br /&gt;この例では「Main.notifyIcon.showInfo()」で本文を表示しているだけですが、eval()関数に渡せば、任意のNILScript文を実行させたりもできます。&lt;br /&gt;&lt;pre&gt;var subject='NILScript:Command';&lt;br /&gt;var addr='test@example.com';&lt;br /&gt;var msg="HELLO";&lt;br /&gt;var key='password';&lt;br /&gt;var opt={cipher:"AES-128-CFB",salt:true,encoding:"utf8"};&lt;br /&gt;Main.createNotifyIcon();&lt;br /&gt;var last=now().getTime();&lt;br /&gt;Thread.create(function(){&lt;br /&gt;    while(true){&lt;br /&gt;        try{&lt;br /&gt;            var pop3=new (require('Mail').POP3)({&lt;br /&gt;                host:'vm01xp',&lt;br /&gt;                user:'test',&lt;br /&gt;                password:'asdf',&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            for(let m in pop3.items){&lt;br /&gt;                if(m.subject==subject){&lt;br /&gt;                    var {text,time}=JSON.parse(&lt;br /&gt;                        require('Cipher').Cipher.decode(m.message,key,opt)&lt;br /&gt;                    );&lt;br /&gt;                    if(text &amp;amp;&amp;amp; time &amp;amp;&amp;amp; (time&amp;gt;last)){&lt;br /&gt;                        Main.notifyIcon.showInfo(text);&lt;br /&gt;                        last=time;&lt;br /&gt;                    }&lt;br /&gt;                    m.remove();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }catch(e){&lt;br /&gt;            println(e);&lt;br /&gt;        }finally{&lt;br /&gt;            free(pop3);&lt;br /&gt;        }&lt;br /&gt;        sleep(60000);&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;セキュリティを強化するため、単に命令本文を暗号化するのではなく、実際の命令本体と命令の送信日時の2つのメンバからなるオブジェクトのJSON文字列を暗号化して、受信側では前回実行した命令よりも新しい命令でないと実行しないようにしています。&lt;br /&gt;こうしておかないと、メールを傍受した何者かが、後でそのメールを送りつけることで過去に送信された命令を任意のタイミングで再実行できてしまいます。&lt;br /&gt;ハッシュなどによる改竄チェックは行っていないので、出鱈目なBASE64文字列が送りつけられても復号化してJSON文字列の解析まで行われてしまいますが、偶然timeとtextのメンバを持つオブジェクトのJSON文字列として正しくデコード出来てしまう可能性は低いので問題ないでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-6403665883136632343?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/6403665883136632343/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/04/mail.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6403665883136632343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6403665883136632343'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/04/mail.html' title='Mailユニットで送受信するメールを暗号化する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-7266981575198768352</id><published>2011-04-08T20:14:00.000+09:00</published><updated>2011-04-08T20:14:49.016+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='メール'/><title type='text'>POP3でメールを受信する</title><content type='html'>最近追加されたMailユニットには、メールの受信を行うPOP3クラスが用意されています。&lt;br /&gt;この機能を利用すれば、新着メールをチェックするツールや、メールで受信した命令に従って処理を自動実行するツールなどを実現できます。&lt;br /&gt;&lt;br /&gt;POP3クラスの基本的な使用方法は以下のようになります。&lt;br /&gt;&lt;pre&gt;try{&lt;br /&gt;    var pop3=new (require('Mail').POP3)({&lt;br /&gt;        host:'vm01xp',&lt;br /&gt;        user:'test',&lt;br /&gt;        password:'asdf',&lt;br /&gt;    });&lt;br /&gt;    for(let m in pop3.items){&lt;br /&gt;        println(m.subject);&lt;br /&gt;    }&lt;br /&gt;}finally{&lt;br /&gt;    free(pop3);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;SMTPの場合と同じように、new POP3()でインスタンスを生成すると、サーバとの接続やログイン処理が行われ、free()でログアウトと切断が行われます。&lt;br /&gt;POP3オブジェクトは、「count」プロパティでメールボックス内のメールの件数が取得したり、「items」プロパティで各メールの情報取得を行うRemoteMailオブジェクトを列挙できます。&lt;br /&gt;RemoteMailオブジェクトには、ヘッダを受信して件名を返す「subject」や、本文テキストを返す「message」などのプロパティが用意されています。また、「remove()」メソッドで、サーバ上からメールを削除することも可能です。&lt;br /&gt;上記の例では、サーバ上のメールの本文を表示しています。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-7266981575198768352?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/7266981575198768352/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/04/pop3.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7266981575198768352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7266981575198768352'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/04/pop3.html' title='POP3でメールを受信する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8148903933375142426</id><published>2011-04-08T20:12:00.000+09:00</published><updated>2011-04-08T20:12:28.327+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='メール'/><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>スクリーンショットをメール送信する</title><content type='html'>NILScriptのMailユニットのSMTPクラスでは、添付ファイルの送信も可能です。&lt;br /&gt;添付ファイルには、Fileオブジェクトの他、メモリ上のバイト列を指すPointerオブジェクトを指定することも可能です。&lt;br /&gt;画像を扱うImageオブジェクトには、ファイルに書き込むことなくPNGやJPEGなどの画像ファイルのバイト列を生成してPointerオブジェクトで得るtoBytes()というメソッドが用意されているので、以下のようにデスクトップのスクリーンショットなどをファイルに保存することなくメール送信することが可能です。&lt;br /&gt;&lt;pre&gt;try{&lt;br /&gt;    var smtp=new (require('Mail').SMTP)({&lt;br /&gt;        host:'vm01xp',&lt;br /&gt;        user:'test',&lt;br /&gt;        password:'asdf',&lt;br /&gt;        pop:true,&lt;br /&gt;    });&lt;br /&gt;    var img=require('Image').Image.capture();&lt;br /&gt;    var buf=img.toBytes('.png');&lt;br /&gt;    smtp.send({&lt;br /&gt;        subject:"ScreenShot",&lt;br /&gt;        from:'test@example.com',&lt;br /&gt;        to:'test@example.com',&lt;br /&gt;        message:"test",&lt;br /&gt;        files:{&lt;br /&gt;            'image/png:ss.png':buf&lt;br /&gt;        },&lt;br /&gt;    });&lt;br /&gt;}finally{&lt;br /&gt;    free(smtp,buf,img);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;「require('Image').Image.capture()」でデスクトップのスクリーンショットをImageオブジェクトとして取得し、img変数に代入します。&lt;br /&gt;次に、img.toBytes('.png')でPNGファイルのバイト列を生成しています。&lt;br /&gt;これらのオブジェクトは、最後にfree()関数で解放する必要があります。&lt;br /&gt;そして、SMTPオブジェクトのsend()メソッドの引数で、filesメンバに添付したいファイルの情報を与えます。&lt;br /&gt;添付するのがFileオブジェクトの場合は、FileオブジェクトそのものやFileオブジェクトの配列として指定するだけで、元のファイル名で添付できますが、Pointerオブジェクトの場合はファイル名を指定する必要があるので、上記のように「"content-type:filename":data」のような形式のオブジェクトにして指定します。&lt;br /&gt;Content-Typeの部分を省略して「"filename":data」のようにすると、Content-Typeは「application/octet-stream」として添付されますが、メールソフトの添付画像表示機能などが効かなくなる場合があるので、形式が分かるならなるべく指定しておいた方がいいでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8148903933375142426?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8148903933375142426/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/04/blog-post_08.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8148903933375142426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8148903933375142426'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/04/blog-post_08.html' title='スクリーンショットをメール送信する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-7151862387346927989</id><published>2011-04-08T20:09:00.000+09:00</published><updated>2011-04-08T20:09:00.446+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='新機能'/><category scheme='http://www.blogger.com/atom/ns#' term='メール'/><title type='text'>処理完了などのイベントをメールで知らせる</title><content type='html'>最近のアップデートで、SMTP/POP3サーバに接続してメールの送受信を行う「Mail」ユニットが追加されました。&lt;br /&gt;この機能を使えば、自動処理の完了など何らかのイベントの発生時にメールを送信して知らせたり、外出先からメールで送信した指令に応じて自動処理を行うことなどが可能になります。&lt;br /&gt;&lt;br /&gt;SMTPクラスによるメール送信の基本的な手順は以下の通りです。&lt;br /&gt;&lt;pre&gt;try{&lt;br /&gt;    var smtp=new (require('Mail').SMTP)({&lt;br /&gt;        host:'vm01xp',&lt;br /&gt;        user:'test',&lt;br /&gt;        password:'asdf',&lt;br /&gt;        pop:true,&lt;br /&gt;    });&lt;br /&gt;    &lt;br /&gt;    smtp.send({&lt;br /&gt;        subject:'テストメール',&lt;br /&gt;        from:'test@example.com',&lt;br /&gt;        to:"test@example.com',&lt;br /&gt;        encoding:'iso-2022-jp',&lt;br /&gt;        message:"テスト本文",&lt;br /&gt;    });&lt;br /&gt;}finally{&lt;br /&gt;    free(smtp);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;まず、SMTPクラスのコンストラクタにホスト名やユーザー、パスワードなどのオプションを与えて呼び出し、インスタンスオブジェクトを得ます。この時、サーバとの接続が確立され、ログイン処理などが行われます。&lt;br /&gt;POP before SMTPを使用するには、オプションに「pop:true」を指定します。未指定時はSMTPのコマンドによる認証が行われます。&lt;br /&gt;&lt;br /&gt;こうして得たSMTPオブジェクトのsend()メソッドに、件名や宛先、本文などを指定するオプションオブジェクトを与えて実行することで、メールの送信が実行されます。&lt;br /&gt;「encoding:'iso-2022-jp'」は、本文や件名を日本語の7ビット文字コードとして一般的なiso-2022-jpでエンコードすることを指定しています。&lt;br /&gt;未指定時はutf-7でエンコードされますが、古い日本製のメールソフトなどではデコードできないかもしれないので、人間に読ませる日本語メールを送信する場合はこのオプションを指定しておいた方がよいでしょう。&lt;br /&gt;&lt;br /&gt;メールの送信が終ったら、「free(smtp)」のようにしてサーバからの切断を行います。&lt;br /&gt;この処理は、エラー発生時でも確実に実行されるように、try...finallyのfinally説で実行するようにします。&lt;br /&gt;&lt;br /&gt;その他の細かな機能の説明などは、NILScriptに同梱のdoc\Mail.txtを参照して下さい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-7151862387346927989?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/7151862387346927989/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/04/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7151862387346927989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7151862387346927989'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/04/blog-post.html' title='処理完了などのイベントをメールで知らせる'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-72376345388763384</id><published>2011-03-30T00:55:00.003+09:00</published><updated>2011-03-30T21:53:41.553+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='自動化'/><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>ノートPCのAC電源復旧時にWoLでデスクトップPCを起動</title><content type='html'>停電時でもPCに稼働し続けて欲しければ、バッテリを搭載しているノートPCを使用するのが無難ですが、PCI接続の機器などを使う必要がある場合、デスクトップPCを選択せざるを得ません。&lt;br /&gt;デスクトップPCでは、バッテリによる予備電源を提供するUPS(無停電電源装置)を利用しても、長時間に及ぶ停電を無停止で乗り切ることは出来ません。&lt;br /&gt;また、USB接続などでPCと連動して停電時に自動で安全なシャットダウンを行う機能は多くのUPSに用意されていますが、電源復旧時にPCを自動で起動する機能は用意されていないことがあり、外出などで手動での電源投入が行なえない状況では、長時間シャットダウンされたままになってしまうことがあります。&lt;br /&gt;&lt;br /&gt;どうしてもデスクトップPCの停止時間を最小限にとどめたければ、別途ノートPCを起動しておき、そこからデスクトップPCを自動起動させるとよいでしょう。&lt;br /&gt;&lt;br /&gt;NILScriptでは「System.hasAC」で電源が供給されているかどうかを取得できる他、System.observe()で「powerStatusChange」イベントにコールバック関数を登録することで、電源の状態が変化したときに任意の処理を実行させられます。&lt;br /&gt;また、LAN上にマジックパケットをブロードキャストして指定のコンピュータを起動させるWOL(WakeOnLAN)の機能も最近追加されました。&lt;br /&gt;これらの機能を利用して以下のようなスクリプトを作成し、AC電源に接続したノートPC上で実行しておけば、AC電源が断たれた状態から復旧したときに自動で指定のPCを起動してくれるはずです。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var mac="00 01 02 03 04 05";//起動対象PCのMACアドレス&lt;br /&gt;var dest="192.168.1.255"; //パケット送信先のブロードキャストアドレス&lt;br /&gt;&lt;br /&gt;Main.createNotifyIcon();&lt;br /&gt;var power=System.hasAC;&lt;br /&gt;&lt;br /&gt;System.observe('powerStatusChange',function(){&lt;br /&gt; if(!power &amp;&amp; System.hasAC){&lt;br /&gt;  require('WOL').WOL.send(mac,dest);&lt;br /&gt; }&lt;br /&gt; power=System.hasAC;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;なお、WOLでPCを遠隔起動するには、対象のPCがWOLに対応したLANカードでルーターに有線接続されていて、BIOSの設定でWOLが有効になっている必要があります。&lt;br /&gt;また、停電でルーターが停止してしまう場合、powerStatusChangeイベントで電源復旧を検出した直後にWOL.send()を行ってもパケットが到達しない可能性があるため、適宜sleep()などを挿入して下さい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-72376345388763384?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/72376345388763384/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/03/pcacwolpc.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/72376345388763384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/72376345388763384'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/03/pcacwolpc.html' title='ノートPCのAC電源復旧時にWoLでデスクトップPCを起動'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5970387981998156673</id><published>2011-03-29T04:59:00.002+09:00</published><updated>2011-03-29T05:05:52.832+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='動画'/><title type='text'>録画したテレビ番組のL字を除去する</title><content type='html'>大災害が発生したりすると、テレビ番組の画面の周囲にL字状の枠が追加されて被害情報などが表示されますが、録画した番組を後で視聴するときには邪魔でしかありません。&lt;br /&gt;エンコード時にクロップして除去してしまえばよいのですが、CMなどでL時の有無が切り替わる部分ではフェードイン・アウトが行われるため、綺麗に除去するエンコード定義を手動で作成するのは非常に面倒です。&lt;br /&gt;そこで、動画からL字の出現範囲を自動検出して、フェードイン・アウトの部分まで正確に除去するAviSynthスクリプトを生成するというNILScript用スクリプトを作成しました。&lt;br /&gt;&lt;br /&gt;AviSynthは、動画の読み込みや加工処理を定義するスクリプト言語の処理系です。&lt;br /&gt;AviSynthをインストールすると、VideoForWindows APIで拡張子「.avs」のスクリプトを動画として読み込めるようになります。&lt;br /&gt;VirtualDubなどのソフトで読み込んで編集・エンコードする一般的な使い方ですが、NILScriptのVideoユニットもVFWを利用しているためAviSynthスクリプトを読み込み可能で、今回のスクリプトでも映像処理の大部分はAviSynthスクリプトで行っています。&lt;br /&gt;&lt;br /&gt;NILScriptのVideoユニットは、このL字除去スクリプトを作成するために暫定的に実装されたものなので、限られた機能しか用意されていませんが、このスクリプトのようにAviSynthと組み合わせれば、様々な動画処理ツールを手軽に作成できるでしょう。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;スクリプトと定義データ一式は以下のURLからダウンロードできます。&lt;br /&gt;使用するには、別途NILScript本体とAviSynth、MPEG-2 VIDEO VFAPI Plug-Inが必要です。&lt;br /&gt;スクリプトの内容や詳しい使用方法は、上記アーカイブ内のファイルを参照して下さい。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lukewarm.s151.xrea.com/rem.zip"&gt;http://lukewarm.s151.xrea.com/rem.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;L字の検出には、L字の左上辺りの映像が不変である部分のサンプル画像を用意しておき、動画の各フレーム画像との差を調べるという手法を用いています。&lt;br /&gt;ほとんど全てのピクセルが一致した場合に完全なL字とみなし、それ以外はL字無しかフェードイン・アウト中のフレームとみなすことにしました。&lt;br /&gt;&lt;br /&gt;スクリプトが実行されると、各フレームのL字の有無を示す小さな画像からなる動画を出力するAviSynthスクリプトを生成して、Videoユニットで読み込み、フレームを一定間隔で飛ばしながらL字の有無を調べます。&lt;br /&gt;L字の有無が切り替わっている箇所が見つかったら、間のフレームを調べて正確な境目を探します。&lt;br /&gt;ここでも、最初に範囲の中央を調べ、既に切り替わっていたら範囲の前半、切り替わっていなければ範囲の後半を再帰的に調べるという二分探索的な手法を採ることで高速化しています。&lt;br /&gt;フェードイン・アウトのフレーム数は放送局ごとに一定なので、完全にL字である範囲がわかれば、フェードイン・アウトの範囲と、L字無しの範囲も確定します。&lt;br /&gt;動画の末尾まで調べたら、元の動画を読み込んで各部分に対応するフィルタを適用して連結するというAviSynthスクリプトを構築して保存すれば処理完了です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5970387981998156673?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5970387981998156673/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/03/l.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5970387981998156673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5970387981998156673'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/03/l.html' title='録画したテレビ番組のL字を除去する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8199154652994825295</id><published>2011-03-24T18:43:00.003+09:00</published><updated>2011-03-25T00:20:10.270+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='新機能'/><category scheme='http://www.blogger.com/atom/ns#' term='動画'/><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>動画ファイルから画像を取得してサムネイル生成などを行う</title><content type='html'>動画ファイルから寸法などの情報や任意のフレームの画像を取得できる「Video」ユニットを暫定的に実装しました。&lt;br /&gt;&lt;br /&gt;動画のフレームは、Imageユニットで定義されているImageオブジェクトとして取得され、リサイズなど様々な処理が可能です。&lt;br /&gt;&lt;br /&gt;下記のスクリプトは、コマンドライン引数で指定した動画ファイルから等間隔にフレームを抜き出し、縮小して並べた画像をファイルに保存するという例です。&lt;br /&gt;&lt;pre&gt;var file=cwd().file(Main.params[0]);&lt;br /&gt;var scale=4;//縮小率&lt;br /&gt;var cx=4, cy=4;//横、縦に並べる数&lt;br /&gt;try{&lt;br /&gt;    var vf=require('Video').VideoFile.open(file);&lt;br /&gt;    var st=vf.openVideo();&lt;br /&gt;    var dist=Math.floor(st.length/(cx*cy));&lt;br /&gt;    var w=Math.floor(st.width/scale), h=Math.floor(st.height/scale);&lt;br /&gt;    var img=require('Image').Image.create(w*cx,h*cy);&lt;br /&gt;    for(var i=0;i&amp;lt;cy;i++){&lt;br /&gt;        for(var j=0;j&amp;lt;cx;j++){&lt;br /&gt;            try{&lt;br /&gt;                var frame=st.getFrazme((i*cx+j)*dist);&lt;br /&gt;                img.drawImage(frame,w*j,h*i,w,h);&lt;br /&gt;            }finally{&lt;br /&gt;                free(frame);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    img.save(cwd().file(file.name+'.jpg'),{quality:80});&lt;br /&gt;}finally{&lt;br /&gt;    free(st,vf,img);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-h2zoRMcshIE/TYtgoPy7LMI/AAAAAAAAAEU/zsadjAU7C20/s1600/NHK_filler_cat.avi.jpg" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"&gt;&lt;img border="0" height="240" width="320" src="http://1.bp.blogspot.com/-h2zoRMcshIE/TYtgoPy7LMI/AAAAAAAAAEU/zsadjAU7C20/s320/NHK_filler_cat.avi.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;実行すると、左記のような画像ファイルが生成されます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;現在の所、VideoForWindowsのAPIを利用しているため、AVIなど限られた形式にしか対応していませんが、&lt;a href="http://sourceforge.net/projects/avisynth2/" target="_blank"&gt;AviSynth&lt;/a&gt;をインストールして、DirectShowSource()などで動画を読み込むAVSスクリプトを作成してそれを読み込むようにすれば、MPEGなど他の形式にも対応させられるはずです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8199154652994825295?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8199154652994825295/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/03/blog-post_24.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8199154652994825295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8199154652994825295'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/03/blog-post_24.html' title='動画ファイルから画像を取得してサムネイル生成などを行う'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-h2zoRMcshIE/TYtgoPy7LMI/AAAAAAAAAEU/zsadjAU7C20/s72-c/NHK_filler_cat.avi.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-607130035007804149</id><published>2011-03-06T05:25:00.000+09:00</published><updated>2011-03-06T05:25:59.723+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><category scheme='http://www.blogger.com/atom/ns#' term='キーボード'/><title type='text'>非アクティブのウィンドウにキー操作を送信</title><content type='html'>GUIプログラムの自動操作を行うとき、対象のウィンドウをいちいちアクティブにしていたのでは、他の作業の邪魔になってしまいます。&lt;br /&gt;ウィンドウを非アクティブのままで操作したければ、キー操作時に送られるウィンドウメッセージを送信する「sendKeys()」を使うといいでしょう。(最近追加された機能なので、使用するには最新版にアップデートして下さい)&lt;br /&gt;&lt;br /&gt;下記の例は、ある音楽プレイヤーソフトにPauseのショートカットキーを送信する例です。&lt;br /&gt;&lt;pre&gt;require('Window').Window.find('{DA7CD0DE-1602-45e6-89A1-C2CA151E008E}').sendKeys('[x]');&lt;br /&gt;&lt;/pre&gt;「require('Window').Window.find('...')」で、指定のクラス名を持つウィンドウの内、一番手前のものを表すWindowオブジェクトが返されます。&lt;br /&gt;そのsendKeys()メソッドを呼び出すことで、ウィンドウメッセージによる擬似的なキーストロークの送信を行います。&lt;br /&gt;大抵のソフトでは、タスクトレイに格納されたりして非表示になっていても、ウィンドウ自体は非表示の状態で存在しているため、上記の要領で操作可能です。&lt;br /&gt;&lt;br /&gt;ショートカットキーは、親ウィンドウではなく配下のコントロールに送信しなければ動作しない場合があります。&lt;br /&gt;配下のコントロールを表すオブジェクトを取得するには、「control()」メソッドを使用します。&lt;br /&gt;次の例は、「TVXEForm」というクラス名の一番手前のウィンドウの配下の「TEditorX」というクラス名のコントロールに「Ctrlキーを押しながらsキーを押して放しCtrlキーを放す」というキーストロークを送信するというものです。&lt;br /&gt;&lt;pre&gt;require('Window').Window.find('TVXEForm').control('TEditorX').sendKeys('Ctrl+[s]');&lt;br /&gt;&lt;/pre&gt;controlの第2引数に数値を指定すれば、複数の同クラス名コントロールの内、任意のオフセットのものを取得できます。未指定時は0を指定したものとみなされ、最初の物が取得されます。&lt;br /&gt;&lt;br /&gt;sendKeysで指定するキーストロークの定義には、NILScriptの「Hotstrokes」ユニットで使用されているストローク定義文字列の内、通常のキーボードのキーのみで構成された物が指定できます。&lt;br /&gt;Hotstrokesでは様々なキーストロークを定義するためのルールがありますが、標準的なショートカットキーを送信するだけなら、修飾キー名(Shift/Ctrl/Alt)に「+」を付けたものに続いてキー名を「[]」で囲んで記述するという方式を覚えておけば十分でしょう。&lt;br /&gt;&lt;br /&gt;なお、送信されるキーストロークの内、修飾キーの部分だけはウィンドウメッセージではなくシステム全体に影響する方式で擬似的なキーストローク生成が行われます。&lt;br /&gt;これは、多くのソフトのショートカットキー認識では、修飾キーの状態をシステムに問い合わせて取得しており、ウィンドウメッセージでCtrlの押し下げを送信しても無視されてしまうためです。&lt;br /&gt;このため、修飾キーを伴うショートカットキーを送信すると、他のソフトに意図しない操作が認識されてしまう可能性があります。&lt;br /&gt;できれば実行したい動作を「F1」のような修飾キーを伴わないショートカットキーに割り当てておき、それを送信すると良いでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-607130035007804149?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/607130035007804149/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/03/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/607130035007804149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/607130035007804149'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/03/blog-post.html' title='非アクティブのウィンドウにキー操作を送信'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2397333495650212280</id><published>2011-02-17T19:34:00.000+09:00</published><updated>2011-02-17T19:34:42.822+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Notebook'/><title type='text'>ContentExtractorのプラグインの仕様</title><content type='html'>NILScriptに同梱の「Notebook.ng」でWebページから本文を抽出するために用意されている「ContentExtractor」では、本文の抽出方法をプラグインとして追加できるようになっています。&lt;br /&gt;現在のところ、はてなダイアリーやFC2ブログなどの代表的なブログサービスや、Vector、窓の杜、ITMediaなどのIT系情報サイトに対応するプラグインなどが用意されていますが、各自でプラグインを作成すればどんなサイトにでも対応させられます。&lt;br /&gt;今回は、ContentExtractorプラグインの仕様について説明します。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;基本的な定義&lt;/h4&gt;ContentExtractorのプラグインは、NILScriptのディレクトリ配下の「plugins\ContentExtractor」ディレクトリ内にプラグイン名のディレクトリを作って格納します。&lt;br /&gt;各プラグインのディレクトリには、プラグイン名に拡張子「.ng」を付けたファイル名でプラグインのスクリプトファイルを格納します。&lt;br /&gt;スクリプトファイル内には、以下のようなオブジェクト定義を記述します。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;({&lt;br /&gt;    description:String(&amp;lt;![CDATA[&lt;br /&gt;        http://wiredvision.jp/の巡回と記事本文抽出。&lt;br /&gt;    ]]&amp;gt;),&lt;br /&gt;    level:50,&lt;br /&gt;    rules:{&lt;br /&gt;        atom:{&lt;br /&gt;            urlPattern:/^http:\/\/(wiredvision\.jp|rss\.rssad\.jp\/rss\/wiredvision)\/.*\/atom\.xml$/i,&lt;br /&gt;            inherit:&amp;quot;std/atom&amp;quot;,&lt;br /&gt;            childContentBodyPattern:true,&lt;br /&gt;            replace:['NoTracker'],&lt;br /&gt;        },&lt;br /&gt;        article:{&lt;br /&gt;            urlPattern:/^http:\/\/wiredvision\.jp\/.*\.html$/i,&lt;br /&gt;            contentPattern:/&amp;lt;!--\s*google_ad_section_start\(name=s2\)\s*--&amp;gt;([\s\S]*?)&amp;lt;!--\s*google_ad_section_end\(name=s2\)\s*--&amp;gt;/i,&lt;br /&gt;            sectionLinkPattern:/(&amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;http:\/\/wiredvision\.jp\/[^&amp;quot;&amp;gt;]+&amp;quot;&amp;gt;[^&amp;lt;]*へ続く&amp;lt;\/a&amp;gt;&amp;lt;\/p&amp;gt;)/i,&lt;br /&gt;            replace:[&lt;br /&gt;                &lt;br /&gt;            ],&lt;br /&gt;        },&lt;br /&gt;    },&lt;br /&gt;})&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;オブジェクトの「rules」メンバの下にページの解析ルールを列挙し、各ルールのurlPatternメンバで、そのルールが対応しているページのURLにマッチする正規表現を指定します。&lt;br /&gt;上記の「atom」ルールの「inherit:"std/atom"」は、stdプラグインで定義されている「atom」ルールを継承し上書きすることを示しています。&lt;br /&gt;std/atomルールは、Atomフィードから各entry要素のlinkやcontentを子アイテムとして抽出するためのルールです。他に「std/rss」や「std/rdf」もあります。&lt;br /&gt;これらのルールでフィードから項目を抽出する際には、アクセス解析用の中継URLをリダイレクト先のURLに置換したり広告項目を除去する機能などが自動的に適用されるようになっています。&lt;br /&gt;「childContentBodyPattern:true」は、content要素を無視してlinkが示すWebページから対応するルールで抽出した本文を本文として使用することを示しています。&lt;br /&gt;これは、フィードに含まれている本文が途中で終って「続きを読む」のリンクになっている場合に本当の本文を保存させるためなどに使用します。&lt;br /&gt;「replace:['NoTracker']」は、フィードのsummary要素に仕込まれているアクセス解析用の不可視の画像を取り除く処理を定義しています。replaceの詳細については後で説明します。&lt;br /&gt;このようなフィード用定義は、urlPatternとinheritの値以外はほとんど使い回せるので、コピペ・改編して利用するといいでしょう。&lt;br /&gt;&lt;br /&gt;「article」ルールでは、記事のページから本文を抽出するルールを定義しています。&lt;br /&gt;ここでは、「contentPattern」に指定された正規表現に従って、ページのHTMLから本文の部分が抽出されます。この時、正規表現中に「()」が使われている場合は、最初の括弧にマッチした部分が抜き出し結果となり、括弧がない場合はマッチ範囲全体が使われます。これは、前後の部分を目印に使いつつ、抜き出し結果には含めたくない場合などのための仕様です。途中に「(p|div)」のような括弧を使ったパターンを含めたい場合は、「(?:p|div)」のように、キャプチャ無し括弧を使ってください。&lt;br /&gt;上記の例のように、コンテキストマッチング型広告サービスを利用しているサイトでは、本文の範囲を認識させるために埋め込まれたコメントタグを利用するのが手っ取り早いでしょう。&lt;br /&gt;&lt;br /&gt;正規表現で抜き出しパターンを指定する際に特に注意すべきなのは「.」は改行にマッチしないということです。改行を含むあらゆる文字列にマッチさせるためには「[\s\S]」などと指定しなければなりません。&lt;br /&gt;また、量指定子「*」や「+」は、そのままでは「貪欲」にマッチングを行うため、[\s\S]と組み合わせて使用する場合は、「?」を付けて「無欲」にする必要があります。&lt;br /&gt;これを忘れて「&amp;lt;h1&amp;gt;aaa&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;AAAA&amp;lt;/p&amp;gt;&amp;lt;h1&amp;gt;bbb&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;BBBB&amp;lt;/p&amp;gt;」のようなHTMLに対して「/&amp;lt;h1&amp;gt;.*&amp;lt;\/h1&amp;gt;/i」のようなマッチングを行うと、「&amp;lt;h1&amp;gt;aaa&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;AAAA&amp;lt;/p&amp;gt;&amp;lt;h1&amp;gt;bbb&amp;lt;/h1&amp;gt;」までが一致してしまったりします。&lt;br /&gt;今回のcontentPatternの場合、終了タグが1回しか出現しないので貪欲でも問題はありませんが、無欲の方が余計な検索が行われず高速に動作するはずです。&lt;br /&gt;&lt;br /&gt;「sectionLinkPattern」では、本文が複数のページに分かれているときに、以降のページにリンクしている部分を抽出・結合するためのパターンを指定します。&lt;br /&gt;また、この例では登場しませんが、ページのタイトルをtitleタグ以外から抽出したい場合に指定する「titlePattern」や、ページの概要を抽出する「summaryPattern」などもあります。&lt;br /&gt;&lt;br /&gt;これらの抜き出しパターンでは、正規表現以外にもいくつかの抽出方法が指定できます。&lt;br /&gt;HTMLの要素に付けられたid属性で抽出するには、「contentPattern:['#contentBody']」のように指定します。&lt;br /&gt;「contentPattern:function(html){/*何らかの処理*/;return(content);}」のように、HTML文字列を引数に受取り抜き出した文字列を返す関数を指定することも可能です。&lt;br /&gt;他にもいくつかの方法がありますが、この3つを覚えておけばほとんどの状況には対応できるでしょう。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;HTMLからの記事一覧の抽出&lt;/h4&gt;RSSフィードなどを配信していないサイトで、記事一覧のページから記事を抽出したい場合は、「childContentPattern」を使用します。&lt;br /&gt;以下は、「vector」プラグインで定義されているカテゴリ別ソフト一覧のページの定義例です。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;        soft_category:{&lt;br /&gt;            urlPattern:/^http:\/\/www\.vector\.co\.jp\/vpack\/filearea\/(?:win|mac)\/.*$/i,&lt;br /&gt;            childContentPattern:/(&amp;lt;LI&amp;gt;\s*&amp;lt;A HREF=&amp;quot;[^&amp;quot;&amp;gt;]*\/se\d+\.html&amp;quot;&amp;gt;[^&amp;lt;]*&amp;lt;\/A&amp;gt;\s*&amp;lt;IMG[^&amp;gt;]*&amp;gt;[\s\S]*?&amp;lt;BR&amp;gt;[\s\S]*?&amp;lt;\/LI&amp;gt;)/ig,&lt;br /&gt;            childContentTitlePattern:/&amp;lt;a href=&amp;quot;[^&amp;quot;&amp;gt;]*\/se\d+\.html&amp;quot;&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/i,&lt;br /&gt;            childContentInternalLinkPattern:/(&amp;lt;a href=&amp;quot;[^&amp;quot;&amp;gt;]*\/se\d+\.html&amp;quot;&amp;gt;.*?&amp;lt;\/a&amp;gt;)/i,&lt;br /&gt;            childContentSummaryPattern:/&amp;lt;\/A&amp;gt;([\s\S]*?)&amp;lt;\/LI&amp;gt;/i,&lt;br /&gt;            childContentBodyPattern:true,&lt;br /&gt;            &lt;br /&gt;            sectionLinkPattern:/&amp;lt;div class=&amp;quot;pagenav&amp;quot;&amp;gt;([\s\S]*?)&amp;lt;\/div&amp;gt;/i,&lt;br /&gt;            replace:[&lt;br /&gt;                'NoImageLink',&lt;br /&gt;                [/&amp;lt;img\b[^&amp;gt;]*alt=&amp;quot;([^&amp;quot;&amp;gt;]*)&amp;quot;[^&amp;gt;]*&amp;gt;([\s\S]*?)&amp;lt;br[^&amp;gt;]*&amp;gt;/ig,'[$1] $2'],&lt;br /&gt;            ],&lt;br /&gt;        },&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;まず、「childContentPattern」で各子アイテムのHTMLを抜き出します。&lt;br /&gt;「childContentTitlePattern」、「childContentInternalLinkPattern」、「childContentSummaryPattern」は、抜き出した子アイテムのHTMLからタイトル、ページ本体へのリンク、概要を抜き出す定義です。&lt;br /&gt;一覧の項目に本文が丸ごと含まれている場合は、「childContentBodyPattern」で本文の抜き出し定義を指定しますが、この例では本文はリンク先のページから抜き出す必要があるため、「childContentBodyPattern:true」を指定しています。&lt;br /&gt;また、複数ページに分かれた一覧を全て取り出すため、「sectionLinkPattern」も指定しています。&lt;br /&gt;std/atomなどのルールも、このようにして定義されています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;replaceによる置換ルール&lt;/h4&gt;contentPatternなどで抜き出した範囲に広告やブログパーツなどの不要部分が含まれてしまう場合は、「replace」に置換ルールの配列を記述して削除などを行います。&lt;br /&gt;配列の要素として単なる正規表現を指定すると、その正規表現に一致する箇所が空文字列に置換されて削除されます。この時、全ての出現箇所を削除するには、正規表現に「g」オプションを付ける必要があることに注意してください。&lt;br /&gt;削除ではなく別の内容に置換したい場合には、「[/&amp;lt;b&amp;gt;([\s\S]*?)&amp;lt;\/b&amp;gt;/ig,'$1']」のように、正規表現と置換文字列の2要素からなる配列を指定します。第2要素には、文字列のreplace()メソッドの第2引数と同じように、関数を指定することも可能です。&lt;br /&gt;よく使われる置換ルールは、「HTMLRewriter」という機能のプラグインで定義されており、ルール名を単に文字列として指定するだけで使用できます。&lt;br /&gt;標準で用意されている置換ルールの一覧と説明は、「plugins\HTMLRewriter\Cleanup\Cleanup.ng」内に書かれています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;画像の保存&lt;/h4&gt;contentPatternなどで抽出された本文にimgタグで埋め込まれている画像は、抽出時に自動的に保存されますが、aタグでリンクされているだけの画像は、そのままでは保存されません。&lt;br /&gt;画像が保存されるようにするには、以下のようにして明示的にダウンロードすべきコンテンツのURLであることを指定します。&lt;br /&gt;&lt;pre&gt;        image:{&lt;br /&gt;            urlPattern:/^http:\/\/blog-imgs-\d+-origin\.fc2\.com\/.*\.(?:jpe?g|png|gif|bmp)$/i,&lt;br /&gt;            download:true,&lt;br /&gt;        },&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;本文からリンクされているのが画像ファイル本体でなく画像を表示するためのHTMLである場合には、URLの変換定義を用意することで、画像本体のみを保存し直接リンクさせられます。&lt;br /&gt;URLの変換定義の方式には、「urlRewrite」と「urlRedirect」の2つがあります。&lt;br /&gt;単なるURLの正規表現置換で画像本体のURLが得られ、HTMLにアクセスしていなくても画像に直接アクセス出来る場合は、以下のように「urlRewrite」で置換文字列を指定します。置換後のURLを保存させるための定義も別途必要であることに注意してください。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;        image_html:{&lt;br /&gt;            urlPattern:/^(http:\/\/japan\.cnet\.com\/)image\/l\/(.*\.(?:jpg|jpeg|png|gif|bmp))$/i,&lt;br /&gt;            urlRewrite:&amp;quot;$1$2&amp;quot;,&lt;br /&gt;        },&lt;br /&gt;        image:{&lt;br /&gt;            urlPattern:/^http:\/\/japan\.cnet\.com\/(?:story_image|image|storage)\/.*\.(jpg|jpeg|png|gif|bmp)$/i,&lt;br /&gt;            download:true,&lt;br /&gt;        },&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;HTMLのURLから画像本体のURLが定まらない場合や、HTMLにアクセスしてCookieの取得などを行わないと画像本体へのアクセスが出来ない場合などは、以下のように「urlRedirect」に、HTML内から画像本体のURLが含まれる部分を抽出する定義を記述します。この定義で抜き出された範囲に最初に出現するhref=やsrc=のリンク先URLが、変換後のURLとなります。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;        softnews_ss:{&lt;br /&gt;            urlPattern:/^http:\/\/www\.vector\.co\.jp\/magazine\/softnews\/\d+\/n\d+_pic\.html$/i,&lt;br /&gt;            urlRedirect:/&amp;lt;td [^&amp;gt;]*&amp;gt;\s*&amp;lt;a href=&amp;quot;[^&amp;quot;&amp;gt;]*&amp;quot;&amp;gt;(&amp;lt;img [^&amp;gt;]*&amp;gt;)&amp;lt;\/a&amp;gt;/i,&lt;br /&gt;        },&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;また、フィードから抜き出されたURLに「?ref=rss」のようなゴミがくっついている場合なども、urlRewriteによるURLの置換を定義しておくと良いでしょう。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ContentExtractorのルール定義の主要部分の説明は以上です。&lt;br /&gt;まだ説明されていない機能やテクニックもいくつかあるので、「doc\ContentExtractor.txt」の説明や、「plugins\ContentExtractor\」内の標準プラグイン内の実際の定義なども参照してみてください。&lt;br /&gt;&lt;br /&gt;出来上がったプラグインを配布したい場合は、ZIPで圧縮してアップロードするなどしてください。そのうち、プラグインの配布や入手、アップデートなどを行う機能も実装される予定です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2397333495650212280?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2397333495650212280/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/02/contentextractor.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2397333495650212280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2397333495650212280'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/02/contentextractor.html' title='ContentExtractorのプラグインの仕様'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8779168374519459694</id><published>2011-02-17T03:33:00.000+09:00</published><updated>2011-02-17T03:33:27.491+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP'/><title type='text'>HTTPオブジェクトのCookieを保存しておいて次回実行時に読み込む</title><content type='html'>HTTPオブジェクトでCookieを扱う際、受取ったCookieをファイルに保存しておいて、次にスクリプトを実行したときに読み込んで利用したい場合があるかも知れません。&lt;br /&gt;このような場合は、HTTPオブジェクトのコンストラクタの引数に以下のようなオプションオブジェクトを指定してください。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;try{&lt;br /&gt;    var http=new (require('HTTP').HTTP)({&lt;br /&gt;        cookies:Main.scriptDirectory.file('cookies.json'),&lt;br /&gt;        saveCookies:true&lt;br /&gt;    });&lt;br /&gt;    //何らかの処理&lt;br /&gt;}finally{&lt;br /&gt; free(http);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;オプションオブジェクトの「cookies」メンバにファイルパスやFileオブジェクトを指定すると、そのファイルからCookieが読み込まれます。この時、ファイルが存在しなくてもエラーになったりはせず、単に何も読み込まずに初期化されます。&lt;br /&gt;また、cookiesに加えて「saveCookies:true」を指定すれば、オブジェクトをfree()で解放する際に、cookiesで指定したファイルにCookieが保存されます。&lt;br /&gt;ファイルから読み込まずに保存だけを行いたい場合は、cookiesを指定せずにsaveCookiesにファイルパスやFileオブジェクトを指定します。&lt;br /&gt;&lt;br /&gt;このCookie保存機能では、ブラウザを閉じると破棄されてしまうセッションCookieも保存できます。これにより、ブラウザをずっと開いたままにしているように装うことも可能となります。&lt;br /&gt;オプションオブジェクトに「discardSessionCookies:true」を指定することで、セッションCookieは保存せず破棄させることも可能です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8779168374519459694?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8779168374519459694/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/02/httpcookie_17.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8779168374519459694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8779168374519459694'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/02/httpcookie_17.html' title='HTTPオブジェクトのCookieを保存しておいて次回実行時に読み込む'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-4540968128518540021</id><published>2011-02-16T00:12:00.001+09:00</published><updated>2011-02-16T12:43:15.203+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP'/><title type='text'>HTTPオブジェクトで受信したCookieを使用したアクセスを行う</title><content type='html'>会員制のサイトなどのコンテンツにアクセスするには、IDとパスワードを入力してログインしなければならない場合があります。&lt;br /&gt;このようなサイトでは、サーバが正しいログイン情報を受取った時にユーザーを識別するセッションIDを生成して「Set-Cookie」というレスポンスヘッダで送信し、それを受取ったブラウザなどのクライアントプログラムが次回以降のアクセス時に「Cookie」というリクエストヘッダでセッションIDを送信することで認証済みであることを証明するという方式がよく用いられています。&lt;br /&gt;&lt;br /&gt;NILScriptのHTTPオブジェクトには、受取ったCookieを保持して次回アクセス時に送信するという機能が用意されており、このような認証が必要なサイトのコンテンツにも簡単にアクセス出来ます。&lt;br /&gt;以下に示すのは、mixiにログインして指定コミュニティのトップページのテキストを抽出・表示するというスクリプト例です。&lt;br /&gt;&lt;pre&gt;var user="user@example.com",pass="password";&lt;br /&gt;var url="https://mixi.jp/view_community.pl?id=38328";&lt;br /&gt;try{&lt;br /&gt;    var http=new (require('HTTP').HTTP)();&lt;br /&gt;    http.getText({&lt;br /&gt;        url:"https://mixi.jp/login.pl",&lt;br /&gt;        method:"post",&lt;br /&gt;        body:{&lt;br /&gt;            next_url:"/home.pl",&lt;br /&gt;            email:user,&lt;br /&gt;            password:pass,&lt;br /&gt;            sticky:"",&lt;br /&gt;        }&lt;br /&gt;    });&lt;br /&gt;    println(String((new (require('LooseXML').HTML)(http.getText(url)))&lt;br /&gt;    .$0('#communityIntro')).replace(/&lt;br[^&gt;]*&gt;/ig,'\n').replace(/&lt;.*?&gt;/ig,''));&lt;br /&gt;}finally{&lt;br /&gt;    free(http);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;HTTPクラスには「HTTP.getText()」のようなクラスメソッドが用意されていますが、Cookieを用いたアクセスを行うには、new HTTP()でインスタンスを生成する必要があります。&lt;br /&gt;次に、このHTTPオブジェクトのgetText()メソッドでログイン情報を送信します。送信先URLとパラメータ名などは、ログインフォームのHTMLなどから探してください。&lt;br /&gt;&lt;br /&gt;ログインに成功すれば、このHTTPオブジェクトにCookieが保存されます。&lt;br /&gt;なお、リクエストオプションオブジェクトで「ignoreCookies:true」を指定すれば、受取ったCookieを無視させることも出来ます。&lt;br /&gt;以降は、普通にこのHTTPオブジェクトのgetText()メソッドやsaveTo()メソッドを呼び出せば、アクセス先サーバから過去に受取って保存されたCookieが送信され、ログイン済みでないとアクセス出来ないコンテンツなどにもアクセス出来ます。&lt;br /&gt;&lt;br /&gt;HTTPオブジェクトには次回アクセス時に再利用するためにKeep-Alive状態になっているTCPStreamオブジェクトなども保持されているので、使い終ったらfree(http)のようにして解放する必要があります。&lt;br /&gt;&lt;br /&gt;なお、この機能はずっと実装するのを忘れたまま放置されていて、つい最近実装されました。使用するには、最新版にアップデートしてください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-4540968128518540021?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/4540968128518540021/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/02/httpcookie.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4540968128518540021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4540968128518540021'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/02/httpcookie.html' title='HTTPオブジェクトで受信したCookieを使用したアクセスを行う'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-253651851583269697</id><published>2011-02-08T22:28:00.000+09:00</published><updated>2011-02-08T22:28:31.064+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Notebook'/><title type='text'>NotebookのScan機能でサイト上の全ページを保存</title><content type='html'>NILScriptに同梱されている「Notebook.ng」では、手動でページを保存したり自動巡回で新着ページを保存するだけでなく、リンクを辿ってサイト上のページを全て保存させることも可能です。&lt;br /&gt;この機能を利用するには、リンクを辿る基点にしたいページでブックマークレットの「ScanForm」を実行するか、サイドバーの「Scan from Website」からURL未入力のフォームに進んでください。&lt;br /&gt;すると、以下のような画面で使用するプラグインの選択などを行なえます。&lt;br /&gt;巡回登録の場合と同様に、説明を参考に使用するプラグインを選択してください。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFEk0LTW9I/AAAAAAAAAEE/k8G3ZuZ5xM4/s1600/notebook_0013.png" imageanchor="1" style=""&gt;&lt;img border="0" height="274" width="320" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFEk0LTW9I/AAAAAAAAAEE/k8G3ZuZ5xM4/s320/notebook_0013.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;「Start」ボタンを押すと、以下のような画面で進捗状況が表示されます。サイトの規模によってはかなりの時間がかかるので注意してください。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_wiFD7NiUNAg/TVFElDAYB2I/AAAAAAAAAEM/l8X2w2jAx_U/s1600/notebook_0014.png" imageanchor="1" style=""&gt;&lt;img border="0" height="208" width="320" src="http://4.bp.blogspot.com/_wiFD7NiUNAg/TVFElDAYB2I/AAAAAAAAAEM/l8X2w2jAx_U/s320/notebook_0014.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-253651851583269697?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/253651851583269697/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/02/notebookscan.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/253651851583269697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/253651851583269697'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/02/notebookscan.html' title='NotebookのScan機能でサイト上の全ページを保存'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFEk0LTW9I/AAAAAAAAAEE/k8G3ZuZ5xM4/s72-c/notebook_0013.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2723654440701824850</id><published>2011-02-08T22:22:00.000+09:00</published><updated>2011-02-08T22:22:59.406+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Notebook'/><title type='text'>Notebook.ngの巡回機能でWebページの更新チェック</title><content type='html'>NILScriptに同梱の「Notebook.ng」に用意された巡回機能では、RSSリーダーのように新着記事を収集するだけでなく、特定のWebページの内容の変化をチェックすることも可能です。&lt;br /&gt;この機能を利用するには、巡回ルールを「blog/body」や「std/htmlBody」などにして巡回登録してください。&lt;br /&gt;これらのルールでは、子アイテムの抽出は行われませんが、対象URL自体の内容が抽出され、変化があれば保存されます。更新が検出されたページは、Notebookのメイン画面の一覧の上位に表示されます。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFChSkZ2wI/AAAAAAAAADs/rbeqjcaAPC8/s1600/notebook_0015.png" imageanchor="1" style=""&gt;&lt;img border="0" height="228" width="320" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFChSkZ2wI/AAAAAAAAADs/rbeqjcaAPC8/s320/notebook_0015.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;ページに更新があると、Notebookのメイン画面の新着ページ一覧の上位に表示されます。この時、一覧項目の下部の「rev.」の部分の番号が更新され、リンクとしてクリックできるようになります。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFCmeQ1n1I/AAAAAAAAAD0/XBQvCZc-Ef4/s1600/notebook_0016.png" imageanchor="1" style=""&gt;&lt;img border="0" height="208" width="320" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFCmeQ1n1I/AAAAAAAAAD0/XBQvCZc-Ef4/s320/notebook_0016.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;リビジョンの部分のリンクをクリックすると、このような画面で前のリビジョンとの差分が表示されます。&lt;br /&gt;色の薄い部分が変化の無かった部分、赤みがかった文字色で打ち消し線が引かれているのは削除された箇所、普通の文字の部分が新たに追加された部分です。(追加された文章を読みやすいように、新着部分が普通の配色になっています。)&lt;br /&gt;更に、サイドバーの「This Page」にある「History」のリンクからは、過去のリビジョン一覧や各リビジョンの内容、任意のリビジョン間の差分なども表示できます。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_wiFD7NiUNAg/TVFC4-qlWYI/AAAAAAAAAD8/E1QUEdGOR3Y/s1600/notebook_0017.png" imageanchor="1" style=""&gt;&lt;img border="0" height="208" width="320" src="http://4.bp.blogspot.com/_wiFD7NiUNAg/TVFC4-qlWYI/AAAAAAAAAD8/E1QUEdGOR3Y/s320/notebook_0017.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;この機能を利用すれば、RSSなどの配信が行われておらず、対応するContentExtractorルールも用意されていないページも、他のサイトと一緒に更新チェックを行なえるでしょう。&lt;br /&gt;&lt;br /&gt;なお、この機能で利用されている差分検出の処理は「Diff」というユニットで定義されています。&lt;br /&gt;自作のスクリプトで差分処理を利用したい場合は、「doc」ディレクトリ内の「Diff.txt」の説明を参照してください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2723654440701824850?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2723654440701824850/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/02/notebookngweb.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2723654440701824850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2723654440701824850'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/02/notebookngweb.html' title='Notebook.ngの巡回機能でWebページの更新チェック'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFChSkZ2wI/AAAAAAAAADs/rbeqjcaAPC8/s72-c/notebook_0015.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2918383035338908125</id><published>2011-02-08T22:17:00.000+09:00</published><updated>2011-02-08T22:17:13.035+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Notebook'/><title type='text'>Notebook.ngの巡回機能でブログなどの新着記事を自動収集</title><content type='html'>NILScriptに同梱されている「Notebook.ng」には、ブログなどの新着記事を自動収集する巡回機能が用意されています。&lt;br /&gt;プラグインで定義したルールに従ってページの本文などを抜き出す「ContentExtractor」機能により、必要な部分だけを保存して、快適に読み進めることが可能です。&lt;br /&gt;&lt;br /&gt;Notebookに巡回対象サイトを登録するには、巡回したいサイト上で「AddCrawl」ブックマークレットを実行してください。&lt;br /&gt;すると、以下のような新規巡回項目設定画面が表示されます。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_wiFD7NiUNAg/TVFBVRk0kII/AAAAAAAAADc/wP2Do9iKfe8/s1600/notebook_0009.png" imageanchor="1" style=""&gt;&lt;img border="0" height="320" width="308" src="http://1.bp.blogspot.com/_wiFD7NiUNAg/TVFBVRk0kII/AAAAAAAAADc/wP2Do9iKfe8/s320/notebook_0009.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;登録対象ページにRSSやAtomのフィードが用意されている場合は、URL欄の下に「rss feed」などとしてリンクが表示されます。このリンクをクリックすれば、フィードURLを対象とした巡回登録画面に移行します。&lt;br /&gt;&lt;br /&gt;その下には、インストールされているContentExtractorプラグインとルールの一覧が表示されます。対応URL認識機能によって対応しているとみなされたルールがあると、リストの上位に表示されます。ルール名の下の説明に従って、使用したいルールを選択してください。&lt;br /&gt;&lt;br /&gt;ルール名の横の「Test」のリンクからは、そのルールを使用した場合の抽出結果のプレビュー画面に進めます。「blog/rss」などの汎用的なルールを使用する場合は、上手く抽出できるか確認してから登録すると良いでしょう。&lt;br /&gt;&lt;br /&gt;Options以下の部分では、高度な巡回オプションを指定できます。一般的なRSS系のルールの場合は、そのままでも問題ありません&lt;br /&gt;&lt;br /&gt;「Filters」では、子アイテムに対して除外や改変などのフィルタリングを行うルールを定義できます。この機能はまだ仮のものなので、準備が整い次第別途説明します。&lt;br /&gt;&lt;br /&gt;「Interval」は巡回間隔です。たまにしか更新されないページでは大きめの値にすることで、他の巡回をスムーズに出来る場合があります。&lt;br /&gt;&lt;br /&gt;「Content Update Check」では、子アイテムごとの更新チェックを行うかどうかと、更新チェック時にHTMLタグ部分を無視するかどうかを指定できます。追記などがほとんどないサイトでは「No」のままでよいでしょう。画像URLのみの更新なども検出したい場合は「Including HTML Tags」を、テキストの更新のみを検出したい場合は「Without Tags」を指定します。&lt;br /&gt;&lt;br /&gt;「Children Order」では子アイテムの並び順を指定できます。「No」を指定すると、常に全ての子アイテムがチェックされますが、記事が更新日時順に並んでいることが分かっているサイトでは、適切なオプションを指定する事で、処理を高速化させられます。&lt;br /&gt;&lt;br /&gt;「Depth」は、列挙された子ページを更に巡回登録するかどうかのオプションです。子ページの巡回オプションは、その下の「Options for Children」などで指定します。これらは、掲示板のスレッド一覧などを巡回するための機能です。説明部分に「"Depth"を"Crawl Children"にすることで――」のような記載があるルール以外では、設定してもあまり意味がないので「Crawl this URL only」のままにしておいてください。&lt;br /&gt;&lt;br /&gt;フォームの一番下の「Save」ボタンを押せば、巡回設定が登録されます。登録された巡回項目の設定変更や削除などは、サイドバーの「All Crawls」で表示される一覧から行なえます。&lt;br /&gt;&lt;br /&gt;サイドバーの「Crawl: Disabled」となっている部分の右の「Start」をクリックして「Crawl: Enabled」にしておくと、定期的に巡回が実行されます。収集されたページは、Notebookのメイン画面の最近更新されたページ一覧などで閲覧可能です。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFBbDw-FHI/AAAAAAAAADk/lFgGjfDNdbE/s1600/notebook_0010.png" imageanchor="1" style=""&gt;&lt;img border="0" height="228" width="320" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVFBbDw-FHI/AAAAAAAAADk/lFgGjfDNdbE/s320/notebook_0010.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2918383035338908125?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2918383035338908125/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/02/notebookng.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2918383035338908125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2918383035338908125'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/02/notebookng.html' title='Notebook.ngの巡回機能でブログなどの新着記事を自動収集'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_wiFD7NiUNAg/TVFBVRk0kII/AAAAAAAAADc/wP2Do9iKfe8/s72-c/notebook_0009.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2706042187899463999</id><published>2011-02-08T22:10:00.000+09:00</published><updated>2011-02-08T22:10:24.876+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Notebook'/><title type='text'>Webページなどを保存して閲覧・検索できる「Notebook.ng」</title><content type='html'>NILScriptの最近のバージョンから同梱されるようになった「Notebook.ng」は、Webページなどを保存して閲覧・検索できるスクリプトです。&lt;br /&gt;ページの追加はブックマークレットなどから手動で行う他、RSSなどを巡回登録して自動で新着記事を取り込むことも可能です。&lt;br /&gt;NILScriptにはWebページからの本文抽出処理をプラグイン方式で定義できる「ContentExtractor」機構が用意されており、ブログのサイドバーなどの不要部分を除いた本文だけを保存して快適に閲覧できます。更に、検索時にサイドバーのカテゴリ一覧などにマッチして関係のないページがヒットしてしまうという問題も避けられます。&lt;br /&gt;&lt;br /&gt;NILScriptは元々このスクリプトを実装することを第一目標として開発を始めたものですが、ようやく主要な機能を実装し仕様も固まってきたので、そろそろ使い方の説明をしたいと思います。&lt;br /&gt;&lt;br /&gt;Notebook.ngを使用するには、Notebook.ngをng.exeかngw.exeで実行します。スタートアップなどへの登録は手動で行ってください。&lt;br /&gt;最初に実行すると、データの保存先などを設定するページがブラウザで開かれます。ここでData Directoryに「Portable」を指定すれば、NILScriptのディレクトリをUSBメモリなどで持ち出して複数のPCで利用することも可能です。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_wiFD7NiUNAg/TVE_sg3i4QI/AAAAAAAAACs/eWRdyp9cisw/s1600/notebook_0001.png" imageanchor="1" style=""&gt;&lt;img border="0" height="218" width="320" src="http://4.bp.blogspot.com/_wiFD7NiUNAg/TVE_sg3i4QI/AAAAAAAAACs/eWRdyp9cisw/s320/notebook_0001.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;初期設定を行うと、以下のようなメイン画面が表示されます。このURLをブラウザのブックマークなどに登録しておいてください。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_wiFD7NiUNAg/TVE_s6lhfZI/AAAAAAAAAC0/qlp7goYP3K8/s1600/notebook_0002.png" imageanchor="1" style=""&gt;&lt;img border="0" height="218" width="320" src="http://4.bp.blogspot.com/_wiFD7NiUNAg/TVE_s6lhfZI/AAAAAAAAAC0/qlp7goYP3K8/s320/notebook_0002.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;次に、サイドバーの「Bookmarklets」のリンクからブックマークレット一覧のページに行き、使用したいブックマークレットをブラウザのブックマークに登録します。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVE_sxfrleI/AAAAAAAAAC8/CF8trILchoY/s1600/notebook_0003.png" imageanchor="1" style=""&gt;&lt;img border="0" height="218" width="320" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVE_sxfrleI/AAAAAAAAAC8/CF8trILchoY/s320/notebook_0003.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;基本的なページの保存を行うには、「Scrap」ブックマークレットを使用します。保存したいページを表示した状態で登録したブックマークレットを開くと、範囲選択を行っている場合は選択範囲の内容が、そうでない場合はサイドバーなどの不要部分を自動的に取り除いた部分が、Notebookに新規項目として保存されます。この際、ページに埋め込まれている画像も保存されるため、ページがサーバから削除されてしまっても、支障なく閲覧できます。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_wiFD7NiUNAg/TVFAXCIrPSI/AAAAAAAAADU/EwHQa9a2i78/s1600/notebook_0004.png" imageanchor="1" style=""&gt;&lt;img border="0" height="274" width="320" src="http://3.bp.blogspot.com/_wiFD7NiUNAg/TVFAXCIrPSI/AAAAAAAAADU/EwHQa9a2i78/s320/notebook_0004.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ページの保存が行われると、以下のように保存されたページが表示されます。&lt;br /&gt;ここでは、左のサイドバーから「タグ」としてキーワードを関連付けたり、ページの重要度を表す「スコア」を変更したりできます。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_wiFD7NiUNAg/TVE_tY8WXLI/AAAAAAAAADE/lNzukygsVkw/s1600/notebook_0006.png" imageanchor="1" style=""&gt;&lt;img border="0" height="247" width="320" src="http://3.bp.blogspot.com/_wiFD7NiUNAg/TVE_tY8WXLI/AAAAAAAAADE/lNzukygsVkw/s320/notebook_0006.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;サイドバーの検索ボックスに検索ワードを入力すれば、該当するページを検索できます。キーワードの前に「:」を付けると、タグのみを検索対象に出来ます。スペースや「:」を含む語句を検索したい場合は「""」で囲んでください。他のもいくつか検索オプション構文が用意されていますが、詳しくは同梱の「doc\Notebook.txt」を参照してください。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVE_tWKJThI/AAAAAAAAADM/-aprHfTAaJo/s1600/notebook_0007.png" imageanchor="1" style=""&gt;&lt;img border="0" height="247" width="320" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TVE_tWKJThI/AAAAAAAAADM/-aprHfTAaJo/s320/notebook_0007.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;なお、Notebook.ngはまだテスト段階のため、不具合や不便な点が残っていると思われます。見つけた場合は、BBSやTwitterなどでお知らせください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2706042187899463999?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2706042187899463999/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/02/webnotebookng.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2706042187899463999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2706042187899463999'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/02/webnotebookng.html' title='Webページなどを保存して閲覧・検索できる「Notebook.ng」'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_wiFD7NiUNAg/TVE_sg3i4QI/AAAAAAAAACs/eWRdyp9cisw/s72-c/notebook_0001.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-834520646459512209</id><published>2011-01-25T21:24:00.002+09:00</published><updated>2011-01-27T07:39:04.211+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>IDLファイルからCOMオブジェクト定義を生成して使用する</title><content type='html'>WindowsがAPIとして用意している機能の中には、COMオブジェクトの形で提供されている物があります。&lt;br /&gt;これらのCOMオブジェクトを利用するために、NILScriptにはCOMユニットが用意されています。&lt;br /&gt;以前のバージョンでは、メソッドの定義を全て自力で記述しなければならないので面倒でしたが、最近の更新で定義を自動化するスクリプトが同梱されるようになったので、手軽に利用できるようになっています&lt;br /&gt;ここでは、COMを利用した処理を行うスクリプトを記述する手順を説明します。&lt;br /&gt;&lt;br /&gt;まず、あらかじめWindows SDKをMicrosoftのサイトから入手してインストールしておいてください。&lt;br /&gt;そして、利用したいAPIがCOMオブジェクトとして提供されていることが分かったら、&lt;br /&gt;「C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include\」などのディレクトリ内のファイルを全文検索するなどして、どのIDLファイルで定義されているかを調べます。&lt;br /&gt;&lt;br /&gt;次に、コマンドプロンプトで以下のようなコマンドラインを実行してください。&lt;br /&gt;&lt;pre&gt;ng tool/idlConv "C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include\shobjidl.idl" &amp;gt; shobjidl.ng&lt;br /&gt;&lt;/pre&gt;すると、IDLファイル内の定義文を元に、以下のようなクラス定義が列挙されたスクリプトが生成されます。&lt;br /&gt;&lt;pre&gt;var PersistFile=Persist.define(&amp;quot;PersistFile&amp;quot;,&amp;quot;{0000010B-0000-0000-C000-000000000046}&amp;quot;,{&lt;br /&gt;    IsDirty:[],&lt;br /&gt;    Load:[&lt;br /&gt;        WideString,        // [in] LPCOLESTR pszFileName&lt;br /&gt;        UInt,              // [in] DWORD dwMode&lt;br /&gt;    ],&lt;br /&gt;    Save:[&lt;br /&gt;        WideString,        // [in, unique] LPCOLESTR pszFileName&lt;br /&gt;        Int,               // [in] BOOL fRemember&lt;br /&gt;    ],&lt;br /&gt;    SaveCompleted:[&lt;br /&gt;        WideString,        // [in, unique] LPCOLESTR pszFileName&lt;br /&gt;    ],&lt;br /&gt;    GetCurFile:[&lt;br /&gt;        Pointer,          // [out] LPOLESTR *ppszFileName&lt;br /&gt;    ]&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;IDLファイルには多くの定義が含まれるので、必要な定義だけを探して自分のスクリプトにコピーしてください。&lt;br /&gt;この時、「.define」の前の派生元クラスの部分が「Unknown」以外になっている場合は、その派生元クラスの定義も見つけてきて派生先クラスの定義より前の部分に記述しておく必要があります。&lt;br /&gt;また、大元の派生元クラスとなる「Unknown」はCOMユニットで定義されているので、以下のような行を一番最初に記述してインポートしておきます。&lt;br /&gt;&lt;pre&gt;var {COM,Unknown,BStr}=require('COM');&lt;br /&gt;&lt;/pre&gt;「COM」や「BStr」もCOMユニットで定義されているクラスで、COMを利用するスクリプトでたまに必要になることがあるので、常に記述するようにしておくといいでしょう。&lt;br /&gt;なお、idlConvによる変換は常に正しく行われるとは限らないので、必ずMSDNのリファレンスなどと照らし合わせて、正しく記述されているか確認してから利用してください。&lt;br /&gt;&lt;br /&gt;次に、COMオブジェクトを利用した処理の記述方法を説明します。&lt;br /&gt;以下は、targetPathで指定したファイルを開くショートカットファイルをlnkPathで指定したファイルに保存するという処理の例です。&lt;br /&gt;&lt;pre&gt;try{&lt;br /&gt; var link=ShellLinkW.create();&lt;br /&gt; var pf=link.toPersistFile();&lt;br /&gt; link.SetPath(targetPath);&lt;br /&gt; pf.Save(lnkPath,0);&lt;br /&gt;}finally{&lt;br /&gt; free(pf,link);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;「ShellLinkW.create()」は、C++などでの「CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(LPVOID*)&amp;link);」に相当します。&lt;br /&gt;クラスメソッド「create()」によるインスタンス生成を行うためには、idlConvで生成された定義にクラスプロパティ「classID」の定義が付加されている必要があります。もしclassIDの定義が正しく生成されていなかった場合は、各自でIDLファイルなどから「CLSID_～」の定義を探してきて追加しておいてください。&lt;br /&gt;&lt;br /&gt;「link.toPersistFile()」は、「link-&gt;QueryInterface(IID_IPersistFile, (LPVOID*)&amp;pf)」に相当します。&lt;br /&gt;このメソッドは、「PersistFile」クラスの定義を実行したときに自動的に追加されます。&lt;br /&gt;&lt;br /&gt;link.SetPath()とpf.Save()は、COMオブジェクトのメソッド呼び出しです。通常のNILScriptやJavaScriptのメソッドと違い、最初の文字も大文字になっているので注意してください。&lt;br /&gt;&lt;br /&gt;最後に、finallyブロック内で「free(pf,link)」を実行して、生成したオブジェクトを解放する必要があります。&lt;br /&gt;これは「if(pf) pf-&gt;Release();if(link) link-&gt;Release()」に相当します。&lt;br /&gt;&lt;br /&gt;このように、最初の定義が多少面倒ですが、処理本体は比較的簡潔に記述できるようになっています。&lt;br /&gt;COMオブジェクトとして提供されているAPIには様々なものがあるので、COMオブジェクトの使用方法を覚えておけば、役に立つことがあるでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-834520646459512209?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/834520646459512209/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2011/01/idlcom.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/834520646459512209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/834520646459512209'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2011/01/idlcom.html' title='IDLファイルからCOMオブジェクト定義を生成して使用する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-772797982358738462</id><published>2010-12-21T21:06:00.000+09:00</published><updated>2010-12-21T21:06:44.370+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='文字列'/><title type='text'>テキストファイルの文字コードを判別して読み込む</title><content type='html'>不特定多数のテキストファイルから検索を行ったりするスクリプトを作る場合、文字コードを正しく認識して読み込む必要があります。&lt;br /&gt;NILScriptのFileオブジェクトに用意されているload()メソッドでは、文字コードを指定するための第1引数を省略した場合、エラーにならずに読み込める文字コードを自動選択して読み込んでくれますが、誤った文字コードでも全てのバイトをデコードできる場合などは、誤認識してしまうことがあります。&lt;br /&gt;より正確な文字コード認識を行いたい場合、「Charset」というユニットを使います。&lt;br /&gt;以下のように記述すれば、Charsetユニットによる高精度な文字コード判別を行ってテキストファイルを読み込むことが出来ます。&lt;br /&gt;&lt;pre&gt;var text=require('Charset').Detector.load(someFile);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;また、以下のようにすることで、検出した文字コード名を得ることも可能です。&lt;br /&gt;&lt;pre&gt;var charset=require('Charset').Detector.detect(someFile);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;他にも、ストリームオブジェクトから読み込みを行いながら文字コードを判別する機能なども用意されています。&lt;br /&gt;&lt;br /&gt;Charsetユニットでは、IEなどで使用されているmlang.dllの機能を利用して文字コードの判別を行っています。「です」「である」などの頻出文字列の出現なども手がかりにしているらしく、通常のload()で使用している方法より正確に判別してくれます。&lt;br /&gt;&lt;br /&gt;なお、読み込まれた文字列はUnicode文字列として保持されるので、海外製の処理系にありがちな駄目文字問題に悩まされることはありません。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-772797982358738462?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/772797982358738462/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/12/blog-post_21.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/772797982358738462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/772797982358738462'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/12/blog-post_21.html' title='テキストファイルの文字コードを判別して読み込む'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-7659046296206860272</id><published>2010-12-13T00:51:00.000+09:00</published><updated>2010-12-13T00:51:35.817+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='自動化'/><title type='text'>入出力のコンソールを子プロセスと共有して進捗などを表示</title><content type='html'>NILScriptは、コマンドラインで指定された処理を行って直ちに終了するコンソールプログラムを組み合わせた自動処理の実現にも役立ちます。&lt;br /&gt;&lt;br /&gt;動画変換やダウンロードなど時間のかかる処理を行うプログラムの多くは、標準出力で進捗状況を確認できるようになっていますが、作業中にバックグラウンドで自動処理させたい場合には、子プロセスが起動するたびにコンソールウィンドウが表示されては邪魔になってしまいます。&lt;br /&gt;しかし、完全に出力を非表示にしてしまうと、残り所要時間が把握しづらく不便です。&lt;br /&gt;&lt;br /&gt;スクリプトのプロセスが所有するコンソールに子プロセスの出力を表示するようにすれば、いちいち新たなウィンドウを表示せずに進捗状況を確認できるようになって便利です。&lt;br /&gt;NILScriptのrun()やProcess.create()では、以下のようにオプションオブジェクトに「shareConsole:true」を指定する事で、子プロセスと現在のプロセスのコンソールを共有させられるので、簡単に子プロセスの出力を自分のコンソールに表示させられます。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;println("1/3")&lt;br /&gt;run('"'+app1+'" "'+file+'"',{shareConsole:true}).waitExit();&lt;br /&gt;println("2/3")&lt;br /&gt;run('"'+app2+'" "'+file+'"',{shareConsole:true}).waitExit();&lt;br /&gt;println("3/3")&lt;br /&gt;run('"'+app3+'" "'+file+'"',{shareConsole:true}).waitExit();&lt;br /&gt;println("done");&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-7659046296206860272?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/7659046296206860272/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/12/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7659046296206860272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7659046296206860272'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/12/blog-post.html' title='入出力のコンソールを子プロセスと共有して進捗などを表示'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-460835590879983513</id><published>2010-12-09T04:50:00.000+09:00</published><updated>2010-12-09T04:50:15.054+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>Webページのスクリーンショット画像を生成</title><content type='html'>Imageユニットが提供する画像処理機能には、ウィンドウの表示内容を画像として取得するcapture()メソッドなども用意されています。&lt;br /&gt;これをATLユニットで用意されているIEコンポーネントの表示機能と組み合わせれば、以下のようにしてWebページのスクリーンショットを生成することも可能です。&lt;br /&gt;&lt;pre&gt;use('Window','ATL');&lt;br /&gt;var w=OnScreenDisplay.create({&lt;br /&gt;    width:800,height:600, x:-32000,alpha:0,&lt;br /&gt;    children:{&lt;br /&gt;        ie:{&lt;br /&gt;            type:Trident,&lt;br /&gt;            top:0,bottom:0,left:0,right:0,&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}).show(true);&lt;br /&gt;w.request(function(){&lt;br /&gt;    this.ie.object.observe('DWebBrowserEvents2_DocumentComplete',function(o){&lt;br /&gt;        w.capture().save('webpage.png');&lt;br /&gt;        w.close();&lt;br /&gt;    });&lt;br /&gt;    this.ie.object.navigate("http://lukewarm.s151.xrea.com/nilscript.html");&lt;br /&gt;});&lt;br /&gt;w.wait('destroy');&lt;br /&gt;&lt;/pre&gt;配下にIEコンポーネントを配置したOnScreenDisplayを生成し表示させた後、ウィンドウのスクリーンショットを保存しウィンドウを閉じるというイベントハンドラを、IEコンポーネントのCOMオブジェクトの読み込み完了イベントに割り当て、キャプチャしたいページのURLにnavigate()しています。&lt;br /&gt;&lt;br /&gt;OnScreenDisplayは、Windowクラスを継承して定義されているクラスで、タイトルバーや枠などを持たず、タスクバーにも表示されず、クリックが背後のウィンドウに透過する情報表示向けのウィンドウです。&lt;br /&gt;これをx:-32000という絶対に画面に表示されない位置に表示させることで、一切画面に表示されることなくキャプチャを実行させられます。&lt;br /&gt;通常のウィンドウは、描画先としてデスクトップのデバイスコンテキストを使用しているため、実際に表示されていない部分は真っ黒になってしまいますが、alphaオプションで半透明にしたウィンドウは独自のデバイスコンテキストを持つため、画面外にあってもキャプチャ可能になります。&lt;br /&gt;半透明にしておけば画面外に出す必要は無い気がしますが、表示される瞬間に一瞬だけちらつきが見えてしまうので、x:-32000は有った方がいいでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-460835590879983513?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/460835590879983513/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/12/web.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/460835590879983513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/460835590879983513'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/12/web.html' title='Webページのスクリーンショット画像を生成'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-7429647446870225045</id><published>2010-12-09T04:06:00.000+09:00</published><updated>2010-12-09T04:06:48.952+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTPD'/><title type='text'>任意のWebページをIEコンポーネントに読み込ませて処理する</title><content type='html'>NILScriptのCOMユニットやATLユニットを使えば、IEコンポーネントでWebページを表示し、様々な操作を行うことも可能です。&lt;br /&gt;しかし、NILScript上のCOMオブジェクトは明示的にfree()メソッドを呼び出して解放しなければならないため、多数のDOMノードオブジェクトを使用する処理などは記述が面倒です。&lt;br /&gt;&lt;br /&gt;そこでおすすめなのが、HTTPD機能で生成した動的WebページをIEコンポーネント上に表示し、Webページ側のJavaScriptで処理を行わせる方法です。&lt;br /&gt;HTTPDには、Webページ上のJavaScriptとNILScript側の関数を連携させるためのclientSide関数とserverSide関数という機能が用意されています。&lt;br /&gt;clientSide関数はブラウザ上で実行されるため、DOMオブジェクトの明示的開放が要らないだけでなく、jQueryオブジェクトも利用できるので、複雑なDOM操作も手軽に記述可能です。&lt;br /&gt;&lt;br /&gt;任意のURLをIE上に読み込んでDOMを利用して情報の取得などを行いたい場合には、HTTPD上に用意したWebページのように自由にスクリプトを埋め込んで実行させることは出来ませんが、ブックマークレット機能を利用することで同様のことが行なえます。&lt;br /&gt;ブックマークレットとは、「javascript:」に続いてスクリプトを記述したURIをブックマークなどから開くことで、Webページ上で任意の処理を実行させられるという手法のことです。&lt;br /&gt;NILScriptのHTTPDでは、NILScript上で定義したclientSide/serverSide関数を利用した処理をブックマークレットとして呼び出せるようにする機能が用意されています。&lt;br /&gt;このブックマークレットのURLをIEコンポーネントのnavigate()メソッドで読み込ませれば、表示しているWebページ上でNILScript上の機能を利用した任意の処理を実行させられます。&lt;br /&gt;&lt;br /&gt;以下は、この手法の利用してWebページのbody要素の高さを調べて表示するという例です。&lt;br /&gt;&lt;pre&gt;use('Window','ATL','HTTPD');&lt;br /&gt;var result;&lt;br /&gt;var httpd=HTTPD.create({&lt;br /&gt;    serverSide:{&lt;br /&gt;        report:function(value){&lt;br /&gt;            //受取った解析結果を変数に代入し、ウィンドウを閉じる(4)&lt;br /&gt;            result=value;&lt;br /&gt;            w.close();&lt;br /&gt;        },&lt;br /&gt;    },&lt;br /&gt;    bookmarklets:{&lt;br /&gt;        analyze:function(){&lt;br /&gt;            //ブラウザ上でWebページを解析し、結果をserverSide関数に渡す(3)&lt;br /&gt;            report([$(document.body).height()]);&lt;br /&gt;        },&lt;br /&gt;    },&lt;br /&gt;});&lt;br /&gt;var w=PlainWindow.create({&lt;br /&gt;    width:800,height:600,&lt;br /&gt;    children:{&lt;br /&gt;        ie:{&lt;br /&gt;            type:Trident,&lt;br /&gt;            top:0,bottom:0,left:0,right:0,&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;w.request(function(){&lt;br /&gt;    this.ie.object.observe('DWebBrowserEvents2_DocumentComplete',function(o){&lt;br /&gt;        //読み込みが完了したらブックマークレットを読み込ませる(2)&lt;br /&gt;        this.navigate(httpd.bookmarkletURL('analyze'));&lt;br /&gt;    });&lt;br /&gt;    //解析したいWebページを読み込ませる(1)&lt;br /&gt;    this.ie.object.navigate("http://lukewarm.s151.xrea.com/nilscript.html");&lt;br /&gt;});&lt;br /&gt;//ウィンドウが閉じられたら、解析結果を利用した処理を行う(5)&lt;br /&gt;w.wait('destroy');&lt;br /&gt;println(result);&lt;br /&gt;&lt;/pre&gt;HTTPD上では、analyzeというブックマークレット関数とreport()というserverSide関数を定義しています。&lt;br /&gt;ブックマークレット上では、「$」でjQueryオブジェクトが利用できる他、serverSideで定義した関数の呼び出しが可能です。&lt;br /&gt;serverSide関数は、第1引数に関数に渡す引数の配列、第2引数に返り値を受取るコールバック関数(省略可)を指定するという特殊な呼び出し方になっていることに注意してください。&lt;br /&gt;また、bookmarkletsの関数は一旦文字列化されてブラウザ上で実行されるため、NILScript側の変数を直接参照することは出来ず、ブラウザのスクリプトエンジンがサポートしていない構文も利用できないことにも注意が必要です。&lt;br /&gt;&lt;br /&gt;次に、Tridentコントロールを一つだけ配置したPlainWindowオブジェクトを生成します。&lt;br /&gt;そして、このIEコンポーネントのCOMオブジェクトのobserve()で、Webページの読み込み完了時にブックマークレットの実行を行うというイベントハンドラを登録し、さらに調査したいURLを読み込ませます。&lt;br /&gt;この処理は、ウィンドウの初期化が完了される前に実行されてしまわないように、ウィンドウを所有しているスレッド上で処理を実行させるrequest()メソッドを利用して呼び出します。&lt;br /&gt;Webページの読み込みが行われると、スクリプト中のコメントの後ろに付けられた番号の順番で処理が実行されていき、最終的に調査結果の表示が行われます。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-7429647446870225045?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/7429647446870225045/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/12/webie.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7429647446870225045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7429647446870225045'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/12/webie.html' title='任意のWebページをIEコンポーネントに読み込ませて処理する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-238103065970370209</id><published>2010-12-08T22:11:00.000+09:00</published><updated>2010-12-08T22:11:17.351+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='スクリプト作成補助'/><title type='text'>NILScriptのプロセス自身のメモリ使用量を取得する</title><content type='html'>大量のデータを処理するスクリプトを作っていてメモリ使用量が心配になったときや、メモリの解放漏れが無いか確かめたいときなどには、スクリプトのプロセスのメモリ使用状況を調べたくなります。&lt;br /&gt;そんなときいちいちタスクマネージャでスクリプトのプロセスを探してメモリ使用量を調べるのは面倒です。&lt;br /&gt;&lt;br /&gt;NILScriptのProcessオブジェクトには、プロセスのメモリ使用状況を取得する機能があり、「Main.process」で現在スクリプトを実行しているプロセスをProcessオブジェクトとして得ることができるので、自プロセスのメモリ使用状況を簡単に取得できます。&lt;br /&gt;&lt;br /&gt;例えば、以下のようにすれば、Imageオブジェクトを生成して解放したときにメモリの解放漏れがあるかどうかが分かります。&lt;br /&gt;&lt;pre&gt;use('Image');&lt;br /&gt;for(var i=0;i&amp;lt;100;i++){&lt;br /&gt;    try{&lt;br /&gt;        var img=Image.create(1920,1080);&lt;br /&gt;    }finally{&lt;br /&gt;        img.free();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;println(Main.process.pagefileUsage);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;なお、Imageオブジェクトのfree()が正しく全てのリソースを解放していなかった件については、先ほど修正しました。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-238103065970370209?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/238103065970370209/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/12/nilscript.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/238103065970370209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/238103065970370209'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/12/nilscript.html' title='NILScriptのプロセス自身のメモリ使用量を取得する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8858963241657824459</id><published>2010-11-21T10:42:00.000+09:00</published><updated>2010-11-21T10:42:52.407+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQLite'/><category scheme='http://www.blogger.com/atom/ns#' term='文字列'/><title type='text'>SQLiteのFTSを応用して長文の要点を抜き出してみる</title><content type='html'>SQLiteの全文検索機能であるFTS3には、snippet()という関数が用意されており、検索ワードが含まれていた箇所の前後の文章を取得できます。&lt;br /&gt;これを応用すれば、長文から要点っぽい部分を抜き出す機能が実現できるのではないかと思い、Segmenterで分かち書きしたテキストをDBに格納し、出現頻度上位の単語を検索した時のsnippet()を取得するというスクリプトを作成してみました。&lt;br /&gt;&lt;pre&gt;use('Clipboard','Segmenter','SQLite');&lt;br /&gt;try{&lt;br /&gt;    var seg=Segmenter.create("ja");&lt;br /&gt;    var db=DB.open();&lt;br /&gt;    db.execute("CREATE VIRTUAL TABLE docs USING fts3(body)");&lt;br /&gt;    var a=seg.segment(Clipboard.text.replace(/[\s\r\n\t]+/g,' '));&lt;br /&gt;    db.table('docs').insert([{body:a.join(' ')}]);&lt;br /&gt;    var re=/[ぁ-ん]{4,}|[々〇\u303B\u3400-\u9FFF\uF900-\uFAFF0-9０-９a-zａ-ｚァ-ヴーｱ-ﾝﾞｰ]{2,}/i;&lt;br /&gt;    var k=$G(a).groupBy(void(0),function(w,g)({w:w,c:g.count()}))&lt;br /&gt;               .filter(function(o)(re.test(o.w)))&lt;br /&gt;               .orderByDesc('c').map('w').head(3).toArray();&lt;br /&gt;    println(k);&lt;br /&gt;    println(db.select(&lt;br /&gt;        [{d:'snippet(docs,"&lt;&lt;","&gt;&gt;","...",0,64)'},'docs','body MATCH $q'],&lt;br /&gt;        "",-1,0,{q:k.join(' ')}&lt;br /&gt;    ).first().d.replace(/([^\w])\s|\s([^\w])/g,'$1$2'));&lt;br /&gt;}finally{&lt;br /&gt;    free(seg,db);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;最初にSegmenterオブジェクトとオンメモリDBオブジェクトを生成し、クリップボードのテキストを分かち書きした配列をDBに格納します。&lt;br /&gt;次に、ジェネレータの拡張メソッドで分かち書き配列を加工し、出現頻度の高い上位3件の単語を得ます。&lt;br /&gt;この時、記号や助詞などの不要な単語を除外するため、正規表現で大雑把にフィルタリングしています。&lt;br /&gt;そして、その頻出単語をキーワードとしてDBから検索を行い、sinppet()を取得し、不要な空白を除去して出力します。&lt;br /&gt;なお、snippet()の引数ではテーブル名、マッチ箇所を囲む開始・終了文字列、列番号(0～)、抜き出したい単語数を指定できます。単語数を負の数にすると、抜き出す箇所が複数に分かれる場合に、合計ではなくそれぞれの部分の単語数が指定した数になるように抜き出されるようです。&lt;br /&gt;&lt;br /&gt;適当にいくつかのニュースやブログ記事で試してみたところ、期待通りに頻出単語とそれを含む部分を抜き出せました。&lt;br /&gt;文章によっては本題ではない部分が抜き出されてしまうこともありましたが、文の書き出しなどを決め撃ちで抜き出す単純な方法よりは、有用な部分を抜き出せる可能性が高いような気がします。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8858963241657824459?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8858963241657824459/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/11/sqlitefts.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8858963241657824459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8858963241657824459'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/11/sqlitefts.html' title='SQLiteのFTSを応用して長文の要点を抜き出してみる'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-58925912492388314</id><published>2010-11-19T00:22:00.001+09:00</published><updated>2010-11-19T00:23:19.434+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQLite'/><category scheme='http://www.blogger.com/atom/ns#' term='文字列'/><title type='text'>Segmenterで分かち書きしたテキストをSQLiteで全文検索</title><content type='html'>NILScriptには軽量データベースエンジンSQLiteを扱うクラスが用意されています。&lt;br /&gt;SQLiteには文字列中の単語をインデックス化して高速な全文検索を行うFTS3という機能が用意されていますが、標準搭載されている単語分割処理は文字列を空白文字で分割するだけの簡易的なものなので、そのままでは日本語のテキストをまともに処理できません。&lt;br /&gt;&lt;br /&gt;そこで、日本語の文字列を分かち書きする機能を提供する「Segmenter」クラスを新たに用意しました。&lt;br /&gt;アルゴリズム本体はプラグイン方式で追加できるようになっており、現在は&lt;a href="http://www.chasen.org/~taku/software/TinySegmenter/"&gt;TinySegmenter- Javascriptだけで実装されたコンパクトな分かち書きソフトウェア&lt;/a&gt;に&lt;a href="http://javascript.g.hatena.ne.jp/edvakf/20101116/1289886927"&gt;高速化のための修正を加えたもの&lt;/a&gt;にSpiderMonkey独自機能を利用したチューニングを加えて作成したプラグインが用意されています。&lt;br /&gt;TinySegmenterは簡易的な物なので、「すもももももももものうち」のように平仮名が連続していたりすると「すも | も | も | もも | も | ももの | うち」のようなおかしな結果になってしまうことがありますが、検索に利用するだけなら十分でしょう。(検索語句の「すもも」も「すも | も」として検索されるため)&lt;br /&gt;より正確な分かち書きが必要な場合は、MeCabなどのエンジンを利用したプラグインを作成するとよいでしょう。&lt;br /&gt;&lt;br /&gt;以下のスクリプトは、SegmenterとSQLiteを組み合わせて全文検索を行うサンプルです。&lt;br /&gt;&lt;pre&gt;var segmenter=require('Segmenter').Segmenter.create("ja");&lt;br /&gt;var db=require('SQLite').DB.open();&lt;br /&gt;db.execute("CREATE VIRTUAL TABLE docs USING fts3(title TEXT, body TEXT)");&lt;br /&gt;db.begin();&lt;br /&gt;Main.directory.directory('doc').files.execute(function(f){&lt;br /&gt;    db.table('docs').insert([{title:f.baseName,body:segmenter.segment(f.load()).join(' ')}]);&lt;br /&gt;});&lt;br /&gt;db.end();&lt;br /&gt;&lt;br /&gt;var q;&lt;br /&gt;while(q=prompt("search query","")){&lt;br /&gt;    println("search result for: "+q);&lt;br /&gt;    db.select([,'docs','body MATCH $q'],"title",-1,0,{q:'"'+segmenter.segment(q).join(' ')+'"'}).execute(function(o){&lt;br /&gt;        println(o.title);&lt;br /&gt;    });&lt;br /&gt;}&lt;br /&gt;free(db,segmenter);&lt;br /&gt;&lt;/pre&gt;各クラスの基本的な使い方については、同梱のドキュメントなどを参照してください。&lt;br /&gt;&lt;br /&gt;全文検索型のテーブルを作成するには、「"CREATE VIRTUAL TABLE name USING fts3(colnames)」のようにします。&lt;br /&gt;そして、挿入する値を指定する際に、分かち書きした値を指定します。Segmenterオブジェクトのsegment()メソッドは配列を返すので、空白で連結する必要があります。&lt;br /&gt;&lt;br /&gt;検索時にMATCH演算子を使うことで、インデックスを利用した全文検索を行なえます。&lt;br /&gt;検索語句は挿入時と同様にSegmenterで分割して空白区切りにし、前後に「"」を付加する必要があります。&lt;br /&gt;MATCH演算子の詳しい使い方は&lt;a href="http://www.sqlite.org/fts3.html#tokenizer"&gt;SQLite FTS3 Extension&lt;/a&gt;などを参照してください。&lt;br /&gt;&lt;br /&gt;上記のスクリプトを実行すると、キーワード入力用のプロンプトが表示され、入力した語句を含むドキュメントが列挙されます。&lt;br /&gt;プロンプト表示までに発生する2秒ほどの待ち時間は、主にSegmenterの処理による物のようです。&lt;br /&gt;個人利用で扱う程度のテキスト量なら、このくらいの処理速度で十分実用に耐えられるでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-58925912492388314?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/58925912492388314/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/11/segmentersqlite.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/58925912492388314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/58925912492388314'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/11/segmentersqlite.html' title='Segmenterで分かち書きしたテキストをSQLiteで全文検索'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-901471260549068522</id><published>2010-10-27T12:04:00.000+09:00</published><updated>2010-10-27T12:04:10.055+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>設定ファイルにウィンドウ位置などの情報を保存する</title><content type='html'>ウィンドウを表示して入力の受け付けや情報の表示を行うタイプのプログラムでは、ウィンドウを表示する際、前回のウィンドウの位置・サイズを記憶して再現してくれるようにすると便利です。&lt;br /&gt;&lt;br /&gt;このような設定情報の保存を行う際には、pref()関数を使います。&lt;br /&gt;この関数は、適切なユーザー設定ディレクトリを自動認識して、設定ファイルを表すFile/Directoryオブジェクトを返してくれます。&lt;br /&gt;&lt;br /&gt;設定ファイルの形式は、JavaScriptのオブジェクトリテラルの表記と同じ書式のテキストで保存するJSONという形式を使うと良いでしょう。&lt;br /&gt;FileオブジェクトのloadJSON()やsaveJSON()というメソッドを使えば、簡単にオブジェクトとして読み込んだり保存できます。&lt;br /&gt;&lt;br /&gt;下記の例は、ウィンドウを閉じようとしたときに位置とサイズを記憶して次回実行時に再現するだけのスクリプトです。&lt;br /&gt;&lt;pre&gt;var config=(pref("windowPosTest.json")||{loadJSON:function()({})}).loadJSON();&lt;br /&gt;var w=require('Window').Window.create({&lt;br /&gt; title:"test",&lt;br /&gt; width:100,height:100,&lt;br /&gt; x:config.windowX||0, y:config.windowY||0,&lt;br /&gt; events:{&lt;br /&gt;  close:function(){&lt;br /&gt;   config.windowX=this.x;&lt;br /&gt;   config.windowY=this.y;&lt;br /&gt;   pref("windowPosTest.json",true).saveJSON(config);&lt;br /&gt;  },&lt;br /&gt; },&lt;br /&gt;}).show();;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;最初のpref()では、既に存在している設定ファイルを表すFileオブジェクトを取得しています。&lt;br /&gt;この時、ファイルが存在していなくてnullが返された場合でもエラーにならずにデフォルトのオブジェクトがセットされるようにしておく必要があります。&lt;br /&gt;&lt;br /&gt;Windowオブジェクトのcloseイベントでは、設定オブジェクトにウィンドウの現在位置をセットして保存を行っています。&lt;br /&gt;保存時のpref()の呼び出しでは、第2引数をtrueにする必要があります。&lt;br /&gt;&lt;br /&gt;スクリプトが不要になったらプログラムのディレクトリを削除するだけで完全に削除できるように、通常はスクリプトのあるディレクトリ内の「users」ディレクトリにユーザー名のディレクトリを作って保存されます。&lt;br /&gt;しかし、スクリプトのあるディレクトリが書き込み禁止になっていたりする場合は、Application Dataディレクトリ内のスクリプトファイル名を名前にしたディレクトリが保存先として選択されます。&lt;br /&gt;また、スクリプトと同じディレクトリに「config」というディレクトリがあれば、そちらが保存先になります。これはプログラムをリムーバブルメディアに入れて持ち出して複数の環境で利用したい場合などのための機能です。&lt;br /&gt;&lt;br /&gt;なお、プログラム用のドライブに頻繁な書き込みをしたくないとか、まとめてバックアップ出来た方がいいなどの理由で、設定がApplication Dataディレクトリに保存されることを好むユーザーは、あらかじめApplication Dataディレクトリ内に該当するディレクトリを作成しておくことで、そちらに保存させることも出来ます。&lt;br /&gt;&lt;br /&gt;これらの仕様により、pref()関数を使用すれば、簡単にユーザーの好みや実行環境に合った最適な場所にデータを保存できるようになっています。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-901471260549068522?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/901471260549068522/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_27.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/901471260549068522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/901471260549068522'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_27.html' title='設定ファイルにウィンドウ位置などの情報を保存する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2934122970968994299</id><published>2010-10-25T02:59:00.002+09:00</published><updated>2010-10-25T02:59:43.490+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><title type='text'>自前ウィンドウの任意の部分をドラッグして移動できるようにする</title><content type='html'>NILScriptの自前ウィンドウ生成機能では、タイトルバーや枠のないウィンドウも生成できます。&lt;br /&gt;しかし、タイトルバーや枠のドラッグによる移動・リサイズが行なえないので、別途移動やリサイズのための動作を用意する必要があります。&lt;br /&gt;&lt;br /&gt;ウィンドウの任意の部分をドラッグして移動できるようにするには、hitTestイベントを利用します。&lt;br /&gt;このイベントは、カーソル下にあるのがウィンドウのどの部位かという問い合わせを受取ったときに実行されます。&lt;br /&gt;ここでカーソル下がタイトルバーであると応答するようにすれば、マウスの左ボタンでドラッグしたときに、タイトルバーをドラッグしたときと同じようにウィンドウが移動されるようになります。&lt;br /&gt;&lt;br /&gt;これを利用して前回のCPU使用率グラフ表示のウィンドウをドラッグ可能にしたのが、以下のスクリプトになります。&lt;br /&gt;&lt;pre&gt;var img=require('Image').Image.create(100,100,"black");&lt;br /&gt;var w=require('Window').PlainWindow.create({&lt;br /&gt;    width:100,height:100,&lt;br /&gt;    graphics:img,&lt;br /&gt;    transparentColor:0x000000,toolWindow:true,&lt;br /&gt;    topmost:true,&lt;br /&gt;    events:{&lt;br /&gt;        hitTest:function(o){&lt;br /&gt;            o.result="caption";&lt;br /&gt;            return(true);&lt;br /&gt;        },&lt;br /&gt;        mbuttonUp:function(o){&lt;br /&gt;            this.close();&lt;br /&gt;        },&lt;br /&gt;    },&lt;br /&gt;});&lt;br /&gt;Thread.create(function(){&lt;br /&gt;    var mon=new (require('SystemMonitor').CPU)(), rate=0;&lt;br /&gt;    while(true){&lt;br /&gt;        w.request(function(){&lt;br /&gt;            img.fillEllipse(1,1,98,98,0x9999FF);&lt;br /&gt;            img.fillPie(1,1,98,98,-Math.PI/2,(Math.PI*2)*rate,0x99FF99,true);&lt;br /&gt;            img.strokeEllipse(1,1,98,98,0x010101,true);&lt;br /&gt;            img.drawTo(w);&lt;br /&gt;        });&lt;br /&gt;        sleep(1000);&lt;br /&gt;        rate=mon.get().usage;&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;w.show();&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2934122970968994299?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2934122970968994299/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_5667.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2934122970968994299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2934122970968994299'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_5667.html' title='自前ウィンドウの任意の部分をドラッグして移動できるようにする'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-497592153208292382</id><published>2010-10-25T02:23:00.000+09:00</published><updated>2010-10-25T02:23:07.533+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>自前ウィンドウ上に表示した画像を更新・再描画する</title><content type='html'>Imageオブジェクトの画像をウィンドウに表示するには、Window.create()のオプションオブジェクトのgraphicsメンバにセットするというのは以前説明しましたが、今回は表示する画像の内容を更新する方法について説明します。&lt;br /&gt;&lt;br /&gt;ウィンドウの画像を更新するには、Imageオブジェクトの各種メソッドで画像を更新した後、描画対象のWindowオブジェクトを引数にしてdrawTo()メソッドを呼び出します。&lt;br /&gt;&lt;br /&gt;この時、複数スレッドからImageオブジェクトに同時アクセスしないように注意する必要があります。&lt;br /&gt;ウィンドウを所有するスレッド上では、Imageオブジェクトを使用した再描画が不特定のタイミングで発生するので、他のスレッド上でImageオブジェクトを操作すると、更新途中の画像が表示されてしまったり、更新処理に失敗してしまったりします。&lt;br /&gt;これを避けるためには、画像の更新処理もウィンドウを所有するスレッド上で実行しなければなりません。&lt;br /&gt;&lt;br /&gt;Windowオブジェクトのイベントハンドラ内で更新・再描画を行う場合は特に気にする必要はありませんが、他のスレッドから更新を行う場合は、Windowオブジェクトのrequest()メソッドを使用してください。&lt;br /&gt;request()メソッドは、指定された関数をウィンドウを所有するスレッド上で実行します。この関数内でImageオブジェクトを操作すれば、安全に画像を更新できます。&lt;br /&gt;&lt;br /&gt;下記のスクリプトは、SystemMonitorユニットのCPUクラスを利用して取得したCPU使用率を円グラフでウィンドウ上に表示するという例です。&lt;br /&gt;&lt;pre&gt;var img=require('Image').Image.create(100,100,"black");&lt;br /&gt;var w=require('Window').PlainWindow.create({&lt;br /&gt;    width:100, height:100,&lt;br /&gt;    transparentColor:0x000000,topmost:true,&lt;br /&gt;    graphics:img,&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;Thread.create(function(){&lt;br /&gt;    var mon=new (require('SystemMonitor').CPU)(), rate=0;&lt;br /&gt;    while(true){&lt;br /&gt;        w.request(function(){&lt;br /&gt;            img.fillEllipse(1,1,98,98,0x9999FF);&lt;br /&gt;            img.fillPie(1,1,98,98,-Math.PI/2,(Math.PI*2)*rate,0x99FF99,true);&lt;br /&gt;            img.strokeEllipse(1,1,98,98,0x010101,true);&lt;br /&gt;            img.drawTo(w);&lt;br /&gt;        });&lt;br /&gt;        sleep(1000);&lt;br /&gt;        rate=mon.get().usage;&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;w.show();&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-497592153208292382?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/497592153208292382/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_25.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/497592153208292382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/497592153208292382'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_25.html' title='自前ウィンドウ上に表示した画像を更新・再描画する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-3424168006611293448</id><published>2010-10-23T08:08:00.000+09:00</published><updated>2010-10-23T08:08:06.400+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>テキストなどに影や縁取りを付けた画像を生成</title><content type='html'>Imageオブジェクトに用意されている様々な機能を組み合わせれば、以下の例のようにテキストや図形に影をつけたり縁取りをするなどのエフェクトを加えて描画することも可能です。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_wiFD7NiUNAg/TMIXeqxpYsI/AAAAAAAAACg/g9K2Oz-GBq0/s1600/logo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_wiFD7NiUNAg/TMIXeqxpYsI/AAAAAAAAACg/g9K2Oz-GBq0/s1600/logo.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;この例の画像を生成するスクリプトは、以下のようになります。&lt;br /&gt;&lt;pre&gt;var {Image}=require('Image');&lt;br /&gt;var base=Image.create(200,64);&lt;br /&gt;base.drawText("NILScript",0,0,{name:"Impact",size:48,brush:{&lt;br /&gt;    color:[0xFF0000,0x990000],&lt;br /&gt;    gradient:{angle:Math.PI/2, width:60},&lt;br /&gt;    gammaCorrect:true,&lt;br /&gt;    focus:0.9,&lt;br /&gt;    curve:true,&lt;br /&gt;}});&lt;br /&gt;&lt;br /&gt;var frame=base.clone();&lt;br /&gt;frame.and(0xFF000000);&lt;br /&gt;frame.matrixFilter([[1,1,1],[1,1,1],[1,1,1]]);&lt;br /&gt;frame.matrixFilter([[1,1,1],[1,1,1],[1,1,1]]);&lt;br /&gt;frame.replaceColor("black","yellow");&lt;br /&gt;&lt;br /&gt;var shadow=frame.clone();&lt;br /&gt;shadow.and(0xFF000000);&lt;br /&gt;shadow.blur(3);&lt;br /&gt;&lt;br /&gt;var img=Image.create(200,64,"white");&lt;br /&gt;img.drawImage(shadow,{x:4,y:4});&lt;br /&gt;img.drawImage(frame);&lt;br /&gt;img.drawImage(base);&lt;br /&gt;&lt;br /&gt;img.save("logo.jpg",{quality:90});&lt;br /&gt;&lt;/pre&gt;まず、最初に背景無しでImageオブジェクトを生成し、グラデーションブラシを用いてテキストを描画しています。&lt;br /&gt;ブラシの定義オプションには様々なものがあるので、NILScriptのアーカイブ内のdoc/Image.txtの説明を参照してください。&lt;br /&gt;&lt;br /&gt;次に、clone()メソッドでテキスト画像のコピーを生成し、and()メソッドでアルファチャンネル以外の値を0にします。&lt;br /&gt;続いて、matrixFilter()メソッドを利用して不透明の領域を太らせます。&lt;br /&gt;matrixFilter()は、各ピクセルと隣接ピクセルのRGBA各値に引数で指定した2次元配列の対応する値を掛けた値の和をそのピクセルの値にするという処理を行います。この時、0未満の値は0に、256以上の値は255になります。&lt;br /&gt;「[[1,1,1],[1,1,1],[1,1,1]]」という配列では、隣接する9ピクセルに一つでも不透明度255のピクセルがあれば不透明度が255になります。&lt;br /&gt;&lt;br /&gt;更に、replaceColor()メソッドで色の置換を行います。&lt;br /&gt;この時点では、不透明度255の黒と不透明度0の黒の2つの部分がありますが、第1引数を"black"にした場合は、不透明度255の黒のみが置換されます。&lt;br /&gt;単色ではなくグラデーションなどを使いたい場合は、そのスタイルで塗りつぶした画像にupdateAlpha()メソッドでアルファチャンネルをコピーすると良いでしょう。&lt;br /&gt;&lt;br /&gt;次に、出来上がった縁取り部分のコピーを生成し、同様にして全体を黒にした後、blur()メソッドでぼかして、影っぽい画像を生成します。&lt;br /&gt;&lt;br /&gt;最後に、白背景の画像を生成し、影を少しずらして貼り付けた後、縁取りと元のテキストを貼り付けて完成です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-3424168006611293448?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/3424168006611293448/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_23.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3424168006611293448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3424168006611293448'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_23.html' title='テキストなどに影や縁取りを付けた画像を生成'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_wiFD7NiUNAg/TMIXeqxpYsI/AAAAAAAAACg/g9K2Oz-GBq0/s72-c/logo.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-4938107798478261245</id><published>2010-10-21T18:44:00.000+09:00</published><updated>2010-10-21T18:44:07.114+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>画像にテキストを描画する</title><content type='html'>NILScriptのImageユニットでは、下記のようにdrawText()メソッドを使用することで、画像上に文字列を書き込むことも出来ます。&lt;br /&gt;&lt;pre&gt;var {Image}=require('Image');&lt;br /&gt;var img=Image.create(256,256,"white");&lt;br /&gt;&lt;br /&gt;m=img.measureText("NILScript");&lt;br /&gt;img.strokeRect(15,15,m.width+2,m.height+2,"black");&lt;br /&gt;img.drawText("NILScript",16,16);&lt;br /&gt;img.drawText("NILScript",0,64,{name:"Impact",size:48,color:"red",bold:true});&lt;br /&gt;img.drawText('NILScript',0,160,{file :'D:\\myfonts\\AoyagiKouzanFont2.ttf' , size:48});&lt;br /&gt;&lt;br /&gt;img.save("drawText.jpg",{quality:90});&lt;br /&gt;&lt;/pre&gt;単に文字列を表示したいだけなら、文字列と描画開始位置のx,y座標を指定するだけです。この場合、デフォルトのフォント、サイズ、色で描画されます。&lt;br /&gt;&lt;br /&gt;第4引数には、様々なオプションを格納したオブジェクトを指定できます。&lt;br /&gt;「name」でフォント名、「size」でピクセル数、colorで塗りつぶし色が指定できます。&lt;br /&gt;また、「file」でフォントファイル名を指定すれば、システムにインストールされていないフォントも使用できます。&lt;br /&gt;&lt;br /&gt;実際に描画される文字列の大きさを知りたい場合には、measureText()メソッドを使用します。このメソッドは、第1引数に文字列、第2引数にオプションを指定します。drawText()と違い、x,y座標は指定しません。&lt;br /&gt;このメソッドの返り値は、widthやheightなどのプロパティを持つオブジェクトになります。これは単なるオブジェクトなので、解放処理は不要です。&lt;br /&gt;この情報を利用すれば、テキストの周りにstrokeRect()などで枠を描画したりすることも可能です。&lt;br /&gt;&lt;br /&gt;上記の例を実行すると、以下のような画像が出来上がります。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TMAK8-NrtuI/AAAAAAAAACc/f2JpvAI-uwU/s1600/drawText.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TMAK8-NrtuI/AAAAAAAAACc/f2JpvAI-uwU/s1600/drawText.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-4938107798478261245?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/4938107798478261245/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_4915.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4938107798478261245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4938107798478261245'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_4915.html' title='画像にテキストを描画する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wiFD7NiUNAg/TMAK8-NrtuI/AAAAAAAAACc/f2JpvAI-uwU/s72-c/drawText.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-1080992015515208351</id><published>2010-10-21T17:34:00.001+09:00</published><updated>2010-10-22T20:10:06.888+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>一定時間キー・マウス操作がなかったときに処理を実行</title><content type='html'>NILScriptのSystemMonitorユニットには、最後にキーボードやマウスの操作が確認されてから経過した時間を取得する「InputIdle」クラスが用意されています。&lt;br /&gt;これを使用すれば、ユーザーが退席している間に何らかの処理を行ったり、作業状況のログを記録したりするツールを作成できます。&lt;br /&gt;&lt;br /&gt;InputIdleクラスの基本的な使い方は、以下のようになります。&lt;br /&gt;&lt;pre&gt;Main.createNotifyIcon();&lt;br /&gt;var mon=new (require('SystemMonitor').InputIdle)();&lt;br /&gt;Thread.create(function(){&lt;br /&gt; var idle;&lt;br /&gt; while(true){&lt;br /&gt;  if(mon.get(true)&amp;lt;5000){ //規定時間&lt;br /&gt;   if(idle){&lt;br /&gt;    idle=false;&lt;br /&gt;    //↓一定時間以上振りに操作を行ったときに実行される処理&lt;br /&gt;    println("wake");&lt;br /&gt;   }&lt;br /&gt;  }else if(!idle){&lt;br /&gt;   idle=true;&lt;br /&gt;   //↓一定時間操作がなかったときに実行される処理&lt;br /&gt;   println("idle");&lt;br /&gt;  }&lt;br /&gt;  sleep(100);//監視間隔&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;無操作時間を取得するには、InputIdleオブジェクトのget()メソッドを呼び出します。&lt;br /&gt;引数がtrueの場合は、プログラムによって生成された操作を除き、実際にユーザーが行った操作のみを考慮した無操作時間が取得されます。&lt;br /&gt;idle変数は、既に無操作時間が規定値を超えているかどうかのフラグです。&lt;br /&gt;最初に無操作時間が規定値を超えた時にtrueにし、無操作時間が規定値以下の時にtrueになっていたらfalseにすることで、一定時間以上の放置と放置からの復帰を検出しています。&lt;br /&gt;上記の例でprintln()関数を呼び出している部分に、放置や復帰を検出したときの処理を記述します。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-1080992015515208351?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/1080992015515208351/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_7267.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/1080992015515208351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/1080992015515208351'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_7267.html' title='一定時間キー・マウス操作がなかったときに処理を実行'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-6205555228868181250</id><published>2010-10-21T16:11:00.001+09:00</published><updated>2010-10-21T19:12:23.963+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>円グラフを生成する</title><content type='html'>NILScriptのImageユニットには、扇形の描画を行うstrokePie()やfillPie()などのメソッドも用意されています。&lt;br /&gt;これらを使用すれば、円グラフの生成や表示が行なえます。&lt;br /&gt;&lt;br /&gt;円グラフを生成するには、下記のようなスクリプトを記述します。&lt;br /&gt;今回は、グラフ化する項目群を格納した配列をitems変数としてスクリプト中に記述していますが、実際にはファイルから読み込んだり何らかの方法で収集して用意してください。&lt;br /&gt;&lt;pre&gt;var {Image}=require('Image');&lt;br /&gt;var img=Image.create(256,256,"white");&lt;br /&gt;var items=[&lt;br /&gt;    {count:100,color:0xFF9999},&lt;br /&gt;    {count:80,color:0x99FF99},&lt;br /&gt;    {count:70,color:0x9999FF},&lt;br /&gt;    {count:40,color:0x66FFFF},&lt;br /&gt;    {count:20,color:0xFF66FF},&lt;br /&gt;    {count:10,color:0xFFFF66},&lt;br /&gt;];&lt;br /&gt;var sum=items.sum('count');&lt;br /&gt;var angle=-Math.PI/2;&lt;br /&gt;for(var i=0,l=items.length;i&amp;lt;l;i++){&lt;br /&gt;    var sweep=(Math.PI*2)*(items[i].count/sum);&lt;br /&gt;    img.fillPie(8,8,240,240, angle, sweep,items[i].color);&lt;br /&gt;    img.strokePie(8,8,240,240, angle, sweep,"black");&lt;br /&gt;    angle+=sweep;&lt;br /&gt;}&lt;br /&gt;img.save("pie_graph.jpg",{quality:90});&lt;br /&gt;&lt;/pre&gt;まず、配列の各要素のcountプロパティの合計値をsum変数に格納しておきます。&lt;br /&gt;次に、グラフの描画開始角度をangle変数に代入します。0が→の向きを表し、一周がMath.PI*2なので、↑の方向から始めるには「-Math.PI/2」を初期値とします。&lt;br /&gt;&lt;br /&gt;配列の各項目ごとのループでは、まず各項目の値を全項目の合計値で割った値に一周を表すMath.PI*2を乗算して、各項目の扇形の角度を求めています。&lt;br /&gt;そして、fillPie()でその範囲を塗りつぶし、strokePie()で輪郭を描画します。&lt;br /&gt;両メソッドの最初の4つの引数は、扇形を含む円が内接する長方形の位置と大きさを表します。&lt;br /&gt;第5引数では開始角度、第6引数が扇形の角度を指定します。&lt;br /&gt;第7引数では、今回は単に色を指定していますが、他にも線の太さや塗りつぶし方法などが指定できます。&lt;br /&gt;描画が終ったら、次の項目の開始角度が今回の項目の範囲の直後になるように、今回の項目が占めた角度を加算します。&lt;br /&gt;これで、以下のようなグラフが作成できます。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_wiFD7NiUNAg/TL_miwewzFI/AAAAAAAAACY/nygYZA8g1Fc/s1600/pie_graph.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_wiFD7NiUNAg/TL_miwewzFI/AAAAAAAAACY/nygYZA8g1Fc/s1600/pie_graph.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;描画したグラフは、save()メソッドでファイルに保存したり、Window.create()のgraphicsオプションにセットしてウィンドウに表示したりして利用してください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-6205555228868181250?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/6205555228868181250/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_21.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6205555228868181250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6205555228868181250'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_21.html' title='円グラフを生成する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_wiFD7NiUNAg/TL_miwewzFI/AAAAAAAAACY/nygYZA8g1Fc/s72-c/pie_graph.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5176767763681065930</id><published>2010-10-20T00:44:00.000+09:00</published><updated>2010-10-20T00:44:34.144+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><category scheme='http://www.blogger.com/atom/ns#' term='スクリプト作成補助'/><title type='text'>C言語で作成した関数を埋め込み</title><content type='html'>スクリプト言語はC言語などと比べると10倍近くも処理速度が遅いのが難点です。&lt;br /&gt;10倍しても1ミリ秒足らずで終るような処理でしたらあまり問題はありませんが、C言語なら500ミリ秒で済む処理が5秒もかかるようになってしまうと、実用に耐えません。&lt;br /&gt;画像の全ピクセルに対する処理など、反復処理が何万回にも及ぶ可能性のある処理は、本体部分をC言語で作成しておいて、それを何らかの方法でスクリプトから呼び出すようにするとよいでしょう。&lt;br /&gt;ここでは、NILScriptのImageユニットで各種フィルタ機能の実装に利用している、Cコンパイラで生成したネイティブコードをスクリプト中に埋め込む方法を紹介します。&lt;br /&gt;&lt;br /&gt;まず、Microsoft Visual C++(無償のExpress Editionでも可)でプロジェクトを作成し、埋め込みたい関数を記述してコンパイルします。&lt;br /&gt;すると、プロジェクトのディレクトリ内の「Release」ディレクトリにソースコードの拡張子を「.cod」にしたファイルが作られます。&lt;br /&gt;このファイルには、ソースコードから生成されたネイティブコードの16進ダンプや、アセンブラのコードが記述されています。&lt;br /&gt;&lt;br /&gt;NILScriptのディレクトリをカレントディレクトリとして「ng tool/codConv ".codファイルのパス"」というコマンドを実行すると、指定された.codファイル中の関数のネイティブコード部分が抽出され、以下のような形式でクリップボードに格納されます。&lt;br /&gt;&lt;pre&gt;var negate=(new CFunction(Hex.decode(&lt;br /&gt; "55 8b ec 53 56 57 8b 75 0c c1 e6 02 8b 5d 14 8b d3 2b de 8b 45 08 8b 7d 10 0f af fa 03 f8 8b d0 03 d6 81 30 ff ff ff 00 83 c0 04 3b c2 7c f3 03 c3 3b c7 7c e9 5f 5e 5b 5d c3"&lt;br /&gt;))).toFunction([],UInt);&lt;br /&gt;&lt;/pre&gt;これをスクリプト中に貼り付け、「[]」の中に引数の型の定義を記述し、必要なら返り値の型を修正すれば、ネイティブコードの埋め込み定義が出来上がります。&lt;br /&gt;あとは普通の関数と同じように呼び出して利用できます。&lt;br /&gt;&lt;br /&gt;なお、Imageユニットのネイティブコード関数の多くは、動作速度を高速化するため、処理のほとんどをインラインアセンブラで記述しています。&lt;br /&gt;何度も使用する値でメモリの読み書きが発生しないようにレジスタに格納したままにするなどの工夫をすることで、C言語からコンパイルしたものより2倍くらい高速化できることもあります。&lt;br /&gt;いきなりアセンブラでプログラムを作るのは大変なので、最初はコンパイラが生成した.codファイルを参考にするとよいでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5176767763681065930?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5176767763681065930/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/c.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5176767763681065930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5176767763681065930'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/c.html' title='C言語で作成した関数を埋め込み'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-6714378846199801703</id><published>2010-10-19T01:16:00.002+09:00</published><updated>2010-10-19T18:57:45.795+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>画像を透明度エフェクト付きで合成</title><content type='html'>Imageユニットによる画像の合成処理では、合成する画像に加工を施すことで、下図のようなエフェクト付きの合成も実現できます。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TLxyKqCFycI/AAAAAAAAACU/BB2bIZ5MM-Q/s1600/output.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TLxyKqCFycI/AAAAAAAAACU/BB2bIZ5MM-Q/s1600/output.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;この例の画像は、下記のようなスクリプトで作成できます。(画像のパスなどの部分は適宜変更してください)&lt;br /&gt;&lt;pre&gt;var Image=require('Image').Image;&lt;br /&gt;var img=Image.load('input.jpg');&lt;br /&gt;var logo=Image.load("logo.png");&lt;br /&gt;&lt;br /&gt;var mask=Image.create(32,32);&lt;br /&gt;mask.fillEllipse(4,4,24,24,"white");&lt;br /&gt;mask.blur(5);&lt;br /&gt;logo.updateAlpha(mask);&lt;br /&gt;&lt;br /&gt;img.drawImage(logo,img.width-logo.width-16,16);&lt;br /&gt;&lt;br /&gt;img.save('output.jpg',{quality:90});&lt;br /&gt;free(mask,logo,img);&lt;br /&gt;&lt;/pre&gt;元画像と合成するロゴ画像を読み込んだら、ロゴ画像と同じ大きさのマスク用Imageオブジェクトを生成し、fillEllipse()で円を描画します。&lt;br /&gt;次に、blur()メソッドで円をぼかします。マスク画像の白い円の部分以外は透明ですので、円周の付近では不透明と透明が混じって段階的に半透明になります。&lt;br /&gt;これを引数として、ロゴ画像のupdateAlpha()メソッドを呼び出すと、不透明度情報がコピーされ、周辺が徐々に透明になるロゴ画像が出来上がります。&lt;br /&gt;これを合成先の画像のdrawImage()メソッドで合成すれば出来上がりです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-6714378846199801703?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/6714378846199801703/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_6721.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6714378846199801703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6714378846199801703'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_6721.html' title='画像を透明度エフェクト付きで合成'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wiFD7NiUNAg/TLxyKqCFycI/AAAAAAAAACU/BB2bIZ5MM-Q/s72-c/output.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5370010948114967999</id><published>2010-10-19T00:34:00.001+09:00</published><updated>2010-10-19T18:57:59.203+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>半透明で画像を合成</title><content type='html'>NILScriptのImageユニットが提供する画像処理機能では、不透明度情報(アルファチャンネル)の取り扱いが可能です。&lt;br /&gt;この機能を利用すれば、写真などの上に半透明のロゴを合成するウォーターマークのような処理も簡単に実現できます。&lt;br /&gt;&lt;br /&gt;新たに図形やテキストを描画する場合は、半透明の描画色で描画するという手もありますが、既存の画像を半透明にして貼り付けたい場合は、下記のようにして「updateAlpha()」メソッドでピクセルの透明度を一括変更してからdrawImage()で貼り付けるといいでしょう。(ファイル名などは適宜変更してください)&lt;br /&gt;&lt;pre&gt;var Image=require('Image').Image;&lt;br /&gt;var img=Image.load('input.jpg');&lt;br /&gt;&lt;br /&gt;var img2=Image.load("logo.png");&lt;br /&gt;img2.updateAlpha(127);&lt;br /&gt;img.drawImage(img2,img.width-img2.width-16,16);&lt;br /&gt;&lt;br /&gt;img.save('output.jpg',{quality:90});&lt;br /&gt;&lt;/pre&gt;updateAlpha()は、0～255の値で画像の不透明度を指定します。&lt;br /&gt;これにより、下記の例のように元の画像(波模様)の上に半透明で別の画像を合成できます。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TLxooy3Xf4I/AAAAAAAAACQ/7CTi2SRpy1c/s1600/output.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TLxooy3Xf4I/AAAAAAAAACQ/7CTi2SRpy1c/s1600/output.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5370010948114967999?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5370010948114967999/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_19.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5370010948114967999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5370010948114967999'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post_19.html' title='半透明で画像を合成'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wiFD7NiUNAg/TLxooy3Xf4I/AAAAAAAAACQ/7CTi2SRpy1c/s72-c/output.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-7897869234270904562</id><published>2010-10-18T22:55:00.003+09:00</published><updated>2010-10-19T18:58:17.456+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>Imageオブジェクトの画像をウィンドウに表示</title><content type='html'>NILScriptのImageユニットでは、画像のリサイズや切り抜き、図形やテキストなどの追加、ぼかしや明るさ調節などのフィルタ処理を組み合わせて、様々な画像処理を実現できます。&lt;br /&gt;しかし、処理が複雑になるほど、思い通りの処理を一発で実現することは難しくなります。&lt;br /&gt;処理結果を確認しながら処理内容を修正したい場合などは、処理結果を自前ウィンドウ状に表示するといいでしょう。&lt;br /&gt;単に処理結果の画像を表示するだけなら、下記のようにWindow.create()のオプションで「graphics」にImageオブジェクトを指定するだけです。&lt;br /&gt;ウィンドウのクライアント領域全体にImageオブジェクトが保持する画像を表示するウィンドウが作成されます。&lt;br /&gt;この場合、ウィンドウが閉じられるまでImageオブジェクトを解放しないように注意してください。&lt;br /&gt;&lt;pre&gt;var Image=require('Image').Image;&lt;br /&gt;var img=Image.create(256,256,"white");&lt;br /&gt;img.fillPolygon([&lt;br /&gt;    [240,16],&lt;br /&gt;    [192,224],&lt;br /&gt;    [80,96],&lt;br /&gt;    [16,240],&lt;br /&gt;    [64,32],&lt;br /&gt;    [176,160],&lt;br /&gt;],"black",true,true);&lt;br /&gt;&lt;br /&gt;var w=require('Window').Window.create({&lt;br /&gt;    width:400,height:400,&lt;br /&gt;    graphics:img,&lt;br /&gt;}).show();&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-7897869234270904562?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/7897869234270904562/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/image_18.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7897869234270904562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7897869234270904562'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/image_18.html' title='Imageオブジェクトの画像をウィンドウに表示'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8430767789065013832</id><published>2010-10-04T20:38:00.000+09:00</published><updated>2010-10-04T20:38:35.461+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>指定サイズ未満で最大の画質のJPEG画像を生成</title><content type='html'>Imageオブジェクトには、画像をファイルに保存するsave()の他にも、画像ファイルデータをメモリ上に出力し、そのバッファを指すポインタオブジェクトを返すtoBytes()メソッドも用意されています。&lt;br /&gt;&lt;br /&gt;この機能を利用すれば、ファイルに保存することなく圧縮後のファイルサイズを知ることが出来ます。&lt;br /&gt;下記のスクリプトは、圧縮後のサイズが上限値以下になる最大の画質でJPEG画像を保存するという応用例です。&lt;br /&gt;&lt;pre&gt;var file=cwd().file('capture.jpeg');&lt;br /&gt;sleep(2000);&lt;br /&gt;try{&lt;br /&gt;    var img=require('Window').Window.active.capture();&lt;br /&gt;    for(var q=100;q&gt;0;q--){&lt;br /&gt;        try{&lt;br /&gt;            var buf=img.toBytes('.jpeg',{quality:q});&lt;br /&gt;            if((buf.size&lt;100000)||(q==10)){&lt;br /&gt;                file.update(buf);&lt;br /&gt;                println(q);&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;        }finally{&lt;br /&gt;            free(buf);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}finally{&lt;br /&gt;    free(img);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;最初に、img変数にアクティブウィンドウのスクリーンショット画像のImageオブジェクトを代入してます。&lt;br /&gt;次に、forループで最大画質の100から1ずつ減らしながら圧縮を試行しています。&lt;br /&gt;toBytes()では、第1引数で拡張子やMIMEタイプで形式を指定します。第2引数の保存オプションで、q変数に格納されている画質を指定しています。&lt;br /&gt;toBytes()が返すPointerオブジェクトでは、sizeプロパティでバイト数が取得できるので、その値が最大値以下ならばファイルへの保存を実行します。&lt;br /&gt;Fileオブジェクトのupdate()メソッドはファイルを上書き保存するメソッドです。引数には多くの場合文字列を指定しますが、Pointerオブジェクトを指定すればバイト列を保存できます。&lt;br /&gt;toBytes()が返したPointerオブジェクトは、不要になったらfree()関数で解放処理を行う必要があります。&lt;br /&gt;最後に、Imageオブジェクトも解放します。&lt;br /&gt;&lt;br /&gt;Webサイトにアップロードする画像を生成するときなどは、この例を応用して最適な画質のJPEG画像を生成させてみるといいでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8430767789065013832?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8430767789065013832/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/jpeg.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8430767789065013832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8430767789065013832'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/jpeg.html' title='指定サイズ未満で最大の画質のJPEG画像を生成'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-3870835587115490214</id><published>2010-10-04T20:06:00.000+09:00</published><updated>2010-10-04T20:06:49.540+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>画面のスクリーンショットを保存</title><content type='html'>画像処理を行うImageユニットには、ウィンドウのスクリーンショット画像を取得する機能も用意されています。&lt;br /&gt;例えば、下記のようにすることで、アクティブウィンドウのスクリーンショット画像を保存できます。&lt;br /&gt;&lt;pre&gt;try{&lt;br /&gt;    var img=require('Window').Window.active.capture();&lt;br /&gt;    img.save('capture.png');&lt;br /&gt;}finally{&lt;br /&gt;    free(img);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;スクリーンショット画像のImageオブジェクトを取得するには、Windowオブジェクトのcapture()メソッドを呼び出します。Imageオブジェクトが定義されているのはImageユニットですが、WindowオブジェクトはWindowユニットで定義されているので、「require('Window').Window～」のようにすることに注意してください。&lt;br /&gt;なお、capture()メソッドの第1引数にtrueを指定すると、タイトルバーなどのノンクライアント領域を除いた部分の画像を取得することも可能です。&lt;br /&gt;&lt;br /&gt;取得したImageオブジェクトはimg変数に代入し、そのsave()メソッドでファイルに保存しています。&lt;br /&gt;最後にfree(img)で取得したImageオブジェクトの解放処理を呼び出す必要がある事に注意してください。&lt;br /&gt;&lt;br /&gt;今回は単に保存しているだけですが、縮小したサムネイル画像や、Webページに埋め込むためのHTMLを生成したりしてもよいでしょう。&lt;br /&gt;また、Hotstrokesでホットキーからキャプチャを実行したり、ウィンドウの状態変化を監視するWindow.observe()などを利用して特定のタイミングで自動キャプチャを行わせるなど、様々な応用ツールに利用できるはずです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-3870835587115490214?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/3870835587115490214/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3870835587115490214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3870835587115490214'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/blog-post.html' title='画面のスクリーンショットを保存'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5528418682532584340</id><published>2010-10-04T19:47:00.001+09:00</published><updated>2010-10-18T08:40:35.433+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='新機能'/><category scheme='http://www.blogger.com/atom/ns#' term='画像'/><title type='text'>画像処理を行うImageオブジェクト</title><content type='html'>画像処理に関する機能を提供するImageユニットが追加されました。&lt;br /&gt;画像ファイルの読み書きや、リサイズなどの基本的な加工処理、多角形などの描画機能などが用意されています。&lt;br /&gt;&lt;br /&gt;例えば、以下のようにすれば、NILScriptのアイコンなどに使われているロゴ画像を生成できます。&lt;br /&gt;&lt;pre&gt;var file=cwd().file('nilscript.png');&lt;br /&gt;var img=require('Image').Image.create(256,256,"white");&lt;br /&gt;img.fillPolygon([&lt;br /&gt;    [240,16],&lt;br /&gt;    [192,224],&lt;br /&gt;    [80,96],&lt;br /&gt;    [16,240],&lt;br /&gt;    [64,32],&lt;br /&gt;    [176,160],&lt;br /&gt;],"black",true,true);&lt;br /&gt;img.save(file);&lt;br /&gt;free(img);&lt;br /&gt;&lt;/pre&gt;Imageクラスのcreate()メソッドで、幅、高さ、塗りつぶしなどを指定して新規のImageオブジェクトを生成できます。&lt;br /&gt;ImageオブジェクトのfillPolygon()メソッドで、一連の点を結ぶ直線で囲まれた領域を塗りつぶします。&lt;br /&gt;そして、saveメソッドで作成した画像を指定したファイルに保存しています。&lt;br /&gt;Imageオブジェクトはfree()関数で明示的に解放する必要があります。特に常駐スクリプトや大量の画像を処理するスクリプトでは、忘れないように注意してください。&lt;br /&gt;&lt;br /&gt;描画系のメソッドはまだ一部しか実装されていませんが、近いうちに線や文字の描画なども実装する予定です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5528418682532584340?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5528418682532584340/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/10/image.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5528418682532584340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5528418682532584340'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/10/image.html' title='画像処理を行うImageオブジェクト'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-1198068008837135355</id><published>2010-09-27T00:12:00.000+09:00</published><updated>2010-09-27T00:12:06.447+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><title type='text'>ウィンドウを画面の横半分などにリサイズ・移動</title><content type='html'>NILScriptのWindowユニットで提供されるクラス群では、スクリプトで生成した自前ウィンドウも他のプロセスが所有するウィンドウも、共通のメソッド・プロパティで操作可能です。&lt;br /&gt;移動やリサイズなどの一般的な操作から、表示スタイルの変更などの手動ではできない操作まで、様々な操作を行なえます。&lt;br /&gt;ウィンドウを移動したりリサイズするには、「moveTo()」メソッドを使用します。移動せずリサイズするだけの「resize()」メソッドもあります。&lt;br /&gt;&lt;br /&gt;ウィンドウをデスクトップの横半分を占めるように広げたい場合などは、ディスプレイの情報を取得する「Display」クラスを使い、下記のようにするとよいでしょう。&lt;br /&gt;&lt;pre&gt;var {Window,Display}=require('Window');&lt;br /&gt;var a=Display.active.work;&lt;br /&gt;Window.active.moveTo(a.left,a.top,a.width/2,a.height);&lt;br /&gt;&lt;/pre&gt;Displayクラスには、プライマリディスプレイを取得する「Display.primary」の他、アクティブウィンドウがあるディスプレイを取得する「Display.active」や、マウスカーソルがあるディスプレイを取得する「Display.pointed」などもあります。&lt;br /&gt;Displayオブジェクトの「work」プロパティでは、タスクバーなどの領域を除いた作業領域の範囲を取得できます。&lt;br /&gt;これらの値を元にした座標やサイズを「Window.active.moveTo()」に渡せば、画面に合せてアクティブウィンドウを移動・リサイズできます。&lt;br /&gt;「Window.find()」などを使えば、アクティブウィンドウ以外の特定のウィンドウを表すWindowオブジェクトを取得して操作することも可能です。&lt;br /&gt;&lt;br /&gt;Hotstrokesの操作に対して割り当てて好きなときに呼び出したり、「Window.observe()」でウィンドウの出現などを監視して自動操作したり、ブラウザなどの常用ソフトのウィンドウをリサイズしてすぐに終了するスクリプトを作成して必要なときに実行したりして利用するといいでしょう。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;なお、ブラウザなど常に起動しているソフトのウィンドウの位置・サイズを固定して長時間常時表示させていると、枠などの変化のない部分の映像がディスプレイに焼き付いてしまうことがあるので注意してください。&lt;br /&gt;液晶ディスプレイでは焼き付きは起こらないという話がありますが、1万時間くらい同じ映像を表示させているとさすがに多少焼き付いてしまうようです。&lt;br /&gt;画面全体が#202020くらいの暗い色になっているときでないと分からないので、全画面で動画再生やゲームをする人でなければ気にならないでしょうが。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-1198068008837135355?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/1198068008837135355/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_27.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/1198068008837135355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/1198068008837135355'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_27.html' title='ウィンドウを画面の横半分などにリサイズ・移動'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2305899980260847070</id><published>2010-09-26T12:11:00.000+09:00</published><updated>2010-09-26T12:11:36.629+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><category scheme='http://www.blogger.com/atom/ns#' term='使用例'/><title type='text'>ウィンドウ生成機能でデスクトップ上に字幕を表示</title><content type='html'>NILScriptでは、ウィンドウを生成して情報を表示したり入力を受け付けたりすることも出来ます。&lt;br /&gt;通常はメモ帳などのアプリケーションと同じタイトルバー付きのウィンドウになりますが、Window.create()のオプションでスタイルを指定する事で、枠のないウィンドウやタスクバーに表示されないウィンドウなども作れます。&lt;br /&gt;今回は、これらのオプションを駆使してデスクトップ上に字幕を表示させる例を紹介します。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_wiFD7NiUNAg/TJ61PVlyvCI/AAAAAAAAACI/a3cCXJ_hI3U/s1600/20100926114917.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="109" src="http://3.bp.blogspot.com/_wiFD7NiUNAg/TJ61PVlyvCI/AAAAAAAAACI/a3cCXJ_hI3U/s320/20100926114917.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;下記のようなスクリプトで、上の画像の「Warning!!」の部分のようなテキストを表示させられます。&lt;br /&gt;&lt;pre&gt;var win=require('Window').Window.create({&lt;br /&gt;    isPopupWindow:true,hasTickFrame:false,hasBorder:false,hasDlgFrame:false,&lt;br /&gt;    toolWindow:true, &lt;br /&gt;    topmost:true,&lt;br /&gt;    transparent:true,&lt;br /&gt;    transparentColor:0xFF01FF,&lt;br /&gt;    alpha:196,&lt;br /&gt;    width:0,height:0,&lt;br /&gt;    children:{ie:{type:require('ATL').Trident,top:0,left:0,right:0,bottom:0}},&lt;br /&gt;});&lt;br /&gt;win.resize(800,120,true).moveToCenter();&lt;br /&gt;win.ie.update('&amp;lt;body style="margin:0;background-color:#FF01FF;overflow:hidden;text-align:center; font-size:96px;color:#FF0000;"&amp;gt;Warning!!&amp;lt;/body&amp;gt;');&lt;br /&gt;win.show();&lt;br /&gt;sleep(3000);&lt;br /&gt;win.close();&lt;br /&gt;&lt;/pre&gt;オプションの1行目の4つの項目は、タイトルバーやウィンドウ周辺の枠を無くすオプションです。余計な物をなるべく表示させたくないときに利用するといいでしょう。&lt;br /&gt;「toolWindow」は、タスクバー上にボタンを表示しないようにするするオプションです。&lt;br /&gt;これらのオプションを指定すると、通常の方法ではウィンドウを閉じられなくなるので、必要に応じてウィンドウを隠したり閉じたりする処理を用意してください。&lt;br /&gt;&lt;br /&gt;「topmost」は、ウィンドウを常に最前面に表示させるオプションです。アクティブウィンドウの上に表示させたい場合などに指定します。&lt;br /&gt;&lt;br /&gt;「transparent」はクリックなどを下のウィンドウに透過させるオプションです。主にtopmostと組み合わせて使います。クリックして操作する必要のない情報表示用ウィンドウで、誤ってクリックして操作の妨げとなることを防ぎたい場合などに指定するといいでしょう。&lt;br /&gt;&lt;br /&gt;「transparentColor」はウィンドウ上の特定の色の部分を完全に透明にするオプションです。字幕などを表示するときは、このオプションで背景を透過させます。透過色は「0xRRGGBB」の形式の数値で指定します。本来透過させるつもりでない部分に使われている色と被ってしまわないように、なるべく使われなさそうな色を指定します。&lt;br /&gt;また、「alpha」では、透過色以外のウィンドウ全体の不透明度を0～255の数値で指定できます。ゼロに近いほど透明になります。&lt;br /&gt;&lt;br /&gt;ウィンドウの大きさを指定する「width」と「height」は、作成オプションでは両方ゼロにしておき、後から「resize()」で適当な大きさにしています。これは、たまに透過指定した背景色が描画されていない状態で一瞬だけ表示されてしまうことがあるのを防ぐためです。なお、「moveToCenter()」は、ウィンドウを画面中央に位置するように移動するメソッドです。&lt;br /&gt;&lt;br /&gt;ウィンドウ内に配置するコントロールを定義する「children」では、背景色や文字スタイルなどを柔軟に指定できるように、ウィンドウ全体にIEコンポーネントを配置することにします。&lt;br /&gt;IEコンポーネント上に表示する内容は、後の「win.ie.update()」で指定します。ここでは、body要素のstyle属性で文字のスタイルや背景色を指定したり、マージンやスクロールバーなどを削除しています。背景色には、transparentColorで指定したのと同じ色を指定します。&lt;br /&gt;body要素内のHTMLには、今回は単なるテキストを指定しましたが、HTMLで装飾を加えたりしてもよいでしょう。ただし、スタイルシートの透過機能などで背景色と混じった部分は透過されなくなってしまうので注意してください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2305899980260847070?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2305899980260847070/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_26.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2305899980260847070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2305899980260847070'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_26.html' title='ウィンドウ生成機能でデスクトップ上に字幕を表示'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_wiFD7NiUNAg/TJ61PVlyvCI/AAAAAAAAACI/a3cCXJ_hI3U/s72-c/20100926114917.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8236674976128118064</id><published>2010-09-26T03:21:00.001+09:00</published><updated>2010-09-27T00:17:32.609+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP'/><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>HTTPでファイルのアップロードを行う</title><content type='html'>NILScriptには、HTTPでリクエストを送信してレスポンスを得る機能も用意されています。&lt;br /&gt;一発でレスポンスボディを得られる手軽なメソッドや、レスポンスボディをストリームとして逐次読み込みするオブジェクトを返すメソッドなどが用意されている他、リクエストヘッダの指定やプロキシの使用など、柔軟な動作設定も可能です。&lt;br /&gt;WSHなどでは実現が面倒なファイルのアップロードも、下記の例のように簡単に実現できます。&lt;br /&gt;&lt;pre&gt;require('HTTP').HTTP.post(url,{&lt;br /&gt; upfile:new File(filePath),&lt;br /&gt; pass:"test",&lt;br /&gt; com:"this is test of file upload",&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;ファイルのアップロードを行うには、POSTによるリクエストを行うpost()メソッドを使用します。&lt;br /&gt;第1引数はリクエストするURL(HTMLのform要素のaction属性で指定される物)を、第2引数にはフォームの項目名と項目内容のペアを列挙したオブジェクトを指定します。&lt;br /&gt;ここで項目内容としてFileオブジェクトが指定されていると、そのファイルの内容がアップロードされます。&lt;br /&gt;上記の例では、変数に格納されたフルパスを元にFileコンストラクタを呼び出していますが、&lt;a href="http://nilscript.blogspot.com/2010/09/blog-post_4430.html"&gt;実行時にファイルの指定を受け付ける様々な方法&lt;/a&gt;の記事で紹介したような方法で得たFileオブジェクトを指定してもよいでしょう。&lt;br /&gt;post()メソッドは、アップロード完了後に表示されるページの内容などのレスポンスボディ文字列を返します。アップロードされたファイルのURLを得たい場合などは、返り値の内容を正規表現マッチングで調べたりするとよいでしょう。&lt;br /&gt;&lt;br /&gt;なお、NILScriptのHTTPには、非同期的な処理を行う機能は用意されていないません。&lt;br /&gt;リクエストを開始したら即座に次の処理に進みたい場合には、「Thread.create()」で生成したスレッド内でリクエストを実行することで非同期化してください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8236674976128118064?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8236674976128118064/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/09/http.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8236674976128118064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8236674976128118064'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/09/http.html' title='HTTPでファイルのアップロードを行う'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-6538602461948629070</id><published>2010-09-24T22:52:00.000+09:00</published><updated>2010-09-24T22:52:41.030+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ファイル'/><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><category scheme='http://www.blogger.com/atom/ns#' term='クリップボード'/><title type='text'>実行時にファイルの指定を受け付ける様々な方法</title><content type='html'>ファイルに対して何らかの処理を行うスクリプトでは、実行時に処理対象ファイルを指定できるようにしておくと便利です。&lt;br /&gt;今回は、ファイルの指定を受け付ける方法をいくつかまとめて紹介します。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;ダイアログ&lt;/h4&gt;「Dialog」ユニットに用意されているFileDialogを使用すれば、標準的なファイル選択ダイアログを表示してファイルを選択させられます。&lt;br /&gt;素早い操作には向きませんが、ソフトの操作に慣れていないユーザーに使わせる場合などには、この方法が一番分かりやすいでしょう。&lt;br /&gt;&lt;br /&gt;下記は、ダイアログを表示して選択させたファイルの合計サイズを「alert()」関数でダイアログ表示するという例です。&lt;br /&gt;FileDialogでは、複数選択の可否や初期表示ディレクトリなど様々な挙動をオプションで指定できます。詳細な説明は、同梱の「doc\Dialog.txt」を参照してください。&lt;br /&gt;show()の返り値は、multiSelectがfalseの場合は一つのFileオブジェクト、trueの場合はFileオブジェクトの配列になります。Fileオブジェクトの機能については、doc\base_io.txtを参照してください。&lt;br /&gt;「sum()」は、配列オブジェクトに追加された拡張メソッドで、指定プロパティの合計値を返します。&lt;br /&gt;&lt;pre&gt;var fileArray=require('Dialog').FileDialog.show({&lt;br /&gt; directory:"D:\\bin",&lt;br /&gt; multiSelect:true,&lt;br /&gt;});&lt;br /&gt;alert(fileArray.sum("size"));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;コマンドライン引数&lt;/h4&gt;コマンドライン引数で対象ファイルを指定できるようにしておけば、スクリプトファイルやショートカットのアイコンへのドラッグ&amp;ドロップの他、「送る」メニューへの登録やコマンドプロンプトからの実行、他のソフトの外部アプリ呼び出し機能での利用など、様々な使い方が可能になります。&lt;br /&gt;&lt;br /&gt;スクリプトへのコマンドライン引数は、「Main.params」というプロパティで配列として取得できますが、配列の各要素は単なる文字列ですので、ファイルに関する操作を行うには、Fileオブジェクトに変換してやる必要があります。　&lt;br /&gt;コマンドプロンプトなどから相対パスを指定して実行した時にも対応できるように「cwd().file()」を利用するといいでしょう。「cwd()」はカレントディレクトリのDirectoryオブジェクトを得る関数、「file()」は相対/絶対パスで指定したファイルのFileオブジェクトを得るメソッドです。&lt;br /&gt;&lt;br /&gt;コマンドライン引数で与えられたファイルの合計サイズを表示するスクリプトは、以下のようになります。&lt;br /&gt;&lt;pre&gt;var fileArray=[];&lt;br /&gt;for(var i=0,a=Main.params,l=a.length;i&amp;lt;l;i++){&lt;br /&gt; fileArray.push(cwd().file(a[i]));&lt;br /&gt;}&lt;br /&gt;alert(fileArray.sum("size"));&lt;br /&gt;&lt;/pre&gt;さらに使い勝手を高めるには、コマンドライン引数が指定されなかった場合にファイル選択ダイアログを表示するなどの処理を追加するといいでしょう。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;クリップボード経由&lt;/h4&gt;NILScriptには、エクスプローラなどでのCtrl+Cでコピーされたファイルリストを読み取る機能が用意されています。&lt;br /&gt;この機能を利用すれば、クリップボード経由で処理対象ファイルを指定する方式のスクリプトを作成可能です。&lt;br /&gt;ファイル選択ダイアログやウィンドウへのドラッグ&amp;ドロップよりも素早い操作で利用できるので、「送る」などに登録するほど利用頻度が高くないスクリプトを作る場合におすすめです。&lt;br /&gt;&lt;br /&gt;クリップボードに格納されているファイルの配列は、下記のようにすることで取得できます。ファイルが格納されていない時はfilesがundefinedになるので、ファイル以外をコピーしている場合はゼロ個のファイルとして扱いたい場合は、「||[]」を付けて空の配列に置き換わるようにしておきます。&lt;br /&gt;なお、クリップボードの内容は確認しづらいので、重大な処理を行うスクリプトでは、間違ったファイルをコピーした状態で実行してしまわないように、確認ダイアログを表示する「confirm()」などによる確認処理を組み込んでおくとよいでしょう。&lt;br /&gt;&lt;pre&gt;var fileArray=require('Clipboard').Clipboard.files||[];&lt;br /&gt;if(confirm(fileArray.join("\n"))){&lt;br /&gt; alert(fileArray.sum("size"));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;ウィンドウへのD&amp;D受け付け&lt;/h4&gt;ウィンドウを表示するタイプのツールでは、ウィンドウにファイルをドラッグ&amp;ドロップすることでファイルを指定できるようにしておくと便利です。&lt;br /&gt;本来はウィンドウを必要としない処理でも、処理対象ファイルを好きな時に指定できるようにしたい場合などは、ドラッグ&amp;ドロップによるファイル指定を受け付けるためのウィンドウを用意するとよいでしょう。&lt;br /&gt;ウィンドウへのファイルドロップを受け付けるには、Window.create()のオプションで「acceptFiles」をtrueにし、「events」の「dropFiles」にイベントハンドラ関数を指定します。&lt;br /&gt;イベントハンドラの第1引数オブジェクトの「files」メンバで、ドロップされたファイルを表すFileオブジェクトの配列を取得できます。&lt;br /&gt;&lt;pre&gt;with(require('Window')){&lt;br /&gt; Window.create({&lt;br /&gt;  width:320,height:240,topmost:true,&lt;br /&gt;  children:{&lt;br /&gt;   edit:{&lt;br /&gt;    type:Edit,multiline:true,readOnly:true,&lt;br /&gt;    left:0,top:0,right:0,bottom:0,&lt;br /&gt;   },&lt;br /&gt;  },&lt;br /&gt;  acceptFiles:true,&lt;br /&gt;  events:{&lt;br /&gt;   dropFiles:function(o){&lt;br /&gt;    this.edit.text=o.files.join("\r\n")+"\r\n合計バイト数: "+o.files.sum("size");&lt;br /&gt;   },&lt;br /&gt;  },&lt;br /&gt; }).moveToCenter().show();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-6538602461948629070?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/6538602461948629070/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_4430.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6538602461948629070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6538602461948629070'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_4430.html' title='実行時にファイルの指定を受け付ける様々な方法'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-3636771601499159163</id><published>2010-09-24T20:07:00.000+09:00</published><updated>2010-09-24T20:07:39.903+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='自動化'/><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>省電力状態からの自動復帰も可能なタイマー機能</title><content type='html'>NILScriptに用意されている「Timer」クラスには、コンピュータがサスペンドやハイバネート状態になっても指定時間経過後に自動復帰させる機能が用意されています。&lt;br /&gt;この機能を利用すれば、サーバが空いている時間帯を利用してのダウンロードなどの待ち時間の長い自動処理を行う際に、予定時刻を待っている間コンピュータを起動したままにしておく必要が無くなり、電力を節約できます。&lt;br /&gt;この機能を利用するには、Timerオブジェクトのコンストラクタで第4引数にtrueを指定します。Timerの使用方法については、同梱のdoc\base_task.txtを参照してください。&lt;br /&gt;&lt;br /&gt;復帰とは逆に、スクリプト上からサスペンドやハイバネートを実行するためのメソッドも用意されています。これらは「System.suspend()」や「System.hibernate()」というSystemクラスのメソッドとなっています。&lt;br /&gt;また、サスペンドやハイバネート状態に移行し、指定時間後に自動復帰するという処理を行う「System.suspendFor()」や「System.hibernateFor()」というメソッドも用意されています。これらの機能の説明は、doc\base_main.txtにあります。&lt;br /&gt;&lt;br /&gt;なお、タイマーによる復帰機能では、タイマーで指定した時間に復帰処理が始まるため、復帰が完了して予約された処理が実行されるまでには数秒～数十秒のタイムラグがあることに注意しなければなりません。&lt;br /&gt;テレビの自動録画のように遅れることが許されない処理では、予約実行のタイマーとは別に、予定時刻の1～2分前に自動復帰させるためのタイマーをセットしておくとよいでしょう。&lt;br /&gt;この場合、「System.awake()」というメソッドを使用すれば、単にサスペンド・ハイバネートから復帰するだけのタイマーを生成できます。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-3636771601499159163?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/3636771601499159163/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_24.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3636771601499159163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3636771601499159163'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_24.html' title='省電力状態からの自動復帰も可能なタイマー機能'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-6767407970864682467</id><published>2010-09-21T23:49:00.000+09:00</published><updated>2010-09-21T23:49:46.888+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='自動化'/><category scheme='http://www.blogger.com/atom/ns#' term='新機能'/><category scheme='http://www.blogger.com/atom/ns#' term='使用例'/><title type='text'>プロセスのCPU使用率を監視して自動処理</title><content type='html'>先日の更新で、CPUの使用状況などを取得するためのクラスを提供する「SystemMonitor」ユニットが追加されました。&lt;br /&gt;このユニットには、「CPU」、「ProcessCPU」、「Network」、「PerformanceCounter」の4つのクラスが用意されています。&lt;br /&gt;「CPU」クラスでは、システム全体のCPU使用率が取得できます。マルチプロセッサの個別の稼働状況も取得可能です。&lt;br /&gt;「ProcessCPU」クラスでは、指定のプロセスのCPU使用率を取得できます。&lt;br /&gt;「Network」は、ネットワークインターフェイスの転送量を取得するクラスです。複数のネットワークインターフェイスの個別の転送量も取得できます。&lt;br /&gt;他にも、「PerformanceCounter」を使うことで、HDDの読み書き量など様々な情報を取得できます。&lt;br /&gt;また、標準クラスである「System」には「memory」メンバとしてシステムのメモリ使用状況を取得するメンバが追加された他、以前からProcessインスタンスの「pagefileUsage」プロパティや「workingSetSize」プロパティでプロセスごとのメモリ使用状況を取得可能になっています。&lt;br /&gt;&lt;br /&gt;これらの機能は、タスクマネージャのような情報表示だけでなく、自動処理を進める条件などとしても役立つでしょう。&lt;br /&gt;例えば、動画のエンコードなどの時間のかかる処理が終ってから別の処理を自動実行させたいけれどエンコードソフトがプロセスの存続やウィンドウのテキストなどによる終了判定がしにくい仕様になっている場合に、プロセスのCPU使用率が低くなった時点で処理完了とみなすといった具合です。&lt;br /&gt;&lt;br /&gt;このような場合、以下の例のようなスクリプトで、処理の完了まで待機させることが出来ます。&lt;br /&gt;&lt;pre&gt;var p=Process.find("VirtualDub.exe");&lt;br /&gt;try{&lt;br /&gt;    var mon=new (require('SystemMonitor').ProcessCPU)(p);&lt;br /&gt;    sleep(1000);&lt;br /&gt;    while(mon.get()&gt;0.05){&lt;br /&gt;        sleep(1000);&lt;br /&gt;    }&lt;br /&gt;}finally{&lt;br /&gt;    free(mon);&lt;br /&gt;}&lt;br /&gt;sleep(10000);&lt;br /&gt;//以降にエンコード終了後の処理を記述&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;最初の行で、監視対象となるProcessオブジェクトを取得しています。&lt;br /&gt;この例では、既に実行中のプロセスを取得する「Process.find()」を使っていますが、「Process.create()」でプロセスの起動から自動化してもよいでしょう。&lt;br /&gt;「var mon=new (require('SystemMonitor').ProcessCPU)(p);」で、そのプロセスのCPU使用率を取得するためのProcessCPUオブジェクトを生成しています。&lt;br /&gt;プロセスのCPU使用率を取得するには、このオブジェクトの「get()」メソッドを呼び出します。&lt;br /&gt;このメソッドは、前回呼び出し時かインスタンス生成時から今回呼び出し時までの期間のCPU使用率を返すので、インスタンス後に即座に呼び出してしまうと正常な値が取得できないため、最初のget()呼び出しの前にもsleep()が呼び出されるようにしておく必要があります。&lt;br /&gt;get()の返り値は0～1の間の小数となるので、上記の例ではCPU使用率が5%以下になるまでループし続けることになります。&lt;br /&gt;CPU使用率が低くなった直後は、まだファイルへの書き込みなどの処理が行われている可能性があるので、数秒程度sleep()してから次の処理に進むようにするとよいでしょう。&lt;br /&gt;なお、「free(mon)」は、監視オブジェクトで使用したリソースを解放するための処理ですが、一連の処理を実行してすぐに終了するタイプのスクリプトでは、省略しても問題は無いでしょう。&lt;br /&gt;&lt;br /&gt;なお、CPUやNetwork、PerformanceCounterクラスも、インスタンスを生成してget()で値を取得するという流れはProcessCPUと同じです。&lt;br /&gt;コンストラクタに渡す引数やget()が返す内容などの詳しい仕様は、同梱のdoc\SystemMonitor.txtを参照してください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-6767407970864682467?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/6767407970864682467/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/09/cpu.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6767407970864682467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6767407970864682467'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/09/cpu.html' title='プロセスのCPU使用率を監視して自動処理'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-7238023961547490428</id><published>2010-09-01T23:15:00.000+09:00</published><updated>2010-09-01T23:15:05.292+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='スクリプト作成補助'/><title type='text'>クリックしたウィンドウのクラス名をコピーするスクリプト</title><content type='html'>Hotstrokesの条件割り当てなどでは、ウィンドウの「クラス名」を指定する事がよくあります。&lt;br /&gt;ウィンドウのクラス名は、Windowsのウィンドウの種類を表す文字列です。NILScriptに用意されているクラスの仕組みとは、特に関係はありません。&lt;br /&gt;タイトルバーの文字列と違って、クラス名は画面に表示されたりしないので、調べるには何らかのツールを使う必要があります。&lt;br /&gt;そこで、クリックしたウィンドウのクラス名をクリップボードにコピーするスクリプトの例を紹介します。&lt;br /&gt;&lt;pre&gt;use('Mouse','Window','Clipboard');&lt;br /&gt;Mouse.wait('lbuttonUp');&lt;br /&gt;Clipboard.text=Window.fromPoint(Mouse.x,Mouse.y).className;&lt;br /&gt;&lt;/pre&gt;実行すると「Mouse.wait('lbuttonUp');」によってマウスの左ボタンが押されるまで待機状態になるので、クラス名を調べたいウィンドウをクリックしてください。&lt;br /&gt;次の行では、クリップボードにテキストとしてウィンドウのクラス名がセットされます。&lt;br /&gt;「Window.fromPoint()」は、デスクトップ全体における指定座標に存在する最も前面のウィンドウを表すWindowオブジェクトを返すクラスメソッドで、Windowオブジェクトの「className」プロパティでクラス名を取得できます。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-7238023961547490428?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/7238023961547490428/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_01.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7238023961547490428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/7238023961547490428'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post_01.html' title='クリックしたウィンドウのクラス名をコピーするスクリプト'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8344984585518144236</id><published>2010-09-01T21:50:00.002+09:00</published><updated>2010-09-01T21:50:52.555+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><category scheme='http://www.blogger.com/atom/ns#' term='使用例'/><title type='text'>最小化されたウィンドウをタスクトレイに格納する</title><content type='html'>NILScriptでは「Main.createNotifyIcon()」でスクリプトの終了などの操作を行うためのタスクトレイアイコンを生成できますが、他にも任意の数のタスクトレイアイコンを生成できます。&lt;br /&gt;これを利用し、特定の種類のウィンドウが最小化された時にそのウィンドウをタスクバーに表示されないようにして代わりにタスクトレイアイコンとして表示するというスクリプトの例を紹介します。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Main.createNotifyIcon();&lt;br /&gt;var targetClasses=['Notepad','MSPaintApp'];&lt;br /&gt;var {Window}=require('Window');&lt;br /&gt;var prev=Window.active;&lt;br /&gt;var myWindow=Window.create();&lt;br /&gt;Window.observe('activate',function(o){&lt;br /&gt;    if(prev.minimized &amp;&amp; (o.window.handle!=prev.handle) &amp;&amp; targetClasses.contains(prev.className)){&lt;br /&gt;        var w=prev;&lt;br /&gt;        w.hide();&lt;br /&gt;        var restore=function(){&lt;br /&gt;            w.show();&lt;br /&gt;            w.restore();&lt;br /&gt;        };&lt;br /&gt;        Main.observe('exit',restore);&lt;br /&gt;        myWindow.addNotifyIcon({&lt;br /&gt;            icon:w.icon,&lt;br /&gt;            text:w.title,&lt;br /&gt;            events:{&lt;br /&gt;                lbuttonUp:function(){&lt;br /&gt;                    restore();&lt;br /&gt;                    Main.unobserve('exit',restore);&lt;br /&gt;                    this.free();&lt;br /&gt;                },&lt;br /&gt;            },&lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;    prev=o.window;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;「Window.observe()」でウィンドウの状態変化を監視するイベントハンドラを登録しています。&lt;br /&gt;Window.observe()が利用しているシェル用のフック機能では、最小化を直接検出することは出来ないようなので、アクティブウィンドウが変った時に前にアクティブだったウィンドウの状態を調べるという方法で代用しています。&lt;br /&gt;最小化ボタンによる通常の最小化ならば、この方法で問題なく検出できるようです。&lt;br /&gt;&lt;br /&gt;Window.observe()では、イベントハンドラの第1引数に与えられるオブジェクトの「window」メンバでイベントが発生したウィンドウを参照できますが、ここでは「prev」変数に代入されている直前にアクティブだったウィンドウの方が対象となります。prevのウィンドウが最小化されていなかったり、対象クラス名に一致しない場合は、単にprev変数に今回アクティブ化されたウィンドウを代入して終ります。&lt;br /&gt;なお、prev変数は最初の定義時にアクティブウィンドウを表す「Window.active」で初期化してあります。&lt;br /&gt;&lt;br /&gt;対象ウィンドウが最小化された場合、ウィンドウの不可視化、スクリプト終了時にウィンドウを復元する処理の登録、トレイアイコンの登録の3つの処理を行います。&lt;br /&gt;その前に、最初の「var w=prev」で、その時最小化されたウィンドウを表すオブジェクトを変数に代入しておく必要があります。こうしておかないと、prev変数が書き換わってしまい、どのウィンドウを対象にしていたのか分からなくなってしまうからです。&lt;br /&gt;このローカル変数「w」はJavaScriptの「クロージャ」という仕組みでrestoreやlbuttonUpにセットした関数から参照されており、次に最小化時処理が行われる時には、新たなw変数が生成され、新たに生成されたrestoreやlbuttonUpの関数から参照されます。&lt;br /&gt;&lt;br /&gt;ウィンドウの可視化と最小化からの復元を行う処理は、関数として「restore」変数に代入して、「Main.observe('exit',restore)」でスクリプト終了時にも実行されるようにイベント割り当てを行っておきます。&lt;br /&gt;&lt;br /&gt;トレイアイコンの登録は、自前ウィンドウのオブジェクトの「addNotifyIcon()」メソッドで行います。ここでは、あらかじめWindow.create()で生成して「myWindow」変数に代入しておいた空の自前ウィンドウを使用しています。&lt;br /&gt;引数となるオプションオブジェクトのiconメンバには、今回最小化されたウィンドウのアイコンである「w.icon」を指定しています。ここでは、他にもアイコンファイルや実行ファイルのパスを指定することも可能です。&lt;br /&gt;トレイアイコンの操作イベントに対する動作割り当てを定義するeventsでは、左クリック時に発生するlbuttonUpイベントに対して、復元関数の呼び出しとスクリプト終了時のイベント登録の解除、トレイアイコン自身の削除の3つの処理を行う関数を割り当てています。&lt;br /&gt;&lt;br /&gt;このトレイアイコン生成機能を利用すれば、様々なツールを手軽に実現できるでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8344984585518144236?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8344984585518144236/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8344984585518144236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8344984585518144236'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/09/blog-post.html' title='最小化されたウィンドウをタスクトレイに格納する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-1839529407426076089</id><published>2010-09-01T15:35:00.000+09:00</published><updated>2010-09-01T15:35:17.207+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hotstrokes'/><category scheme='http://www.blogger.com/atom/ns#' term='クリップボード'/><category scheme='http://www.blogger.com/atom/ns#' term='使用例'/><title type='text'>選択テキストをWeb検索するHotstrokes定義</title><content type='html'>選択中の文字列をパラメータにして検索サイトのURLを開くなど、エディタやブラウザでの選択文字列に対して処理を行いたいことはよくあります。&lt;br /&gt;&lt;br /&gt;NILScriptでは、「Window」ユニットの「Edit」クラスに用意されている「selection」プロパティで選択文字列の読み書きを行なえますが、エディットコントロール側がエディタ関連のウィンドウメッセージに応答するように作られている必要があり、全ての選択テキストに対して有効なわけではありません。&lt;br /&gt;エディタ関連メッセージに未対応のテキストエディタやブラウザなどからは、別の方法で選択テキストを取得しなければなりません。&lt;br /&gt;一番汎用的だと思われるのは、Ctrl+Cなどを送信してコピーを実行し、クリップボードにコピーされたテキストを取得する方法でしょう。&lt;br /&gt;&lt;br /&gt;下記に挙げるのが、エディタ関連メッセージに対応したコントロールではselection、それ以外のコントロールではクリップボードを使用して選択テキストを取得しGoogle検索するという機能をHotstrokesに割り当てるスクリプトです。&lt;br /&gt;&lt;pre&gt;Main.createNotifyIcon();&lt;br /&gt;var {Clipboard}=require('Clipboard');&lt;br /&gt;var {Hotstrokes}=require('Hotstrokes');&lt;br /&gt;var {Edit}=require('Window');&lt;br /&gt;Hotstrokes.defineConditions({&lt;br /&gt; 'Editor':function()(['Edit','TEditorX'].contains(this.focusedWindow.className)),&lt;br /&gt;}).map({&lt;br /&gt; 'Win+G':{&lt;br /&gt;  'Editor':function(){&lt;br /&gt;   this.cancel();&lt;br /&gt;   exec('http://www.google.com/search?q='+encodeURIComponent(Edit.focused.selection));&lt;br /&gt;  },&lt;br /&gt;  '':function(){&lt;br /&gt;   this.cancel();&lt;br /&gt;   Thread.create(function(){&lt;br /&gt;    var bk=Clipboard.text;&lt;br /&gt;    Hotstrokes.send("Ctrl+C");&lt;br /&gt;    sleep(100);&lt;br /&gt;    exec('http://www.google.com/search?q='+encodeURIComponent(Clipboard.text));&lt;br /&gt;    if(bk){&lt;br /&gt;     Clipboard.text=bk;&lt;br /&gt;    }&lt;br /&gt;   });&lt;br /&gt;  },&lt;br /&gt; },&lt;br /&gt;}).register();&lt;br /&gt;&lt;/pre&gt;最初のdefineConditions()では、「Editor」という条件名にエディタ関連メッセージに対応したコントロールのクラス名を条件とする関数を定義しています。&lt;br /&gt;「contains()」は、引数で指定した値を要素として持つかどうかを返す配列の拡張メソッド、「this.focusedWindow.className」は、ストロークが受理された時にフォーカスを持っているコントロールのクラス名を得る式です。&lt;br /&gt;上記の例では、メモ帳などで使われる基本的なテキスト編集欄であるEditや、VxEditorで使われているTEditorXを対象として定義しています。&lt;br /&gt;&lt;br /&gt;map()では、Windowsキー+Gに対して、条件に応じた動作を割り当てています。&lt;br /&gt;「this.cancel()」というのは、Gキーの押し下げストロークの本来の動作を無効化するという動作です。これがないと、「g」という文字が入力されて選択テキストが上書きされてしまうでしょう。&lt;br /&gt;&lt;br /&gt;Editorの場合の動作では「Edit.focused.selection」でフォーカスのあるエディタの選択テキストを取得しています。「Edit.forused」は、フォーカスのあるコントロールをEditクラスのインスタンスとして取得するというEditクラスのプロパティです。&lt;br /&gt;exec()は、システムの関連付けに従ってファイルやURLを開く関数、encodeURIComponent()はURLのパラメータとして使えるように文字列をエンコードするJavaScript標準の関数です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;他の条件に一致しなかった時に参照されるデフォルト動作である「''」に対する割り当てでは、this.cancel()以外を「Thread.create()」によって新規スレッドで実行しています。&lt;br /&gt;sleep()などを含み時間がかかる処理は、そのまま実行すると動作が不安定になってしまう場合があるので、このようにして新規スレッドで実行させるように習慣づけておくとよいでしょう。&lt;br /&gt;スレッド内では、クリップボードのテキストを変数にバックアップし、Ctrl+Cを送信し、コピー処理が完了するのをsleep()で待って、検索結果のURLを開き、バックアップしたテキストがあれば書き戻すという処理を行っています。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-1839529407426076089?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/1839529407426076089/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/09/webhotstrokes.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/1839529407426076089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/1839529407426076089'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/09/webhotstrokes.html' title='選択テキストをWeb検索するHotstrokes定義'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-720184381175980659</id><published>2010-08-31T23:57:00.001+09:00</published><updated>2010-08-31T23:58:20.745+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='新機能'/><title type='text'>ActiveXオブジェクトに対応</title><content type='html'>ここ数日の更新で、ActiveXのオブジェクトを扱う「COM」ユニットと「ATL」ユニットが新たに追加されました。&lt;br /&gt;&lt;br /&gt;COMユニットでは、WSHのActiveXObjectのように、InternetExplorerなどのプログラムの制御などを行なえます。&lt;br /&gt;WSHではIDispatchが実装されたオブジェクトしか扱えませんが、NILScriptのCOMでは「Unknown.define()」でメソッドの定義を指定してラッパークラスを登録することで、他のインターフェイスしか持たないオブジェクトの操作も可能となっています。&lt;br /&gt;イベントハンドラの登録は、EventMixinによって実装されており、他のNILScriptオブジェクトと同じ感覚で使用できます。&lt;br /&gt;一方、Dispatchオブジェクトを手動で開放しなければならないなど、WSHのJScriptとはいくつかの点で使い勝手が異なっているので注意してください。&lt;br /&gt;&lt;br /&gt;ATLユニットでは、Windowユニットで提供される自前ウィンドウ生成機能でIEコンポーネントなどのActiveXコントロールを使用するためのクラスが提供されます。&lt;br /&gt;IEコンポーネントをHTTPDと組み合わせれば、様々なインターフェイスを手軽に実現できるでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-720184381175980659?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/720184381175980659/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/activex.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/720184381175980659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/720184381175980659'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/activex.html' title='ActiveXオブジェクトに対応'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5331177603238358023</id><published>2010-08-20T00:51:00.002+09:00</published><updated>2010-08-20T09:34:41.890+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ファイル'/><category scheme='http://www.blogger.com/atom/ns#' term='クリップボード'/><title type='text'>クリップボードにファイルをコピーする</title><content type='html'>NILScriptのClipboardユニットでは、エクスプローラなどでCtrl+C/Ctrl+Vでのコピー・移動を行う時に使用されるファイルリスト形式なども扱えます。&lt;br /&gt;Hotstrokesなどの機能と組み合わせれば、ファイルの管理を効率化する機能を実現するのに役立つはずです。&lt;br /&gt;&lt;br /&gt;クリップボードにファイルをコピーするには、「Clipboard.files」というプロパティにFile/Directoryオブジェクトやファイルパス文字列、あるいはその配列を代入すればよいのですが、filesのみをセットした場合「切り取り」と「コピー」のどちらの扱いになるかが不定であることに注意しなければなりません。この状態でエクスプローラに「貼り付け」を行った場合、エクスプローラから「切り取り」していた時と同じように、ファイルが移動されてしまいます。&lt;br /&gt;&lt;br /&gt;移動ではなくコピーにしたい場合、複数の形式を同時にセットできる「contents」プロパティを使って、「isMove」という形式と共にセットします。&lt;br /&gt;isMoveは、その名の通り「移動」扱いにするかどうかを表す情報で、真偽値として読み書きできます。&lt;br /&gt;下記のようにすれば、指定のファイルを「コピー」扱いでクリップボードに格納できます。&lt;br /&gt;&lt;pre&gt;var Clipboard=require('Clipboard').Clipboard;&lt;br /&gt;var f=Main.directory.file('readme.txt');&lt;br /&gt;Clipboard.contents={isMove:false, files:f};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;クリップボードに格納されたファイルは、Clipboard.filesを参照することで、File/Directoryオブジェクトの配列として取得できます。&lt;br /&gt;この時、ファイルリストがコピーされていない場合はundefinedとして取得されることに注意してください。undefinedを配列として扱おうとすると、エラーになってしまいます。&lt;br /&gt;ファイルリストがコピーされていない場合は要素数ゼロの配列とみなしてしまってよい場合は、下記のように「||[]」を加えておくとよいでしょう。&lt;br /&gt;&lt;pre&gt;var Clipboard=require('Clipboard').Clipboard;&lt;br /&gt;for(var i=0, a=Clipboard.files||[], l=a.length; i&amp;lt;l; i++){&lt;br /&gt; println(a[i].path+'('+a[i].size+')');&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;また、下記のようにして、ファイルリスト形式が格納されている場合のみ処理を行わせるという方法もあります。&lt;br /&gt;&lt;pre&gt;var Clipboard=require('Clipboard').Clipboard;&lt;br /&gt;if(Clipboard.hasFormat('files')){&lt;br /&gt; for(var i=0, a=Clipboard.files, l=a.length; i&amp;lt;l; i++){&lt;br /&gt;  println(a[i].path+'('+a[i].size+')');&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5331177603238358023?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5331177603238358023/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_20.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5331177603238358023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5331177603238358023'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_20.html' title='クリップボードにファイルをコピーする'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5311374019638489952</id><published>2010-08-19T23:21:00.001+09:00</published><updated>2010-08-19T23:22:42.592+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='使用例'/><title type='text'>Shift-JISやEUC-JPでURLエンコードを行う</title><content type='html'>HTTPでURLを扱う時は、ASCII文字しか使用してはならないことになっているため、使用できない文字は「%」の後に2桁の16進数文字を続けて1バイトを表す「パーセントエンコーディング」という方式でエンコードしなければなりません。&lt;br /&gt;日本語などのマルチバイト文字の文字コードには特に規定がないため、WebサイトによってUTF-8だったりEUCだったりまちまちです。&lt;br /&gt;&lt;br /&gt;URLをブラウザなどで開く場合、正しくエンコーディングされていないと、ページが開かれなかったり検索ワードが文字化けしてしまうことがあります。&lt;br /&gt;JavaScriptでは、「encodeURI()」や「encodeURIComponent()」という関数でパーセントエンコーディングを行なえますが、文字コードはUTF-8に固定されており、Shift-JISやEUCなどの文字コードでのエンコードはできません。&lt;br /&gt;&lt;br /&gt;Shift-JISやEUCでエンコードされたURLを生成したい場合は、NILScriptに用意されている「MBString.encodeURI()」や「MBString.encodeURIComponent()」を利用してください。&lt;br /&gt;例えば、「keyword」という変数に格納された文字列をShift-JISにエンコードして埋め込んだURLを関連付けに従って開くには、以下のようにします。&lt;br /&gt;実際には、Hotstrokesなどの機能と組み合わせて利用すると良いでしょう。&lt;br /&gt;&lt;pre&gt;exec('http://search.example.com/?q='+MBString.encodeURIComponent(keyword,'sjis'));&lt;br /&gt;&lt;/pre&gt;MBString.encodeURIComponent()は、通常のencodeURIComponent()と違い、第2引数で文字コードを指定できます。&lt;br /&gt;&lt;br /&gt;URLの文字コードを判別するには、ブラウザ上で利用したいサービスのキーワード入力欄から「あ」を検索してみるとよいでしょう。検索結果ページのURLに「%82%A0」が含まれれば「sjis」、「%A4%A2」が含まれれば「euc」、「%E3%81%82」が含まれれば「utf8」を指定すればよいはずです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5311374019638489952?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5311374019638489952/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/shift-jiseuc-jpurl.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5311374019638489952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5311374019638489952'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/shift-jiseuc-jpurl.html' title='Shift-JISやEUC-JPでURLエンコードを行う'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-968951589613510346</id><published>2010-08-18T23:35:00.001+09:00</published><updated>2010-08-18T23:38:41.196+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='使用例'/><title type='text'>プロセスの終了を監視して再起動したりする</title><content type='html'>NILScriptのProcessオブジェクトにはイベント機構が用意されており、「exit」イベントでプロセスの終了を検出できます。システムによるプロセス終了通知機能を利用しているので、定期的にプロセスの有無をチェックするよりも少ない負荷で、高速に応答できます。&lt;br /&gt;&lt;br /&gt;この機能を利用すれば、サーバなどのプロセスが予期せず終了した時に自動的に再起動するというような処理を、下記のような簡単なスクリプトで実現できます。&lt;br /&gt;&lt;pre&gt;var p=Process.find('mspaint.exe')||Process.create('mspaint');&lt;br /&gt;while(true){&lt;br /&gt; p.wait('exit');&lt;br /&gt; p=Process.create('mspaint');&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;「Process.find('mspaint.exe')」は、指定のプロセスが存在していればProcessオブジェクトを返すという処理です。プロセスが存在していなければ「undefined」という値が返ります。「Process.create('mspaint')」は、指定のコマンドラインのプロセスを起動を試み、成功すればProcessオブジェクトを返します。&lt;br /&gt;「||」は、左の式を評価した結果がオブジェクトなどのtruthy値ならその値を返し、undefinedなどのfalsy値ならば右の式を評価した結果を返すという演算子です。左の式がtruthyの場合は、右の式は無視されます。&lt;br /&gt;これらを組み合わせると、「プロセスが存在していればそれを表すProcessオブジェクトを、存在していなければ新たにプロセスを起動してそのProcessオブジェクトを返す」という処理になります。&lt;br /&gt;このような「存在していなければ新規に作成」というテクニックは、よく利用するので覚えておくと良いでしょう。&lt;br /&gt;&lt;br /&gt;p.wait('exit')が肝心の当該プロセスの終了まで待機する処理です。当該プロセスが順調に動作し続ければ、スレッドはこの部分で止まったままとなります。当該プロセスが終了すると、p.wait()から制御が戻り、次の処理に進みます。&lt;br /&gt;次の行では、新たに起動したプロセスのProcessオブジェクトをp変数に代入します。&lt;br /&gt;この2つの処理はwhile文で繰り返し実行されます。&lt;br /&gt;&lt;br /&gt;この処理を他の常駐機能と一緒のスクリプトにまとめたい場合は、下記のようにThread.create()でスレッド化します。&lt;br /&gt;&lt;pre&gt;Thread.create(function(){&lt;br /&gt; var p=Process.find('mspaint.exe')||Process.create('mspaint');&lt;br /&gt; while(true){&lt;br /&gt;  p.wait('exit');&lt;br /&gt;  p=Process.create('mspaint');&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;プロセス監視機能を単独で使用したい場合でも、このようにスレッド化しておいて、「Main.createNotifyIcon();」という行を追加しておけば、タスクトレイアイコンから終了させられるようになって便利です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-968951589613510346?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/968951589613510346/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_558.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/968951589613510346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/968951589613510346'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_558.html' title='プロセスの終了を監視して再起動したりする'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5521406302670484515</id><published>2010-08-18T21:08:00.000+09:00</published><updated>2010-08-18T21:08:24.695+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>スクリプトの常駐機構</title><content type='html'>NILScriptでは、キーボードやマウスなどのイベントハンドラ関数を登録している時にスクリプトの本体が末尾まで実行されてもプロセスが終了してしまわないように、「常駐カウント」という仕組みが用意されています。&lt;br /&gt;イベントハンドラ関数の登録などが行われ、常駐カウントが増やされた状態でスクリプトの本体が末尾まで実行されると、メインスレッドは終了せずに常駐状態になります。イベントハンドラ関数の登録が解除されたりして常駐カウントが0になると、常駐状態から抜けてプロセスが終了します。&lt;br /&gt;&lt;br /&gt;NILScriptに元々用意されている機能では、必要に応じて自動的に常駐カウントが増減されますが、Thread.create()で自前のスレッドを生成して、必ず最後まで実行して欲しい処理を並列実行させる場合には、下記のようにして明示的に常駐カウントを増減させる必要があります。&lt;br /&gt;&lt;pre&gt;function count(name,num,interval){&lt;br /&gt; Thread.create(function(){&lt;br /&gt;  for(var i=0;i&amp;lt;num;i++){&lt;br /&gt;   println(name+': '+i);&lt;br /&gt;   sleep(interval||100);&lt;br /&gt;  }&lt;br /&gt;  Main.unreside();&lt;br /&gt; });&lt;br /&gt; Main.reside();&lt;br /&gt;}&lt;br /&gt;count("A",10);&lt;br /&gt;count("B",6,400);&lt;br /&gt;&lt;/pre&gt;「Main.reside()」が常駐カウントを増やすメソッド、「Main.unreside()」が常駐カウントを減らすメソッドです。&lt;br /&gt;Main.reside()は、監視スレッド側ではなく、メインスレッド内で呼び出す必要がある事に注意してください。これは、監視スレッド内で呼び出すと、Main.reside()が実行される前にメインスレッドが終了してしまうことがある為です。&lt;br /&gt;&lt;br /&gt;ユーザーの操作でスクリプトを終了させられるようにしたい場合は、「Main.createNotifyIcon()」でタスクトレイアイコンを作成するか、Hotstrokesで何らかのキー操作に「exit()」関数の呼び出しを割り当てておくと良いでしょう。exit()は、スクリプトを終了させる関数です。&lt;br /&gt;なお、トレイアイコンやHotstrokesを使用すると常駐カウントが増やされるので、別途Main.reside()を呼び出す必要はありません。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5521406302670484515?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5521406302670484515/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_18.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5521406302670484515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5521406302670484515'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_18.html' title='スクリプトの常駐機構'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2736276837473152558</id><published>2010-08-17T21:25:00.002+09:00</published><updated>2010-08-31T03:51:43.777+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>文字列の全角・半角を変換する</title><content type='html'>NILScriptではJavaScript標準の型である文字列や数値にも拡張メソッドが用意されています。&lt;br /&gt;文字列の拡張メソッド「format()」では、引数で指定した条件に従って文字列の全角・半角などの変換を行なえます。&lt;br /&gt;引数には、今の所以下のアルファベットの組み合わせを指定できます。&lt;br /&gt;&lt;pre&gt;a 全角→半角(アルファベットと数字)&lt;br /&gt;A 半角→全角(アルファベットと数字)&lt;br /&gt;r 全角→半角(アルファベット)&lt;br /&gt;R 半角→全角(アルファベット)&lt;br /&gt;n 全角→半角(数字)&lt;br /&gt;N 半角→全角(数字)&lt;br /&gt;s 全角→半角(空白文字)&lt;br /&gt;S 半角→全角(空白文字)&lt;br /&gt;m 全角→半角(対応する半角文字がある全ての記号)&lt;br /&gt;M 半角→全角(全ての記号)&lt;br /&gt;E 半角→全角(ファイル名に使用できない記号)&lt;br /&gt;f 全角→半角(ファイル名に使用可能な記号)&lt;br /&gt;Y MもしくはEと共に指定すると、\を／でなく￥に置換&lt;br /&gt;k 全角→半角(カタカナ)&lt;br /&gt;K 半角→全角(カタカナ)&lt;br /&gt;V 半角→全角(カタカナ。濁点・半濁点の合成を行う)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;これを利用すれば、何故か英数字が全角になっているサイトから抽出した文字列を半角に修正するなどの処理が簡単に行なえます。&lt;br /&gt;例えば、「title」という変数に入っている文字列の全角文字を半角文字に置き換えるには、以下のようにします。&lt;br /&gt;&lt;pre&gt;title=title.format('asm');&lt;br /&gt;&lt;/pre&gt;これだけで、「ＮＩＬＳｃｒｉｐｔ」のような忌々しい全角文字列を「NILScript」のように半角に変換できます。&lt;br /&gt;全角英数字は、検索で見つけにくくなるなどの害がありますので、是非この機能を活用して撲滅してください。&lt;br /&gt;&lt;br /&gt;ファイル名に使用できない文字だけを全角に変換する機能も便利です。&lt;br /&gt;下記のようにすれば、ファイル名に使用可能な記号は半角に、使用不可能な記号は全角に変換してくれます。&lt;br /&gt;&lt;pre&gt;var filename=title.format('asfE');&lt;br /&gt;&lt;/pre&gt;Webページのタイトル等から取得した文字列には、ファイル名に使用できない文字が含まれている可能性があるので、保存ファイル名などとして使う場合には、このようにして変換すると良いでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2736276837473152558?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2736276837473152558/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_5727.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2736276837473152558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2736276837473152558'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_5727.html' title='文字列の全角・半角を変換する'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-4599499512267437530</id><published>2010-08-17T06:53:00.000+09:00</published><updated>2010-08-17T06:53:28.255+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>クラスの定義方法</title><content type='html'>NILScriptには、Javaなどのような「クラスベース」のオブジェクト指向プログラミングを行うための機能が用意されており、プロトタイプベースのオブジェクト指向機能しか用意されていない素のJavaScriptよりも簡単に、クラスのような物を作成できます。&lt;br /&gt;ここでは、NILScriptでのクラスの作成方法を説明します。&lt;br /&gt;NILScriptに同梱の「doc\base_class.txt」にも、細かな機能の解説が用意されているので、併せて参照してください。&lt;br /&gt;&lt;br /&gt;クラスを定義するには、下記のように「new Class()」の返り値を変数などに代入します。&lt;br /&gt;&lt;pre&gt;var SomeClass=new Class({&lt;br /&gt; __class__:{&lt;br /&gt;  __call__:function(){&lt;br /&gt;   println("called as a function");&lt;br /&gt;  },&lt;br /&gt;  someClassMethod:function(){&lt;br /&gt;  },&lt;br /&gt; },&lt;br /&gt; __new__:function(){&lt;br /&gt;  println("initializing");&lt;br /&gt; },&lt;br /&gt; someMethod:function(){&lt;br /&gt;  println("do something");&lt;br /&gt; },&lt;br /&gt; someProperty:"defaultValue",&lt;br /&gt; get somePropertyWithAccessor(){&lt;br /&gt; },&lt;br /&gt; set somePropertyWithAccessor(){&lt;br /&gt; },&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;引数となっているのが、インスタンスのメンバを定義したオブジェクトです。&lt;br /&gt;「__new__()」メソッドは、「new SomeClass()」のようにしてクラスのインスタンスを生成する時に実行されるコンストラクタとなります。&lt;br /&gt;「__class__」には、クラス自体のメンバを定義したオブジェクトを指定します。このメンバは、インスタンスを生成することなく「SomeClass.someClassMethod()」のようにして使用できます。&lt;br /&gt;特殊なクラスメンバである「__call__()」では、クラスが「new」を伴わずに通常の関数として呼ばれた時に実行される処理を指定できます。&lt;br /&gt;その他、関数メンバであるメソッドや、単なる値のプロパティ、getter/setterによるプロパティも定義できます。&lt;br /&gt;「__new__」「__class__」「__call__」などは、不要なら定義しなくても構いません。&lt;br /&gt;&lt;br /&gt;別のクラスの機能を継承した派生クラスを作成することも可能です。&lt;br /&gt;継承を行うには、下記のようにnew Class()の第1引数に継承元となるクラスを指定します。&lt;br /&gt;この場合、クラスに追加・上書きするメンバは、第2引数で指定します。&lt;br /&gt;&lt;pre&gt;var SubClass=new Class(SomeClass,{&lt;br /&gt; __class__:{&lt;br /&gt;  someClassMethod:function(){&lt;br /&gt;  },&lt;br /&gt; },&lt;br /&gt; someMethod:function(){&lt;br /&gt; },&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;なお、この継承はJavaScriptのプロトタイプチェーンを利用しているため、「(new SubClass()) instanceof SomeClass」のような式はtrueになります。&lt;br /&gt;派生クラスのインスタンスではなく直接のインスタンスかどうかを調べたい場合は、「someObject.constructor===SomeClass」のようにするとよいでしょう。&lt;br /&gt;&lt;br /&gt;更に、継承とは別に他のクラスの機能を一括して組み込む「ミックスイン」という機能も用意されています。&lt;br /&gt;ミックスインを利用するには、第2引数以降にミックスしたいクラスを指定します。&lt;br /&gt;他のクラスを継承させずにミックスのみを行いたい場合は、以下のように第1引数を「{}」にするとよいでしょう。&lt;br /&gt;&lt;pre&gt;var SomeMixedClass=new Class({},SomeMixin,{&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;どんなクラスでもミックスできますが、通常はミックスインとして使うことを意図して用意されたクラスをミックスします。&lt;br /&gt;NILScriptには、標準で「EventMixin」や「StreamMixin」など、よく使う機能を定義したミックスイン用クラスが用意されているので、是非活用してください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-4599499512267437530?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/4599499512267437530/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_17.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4599499512267437530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4599499512267437530'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_17.html' title='クラスの定義方法'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5799148112799560583</id><published>2010-08-16T20:06:00.002+09:00</published><updated>2010-08-16T20:06:57.650+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>同期的にイベントを待機するwait()メソッド</title><content type='html'>NILScriptでは、クリップボードやファイルなど、イベント機構を備えたクラスは全て「observe()」というメソッドでイベントハンドラ関数の登録を行うようになっています。&lt;br /&gt;これは、イベント機構で必要となる機能が「EventMixin」というクラスにまとめて実装されており、ミックスインという仕組みで各クラスに組み込まれているためです。&lt;br /&gt;&lt;br /&gt;EventMixinには、他にも「wait()」などのメソッドが用意されており、EventMixinがミックスされている全てのクラスで使用できます。&lt;br /&gt;wait()メソッドは、第1引数に指定された名前のイベントが発生するのを待ってから処理を返します。第2引数でタイムアウトを指定した場合は、指定ミリ秒数が経過したら待機を打ち切り、イベントが発生したかどうかを返り値とします。&lt;br /&gt;&lt;br /&gt;この機能を使用すれば、イベントが発生するのを待って次の処理に進むというスクリプトが、下記のようにシンプルに記述できます。&lt;br /&gt;&lt;pre&gt;var f=Main.directory.file("readme.txt");&lt;br /&gt;println("readme.txtが更新されるのを待っています");&lt;br /&gt;f.wait("modify");&lt;br /&gt;println("更新されました");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;バッチ処理的なスクリプトを書く時には特に便利ですので、覚えておくとよいでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5799148112799560583?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5799148112799560583/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/wait.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5799148112799560583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5799148112799560583'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/wait.html' title='同期的にイベントを待機するwait()メソッド'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5367844495932364519</id><published>2010-08-15T23:59:00.002+09:00</published><updated>2010-08-15T23:59:46.552+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>ファイルの作成・更新・削除を監視</title><content type='html'>2010/08/15版以降のNILScriptには、ファイルの変更を監視してイベントハンドラ関数を実行する機能が用意されています。定期的にファイル情報を取得するのではなく、OSのファイル更新イベント通知機能を使用しているので、システムへの負荷は少なくて済みます。&lt;br /&gt;この機能を利用すれば、ファイルの作成などでしか処理の完了を検出できないソフトを含む作業の自動化などを簡単に実現できます。&lt;br /&gt;&lt;br /&gt;特定のファイルの作成・変更・削除を監視するには、Fileクラスのインスタンスオブジェクトの「observe()」メソッドを使います。&lt;br /&gt;&lt;pre&gt;Main.createNotifyIcon();&lt;br /&gt;var f=new File("E:\\work\\_devel\\ng\\test\\test");&lt;br /&gt;f.observe(['create','remove','modify','renameTo','renameFrom'],function(o){&lt;br /&gt; Main.notifyIcon.showInfo(o.event+":"+(o.file||""));&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;「Main.createNotifyIcon()」は、NILScript標準のタスクトレイアイコンを作成するメソッドです。Fileオブジェクトのobserve()を使うとスクリプトが常駐状態になるので、スクリプトを手動で終了させるためにトレイアイコンを用意しておく必要があります。&lt;br /&gt;2行目では、パスを指定してFileオブジェクトを生成しています。&lt;br /&gt;3行目が、イベントハンドラの登録処理です、observe()の第1引数には監視するイベント名を指定しますが、配列を指定すれば複数のイベントに対していっぺんにイベントハンドラを登録できます。ここでは、用意されている全てのイベント名を指定しています。&lt;br /&gt;イベントハンドラ関数の中では、第1引数に与えられるオブジェクトの「event」メンバでイベント名を、「file」メンバで「renameTo」「renameFrom」のリネーム後・前のファイルのFileオブジェクトを参照できます。&lt;br /&gt;「Main.notifyIcon.showInfo()」は、タスクトレイアイコンのバルーンでテキストを表示するメソッドです。&lt;br /&gt;&lt;br /&gt;ディレクトリ内の不特定多数のファイル・ディレクトリの作成・変更・削除を監視するには、Directoryオブジェクトの「observe()」メソッドを使用します。&lt;br /&gt;&lt;pre&gt;var d=new Directory("E:\\work\\_devel\\ng\\test");&lt;br /&gt;d.observe(['add','remove','modify','rename'],function(o){&lt;br /&gt; Main.notifyIcon.showInfo(o.event+' '+(o.old||"")+' =&gt; '+o.file);&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;使い方はほとんどFileオブジェクトのobserve()と同じですが、用意されているイベント名が一部異なります。&lt;br /&gt;また、作成・変更・削除されたファイルが、引数オブジェクトの「file」メンバで、renameイベントでのリネーム前のファイルが「old」メンバで取得できます。&lt;br /&gt;&lt;br /&gt;これらの監視機能を使用する上で注意すべきなのは、ファイルの作成イベントが発生した時点では、まだファイルへの書き込みが行われている可能性があると言うことです。書き込み途中のファイルを操作しようとしても、ファイルを開けず失敗してしまったり、中途半端な内容しか読み取られなかったりするでしょう。&lt;br /&gt;これを回避するには、ファイルのパスと最後に更新イベントが発生した時間をオブジェクトに格納しておいて、一定時間更新が発生していないファイルを書き込み完了とみなして操作するなどの工夫をするといいでしょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5367844495932364519?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5367844495932364519/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_15.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5367844495932364519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5367844495932364519'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_15.html' title='ファイルの作成・更新・削除を監視'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2666403531087214193</id><published>2010-08-15T02:04:00.001+09:00</published><updated>2010-08-15T02:04:50.554+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>コマンドラインでのスクリプト指定が不要なEXEを作成</title><content type='html'>NILScriptでは通常、コマンドライン引数で実行させたいスクリプトファイル名を指定しなければならないため、Mozilla Firefoxの設定の「プログラム」の項での「他のプログラムを選択」のように、EXEファイルパスしか指定できない外部プログラム呼び出し機能からは、スクリプトを実行させられません。&lt;br /&gt;この問題を解決するために、コマンドラインでスクリプトファイル名を渡さずに一定のスクリプトを実行するというEXEファイルを作成する機能が用意されています。&lt;br /&gt;&lt;br /&gt;この機能を利用するには、NILScriptに同梱の「mkexe_c.bat」か「mkexe_w.bat」を実行し、表示されるプロンプトで生成したい実行ファイルの名前を指定してください。「_c」の方はコンソール版、「_w」は非コンソール版の実行ファイルが作成されます。&lt;br /&gt;&lt;br /&gt;すると、NILScriptのディレクトリ内に、入力した名前で拡張子「.exe」のファイルと「.js」のファイルが作成され、拡張子「.js」のスクリプトファイルがメモ帳で開かれます。(使用するエディタはmkexe.ngを編集すれば変更できます。)&lt;br /&gt;&lt;br /&gt;スクリプトファイルの内容は以下のようになっており、「/* script body */」と書かれている箇所に実行させたいスクリプトを記述します。&lt;br /&gt;&lt;pre&gt;__NG__EvalFile(__NG__HostPath().replace(/([^\\]+)$/,"lib\\Base.ng"));&lt;br /&gt;Main.main=function(){&lt;br /&gt; /* script body */&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;Main.execute();&lt;br /&gt;&lt;/pre&gt;後は、EXEファイルの方を実行すれば、記述したスクリプトが実行されます。&lt;br /&gt;なお、実行ファイルに渡されたコマンドライン引数は、スクリプト中で「Main.params」というプロパティで配列として参照できます。&lt;br /&gt;&lt;br /&gt;実は実行ファイルの部分はng.exe/ngw.exeと全く同じなのですが、コマンドラインの第1引数のスクリプトを読み込んで実行するという処理が定義されている「Main.main()」を上書きすることで、コマンドライン引数を使用せずに任意の処理を実行させられるのです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2666403531087214193?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2666403531087214193/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/exe.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2666403531087214193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2666403531087214193'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/exe.html' title='コマンドラインでのスクリプト指定が不要なEXEを作成'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8350868940133261325</id><published>2010-08-14T04:40:00.000+09:00</published><updated>2010-08-14T04:40:42.193+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>HTTPDのプロキシサーバ機能</title><content type='html'>NILScriptのHTTPDには、プロキシサーバとして動作してブラウザからのリクエストに応答し、コンテンツを書き換えたりするという機能も用意されています。&lt;br /&gt;プロキシ機能を使用するには、HTTPD初期化時の引数オブジェクトに、以下のようなメンバを指定します。&lt;br /&gt;後は、ブラウザで「プロキシ自動設定スクリプト」などの欄に「http://localhost/__proxy__/conf.pac」を指定すれば、「useProxy」の条件に一致し「noProxy」に一致しないURLへのアクセス時に、NILScriptのHTTPDのプロキシ機能を経由してアクセスされます。&lt;br /&gt;実際の例はNILScriptに同梱の「sample\HTTPD.ng」を参照してください。また、メソッドなどの詳細はNILScriptに同梱の「doc\HTTPD.txt」で説明されています。&lt;br /&gt;&lt;pre&gt; useProxy:"http://",&lt;br /&gt; noProxy:"http://localhost/",&lt;br /&gt; proxyRequest:function(c){&lt;br /&gt;  println(c.method+' '+c.url);&lt;br /&gt;  if(c.url.host=='lukewarm.s151.xrea.com'){&lt;br /&gt;   c.addScripts(function(){&lt;br /&gt;    TestPlugin.serverSideTest(['proxy @ '+location.href])&lt;br /&gt;   });&lt;br /&gt;   if(c.url.path.match(/\.png$/)){&lt;br /&gt;    c.cache=Main.scriptDirectory.directory('cache');&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; },&lt;br /&gt; proxyResponse:function(c,r){&lt;br /&gt;  if((c.url.host=='lukewarm.s151.xrea.com')&lt;br /&gt;      &amp;&amp;(c.url.path.match(/\.dat$/))){&lt;br /&gt;   r.lines.invoke('split',/&amp;lt;&amp;gt;/).addIndex()&lt;br /&gt;    .execute(function([i,[name,mail,date,message,title]]){&lt;br /&gt;    if(i==0){&lt;br /&gt;     c.beginHTML(title);&lt;br /&gt;    }&lt;br /&gt;    c.write('&amp;lt;h3&amp;gt;'+(i+1)+': '+name+'('+mail+') - '+date&lt;br /&gt;      +'&amp;lt;/h3&amp;gt;&amp;lt;p&amp;gt;'+message+'&amp;lt;/p&amp;gt;');&lt;br /&gt;   });&lt;br /&gt;   c.endHTML();&lt;br /&gt;  }&lt;br /&gt; },&lt;br /&gt;&lt;/pre&gt;プロキシとしての動作を指定しているのは、「proxyRequest」と「proxyResponse」の2つのメンバです。&lt;br /&gt;&lt;br /&gt;proxyRequestの関数は、プロキシのリクエストを受取った時点で呼ばれます。&lt;br /&gt;第1引数には通常のコンテンツ生成関数と同じようにConnectionオブジェクトが与えられ、その機能でリクエスト情報の取得やレスポンスの送信などを行えます。&lt;br /&gt;また、HTML中に任意のスクリプトを挿入する「c.addScript()」や、テキストやHTMLノードに対するフィルタリングを行うメソッド群など、プロキシハンドラ専用の機能もいくつか用意されています。&lt;br /&gt;addScript()で埋め込めるスクリプトでは、HTTPD上に定義したサーバ側関数なども利用できます。&lt;br /&gt;&lt;br /&gt;「c.cache=」のようにすれば、レスポンスボディを保存するキャッシュファイルを指定できます。この場合、キャッシュファイルがあれば本来のリクエストを行わずにそれを返し、無ければ受信しながらキャッシュファイルとして保存するという動作になります。&lt;br /&gt;また、「c.error(404)」のようにして、本来のリクエストを行わずにエラーを返したり、「c.write()」などで自前のコンテンツに差し替えてしまうことも可能です。&lt;br /&gt;&lt;br /&gt;proxyRequestの中で送信が行われなかった場合、リクエストに従ってアクセスを行いレスポンスヘッダの取得までが行われ、proxyResponseで指定した関数が呼ばれます。&lt;br /&gt;この時、第1引数にはConnectionオブジェクトが、第2引数にはリクエストにしたがって行ったHTTPリクエストのResponseオブジェクトが与えられます。Responseオブジェクトの機能の詳細については、「doc\HTTP.ng」の方で説明されています。&lt;br /&gt;&lt;br /&gt;ここでは、レスポンスヘッダを書き換えたり、エラー時に代替コンテンツを生成して返すなどの処理を行うといいでしょう。&lt;br /&gt;また、第2引数のレスポンスオブジェクトからレスポンスボディを読み込んで、そこから抜き出した情報を元にレスポンスを生成することも出来ます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;プロキシ機能を利用すれば、ブラウザを問わずに利用できる様々なブラウジング補助機能を実現できます。&lt;br /&gt;ただし、ブラウザの設定を変更してプロキシを設定しなければならないという難点があるので、できるだけ通常のコンテンツ生成関数を利用した方がいいかもしれません。&lt;br /&gt;例えば、あるWeb掲示板の表示を見やすくする機能を作りたい場合は、ページを取得して見易いHTMLに加工して返すというコンテンツ生成関数をHTTPD上のURLに割り当て、プロキシ機能では掲示板のURLから用意したURLへのリダイレクトのみを行うようにしておくのです。&lt;br /&gt;こうすれば、プロキシ機能を利用できなくても、HTTPD上のURLへ直接アクセスすれば、用意された機能を利用できます。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8350868940133261325?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8350868940133261325/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/httpd_14.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8350868940133261325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8350868940133261325'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/httpd_14.html' title='HTTPDのプロキシサーバ機能'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2295342366402168356</id><published>2010-08-13T03:14:00.002+09:00</published><updated>2010-08-13T21:41:37.155+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>ネイティブコード関数のスクリプトへの埋め込み</title><content type='html'>ネイティブコード関数呼び出し機能では、DLL内の関数だけでなく、任意のアドレスを関数として呼び出すことも可能です。16進数列を元にバイト配列を生成してポインタオブジェクトを返す「Hex.decode()」と共に使用すれば、スクリプト中に任意のネイティブコード関数を埋め込んで使用できます。&lt;br /&gt;このテクニックは、バイト列の操作などの速度を要する低レベルな処理を自前で実装したい時に役立ちます。&lt;br /&gt;&lt;br /&gt;埋め込むネイティブコード関数を脳内アセンブルで作るのは大変なので、C言語などのコンパイラが生成する中間ファイルを使用するといいでしょう。&lt;br /&gt;VisualStudioでは、「.cod」という拡張子の中間ファイルとして、アセンブラや16進数列の機械語コードが出力されます。&lt;br /&gt;&lt;br /&gt;下記は、Base.ng中で定義されているネイティブコード関数埋め込みの例です。&lt;br /&gt;&lt;pre&gt;memIndexOf=(new CFunction(&lt;br /&gt; Hex.decode('55 8B EC (中略) E5 5D C3')&lt;br /&gt;)).toFunction([Pointer,Int,Pointer,Int],Int)&lt;br /&gt;&lt;/pre&gt;ライブラリオブジェクトの「proc()」の代わりに、「(new CFunction(Hex.decode("機械語の16進数文字列"))).toFunction([引数の型],返り値の型)」のようにして、16進数文字列をバイト配列→関数ポインタオブジェクト→ラッパー関数と変換しています。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2295342366402168356?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2295342366402168356/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_13.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2295342366402168356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2295342366402168356'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_13.html' title='ネイティブコード関数のスクリプトへの埋め込み'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-4555171189515908176</id><published>2010-08-12T22:52:00.002+09:00</published><updated>2010-08-12T22:58:56.161+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>ネイティブコード関数からのコールバック</title><content type='html'>DLLなどが提供するネイティブコード関数の中には、他の関数へのポインタを引数として受取る物があります。&lt;br /&gt;NILScriptでは、このようなコールバックで使用するためにJavaScriptの関数をネイティブコード関数でラップする機能も用意されています。&lt;br /&gt;ここでは、この関数エクスポート機能の使い方について説明します。&lt;br /&gt;&lt;br /&gt;まず、最初に関数の引数と返り値の型を指定して、関数ポインタ型のクラスを生成し、変数に代入しておきます。&lt;br /&gt;下記は、Windowユニットで使用されている例です。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var EnumWindowsProc=StdCallFunction.define([UInt,Int],Int);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;引数の型には、WideStringやMBStringなどの文字列系の型や、「new Struct()」で生成した構造体型を表すクラスなどを指定する事も出来ます。&lt;br /&gt;「StdCallFunction」の他にも、「CFunction」や「ThreadSafeStdCallback」、「ThreadSafeCallback」というクラスがあります。&lt;br /&gt;StdCallが付いているのが呼び出し規約がstdcallのもので、それ以外がcdeclのものです。ThreadSafeの意味については、後で説明します。&lt;br /&gt;&lt;br /&gt;次に、下記のようにしてこの関数型を引数に取るネイティブコード関数のラッパー関数を生成します。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var EnumWindows=user32.proc('EnumWindows',[EnumWindowsProc,UInt],Int);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;その後、コールバック関数型を指定した引数にJavaScriptの関数を渡して、ラッパー関数を呼び出します。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var handles=[];&lt;br /&gt;EnumWindows(function(handle,lp){&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;handles.push(handle);&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return(1);&lt;br /&gt;},0);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;この例では、EnumWindows()が呼び出されている間に、存在するトップレベルウィンドウの数だけコールバック関数が呼び出されます。&lt;br /&gt;&lt;br /&gt;なお、コールバックの呼び出しが、コールバック関数を与えた関数から返った後に実行される可能性がある場合、関数を直接渡してはならないことに注意してください。&lt;br /&gt;このような場合、以下のように関数型クラスの「from()」メソッドにコールバック関数を渡して関数ポインタオブジェクトを生成し、コールバック関数の呼び出しが起こる可能性がある限り参照が維持されるように、変数やプロパティに代入しておく必要があります。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//定義部分(抜粋)&lt;br /&gt;var LowLevelMouseProc=StdCallFunction.define([Int,UInt,UInt],Int);&lt;br /&gt;var SetWindowsHookEx=user32.proc("SetWindowsHookExW"&lt;br /&gt;      ,[UInt,LowLevelMouseProc,UInt,UInt],UInt,true);&lt;br /&gt;&lt;br /&gt;//関数ポインタオブジェクトの生成とコールバックの登録&lt;br /&gt;var func=LowLevelMouseProc.from(function(code,wp,LP){/*** 略 ***/});&lt;br /&gt;var hHook=SetWindowsHookEx(14,func,Main.handle,0);&lt;br /&gt;&lt;br /&gt;/* 略(コールバックが呼び出される可能性のある処理(GetMessage()の呼び出し)) */&lt;br /&gt;&lt;br /&gt;//コールバックの登録解除と関数ポインタオブジェクトの解放&lt;br /&gt;hHook&amp;amp;&amp;amp;UnhookWindowsHookEx(hHook);&lt;br /&gt;func&amp;amp;&amp;amp;func.free();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;こうしておかないと、JavaScript関数やラッパー関数のメモリが途中で解放されてしまい、参照エラーや予期せぬ動作を引き起こしてしまうからです。&lt;br /&gt;コールバック関数の登録解除処理を実行し、コールバック関数が呼ばれる可能性が無くなったら、関数ポインタオブジェクトの「free()」メソッドを呼び出して、関数ポインタオブジェクトが指しているラッパー関数のメモリ解放などを行います。&lt;br /&gt;&lt;br /&gt;最後に、「ThreadSafe」の意味について説明します。&lt;br /&gt;ThreadSafeの付いていない種類のコールバック関数では、関数ポインタオブジェクト生成時のスレッドのスクリプト実行コンテキストが使い回されるため、別のスレッドから呼び出されると不具合が生じてしまいます。&lt;br /&gt;一方、ThreadSafeの付いている種類のコールバック関数では、毎回スクリプト実行コンテキストを新規生成して、それを使用してエクスポートされた関数を呼び出すため、別のスレッドからも問題なく呼び出せます。&lt;br /&gt;ThreadSafe版を単一スレッド上から呼び出しても問題はありませんが、呼び出し時に多くのコストがかかるので、なるべくならThreadSafeでない方を使うことが望ましいでしょう。&lt;br /&gt;実際の所は、ThreadSafeのコールバック関数が必要になるケースはそれほど多くはなく、NILScriptの標準機能の中では、今の所Thread.create()でしか使用されていません。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-4555171189515908176?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/4555171189515908176/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_6377.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4555171189515908176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4555171189515908176'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_6377.html' title='ネイティブコード関数からのコールバック'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-3466473929762875327</id><published>2010-08-12T16:12:00.000+09:00</published><updated>2010-08-12T16:12:59.407+09:00</updated><title type='text'>構造体を使用したネイティブコード関数呼び出し</title><content type='html'>DLLが提供するネイティブコード関数の中には、複数の値からなるバイト列である「構造体」を使用する物も少なくありません。&lt;br /&gt;ここでは、構造体を利用したネイティブコード関数呼び出しの方法を説明します。&lt;br /&gt;&lt;br /&gt;下記は、構造体を利用したネイティブコード関数呼び出しの一例です。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var Point=new Struct({&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;x:Int,&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;y:Int,&lt;br /&gt;});&lt;br /&gt;var GetCursorPos=user32.proc("GetCursorPos",[Point],Int);&lt;br /&gt;try{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var point=Point.alloc();&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;GetCursorPos(point);&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;println([point.x,point.y]);&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;println(Hex.encode(point));&lt;br /&gt;}finally{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;free(point);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;最初に「new Struct()」で構造体オブジェクトを生成して、変数に代入しています。引数には、構造体のフィールド名と値の型を表すオブジェクトのペアを列挙したオブジェクトを指定します。フィールド定義は、構造体内での並び順の通りに並べる必要があります。&lt;br /&gt;ライブラリオブジェクトのproc()によるラッパー関数定義で、引数の型を指定する箇所に構造体オブジェクトを格納した変数名を記述すれば、その構造体へのポインタを引数として受取ることを指定できます。&lt;br /&gt;&lt;br /&gt;tryブロック内が、構造体オブジェクトを利用した関数呼び出しを行う部分です。&lt;br /&gt;構造体のバッファは、UIntなどのバッファの時と同じように、「alloc()」メソッドで確保します。&lt;br /&gt;この返り値を引数にしてGetCursorPos()を呼び出すことにより、確保したバッファ内に値が書き込まれます。&lt;br /&gt;「point.x」や「point.y」のように、構造体定義で指定したフィールド名と同じ名前のプロパティで、バッファ内の当該フィールドの値を取得できます。また、「point.x=100」のようにすれば、フィールドの値を書き換えることも可能です。&lt;br /&gt;なお、「Hex.encode()」は、ポインタオブジェクトが確保しているバイト列を2桁区切りの16進数文字列として返すメソッドです。ポインタを利用した関数の動作確認をしたい場合などに役立ちます。&lt;br /&gt;&lt;br /&gt;最後に、確保したバッファを解放するたに、finallyブロック内で「free()」関数を実行しています。使用する関数によっては、すぐにバッファを解放してはならない場合などもありますので、関数のドキュメントなどをよく確認してください。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-3466473929762875327?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/3466473929762875327/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_313.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3466473929762875327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3466473929762875327'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_313.html' title='構造体を使用したネイティブコード関数呼び出し'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8942622248881568593</id><published>2010-08-12T16:08:00.000+09:00</published><updated>2010-08-12T16:08:34.343+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>ポインタを使用したネイティブコード関数呼び出し</title><content type='html'>DLLが提供するネイティブコード関数の中には、引数にポインタを指定して、返り値以外にも値を受け取れるようになっている物があります。このような場合は、引数の型を「Pointer」にしておいて、Intなどの「alloc()」メソッドで生成したバッファオブジェクトを渡してやる必要があります。&lt;br /&gt;&lt;br /&gt;下記は、その一例です。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var GetComputerName=kernel32.proc('GetComputerNameW',[WideString,Pointer],UInt);&lt;br /&gt;try{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var buf=WChar.alloc(128);&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var size=UInt.alloc().update(127);&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;println(GetComputerName(buf,size));&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;println(size.item());&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;println(buf.toString());&lt;br /&gt;}finally{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;free(buf,size);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Unicode文字列バッファで値を受取るには、引数の型を「WideString」にしておいて、「WChar.alloc()」で確保したバッファを渡します。alloc()の引数には、確保する要素数を指定します。引数の型はWideStringですが、alloc()はWCharのメソッドである事に注意してください。&lt;br /&gt;また、バイト配列やマルチバイト文字列の場合、引数の型を「MBString」にして、バッファの確保は「Byte.alloc()」で行います。&lt;br /&gt;WideStringやMBStringは、「toString()」メソッドでゼロ終端文字列とみなしてJavaScriptの文字列値に変換できます。&lt;br /&gt;&lt;br /&gt;「UInt.alloc()」では、1つのUIntバッファを確保しており、続く「update(127)」でバッファの内容を書き換えています。このメソッドは、メソッドを呼び出されたPointerオブジェクト自身を返します。&lt;br /&gt;ポインタオブジェクトを引数として関数を呼び出した後、「item()」メソッドを使用すれば、バッファの内容を数値として取得できます。&lt;br /&gt;&lt;br /&gt;最後に、確保したバッファを解放するため、「free()」という関数を呼び出しています。この関数は、引数がfree()メソッドを持つオブジェクトだった場合にそれを呼び出すという動作になっており、Pointerオブジェクト以外にもfree()メソッドを持つ様々なオブジェクトの解放処理をまとめて実行できます。&lt;br /&gt;free()は、何らかの問題があって例外が投げられた場合などにも必ず実行されるように、try...finally文のfinally節で実行する必要があります。また、この方法を使えば、buf.toString()の値を関数の返り値として返したい場合などに、いちいち変数に代入してからbufをfree()したりする必要が無くなるという利点もあります。&lt;br /&gt;&lt;br /&gt;なお、JavaScriptにはGCという仕組みが用意されており、文字列やオブジェクトなどの値はどこからも参照されなくなったら自動的に解放されるようになっていますが、NILScriptでは敢えてこの仕組みを使わずに、明示的に解放処理を記述するようになっています。&lt;br /&gt;これは、JavaScriptには「クロージャ」という仕組みがあり、変数に代入した値がその変数を定義した関数やブロックを抜けてもずっと参照されたままの状態になってしまうことがよくあるからです。&lt;br /&gt;これは、変数を参照可能な場所で生成された関数が他の場所から参照され続けていることによるものですが、イベントハンドラ関数などが多用されているNILScriptでは、この状態が発生しやすくなっています。&lt;br /&gt;「buf=null」などとしてやれば参照が失われてGCの解放対象となりますが、それではfree()を呼び出すのと同じですので、より直接的なfree()による解放が採用されています。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8942622248881568593?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8942622248881568593/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_9157.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8942622248881568593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8942622248881568593'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_9157.html' title='ポインタを使用したネイティブコード関数呼び出し'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-4974723819725721151</id><published>2010-08-12T16:04:00.002+09:00</published><updated>2010-08-12T16:17:05.584+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>DLLなどのネイティブコード関数の呼び出し</title><content type='html'>NILScriptの特徴の一つに、DLLなどのネイティブコード関数を呼び出すラッパー関数を生成する機能があります。&lt;br /&gt;実はNILScriptの機能のほとんどは、この機能でWindowsのAPIやNILScriptに同梱したDLLの関数を呼び出すことで実現しています。&lt;br /&gt;ここでは、ネイティブコード関数呼び出しの基本的な手順を説明します。&lt;br /&gt;なお、ネイティブコード関数関連の機能の説明は「doc\base_native.txt」にありますが、不完全な部分などがありますので、libディレクトリ内のユニットスクリプトでの実際の使用例も参照してください。&lt;br /&gt;&lt;br /&gt;まず、最初に「Library.load()」か「WinLibrary.load()」で、ライブラリの読み込みを行います。関数の呼び出し規約がcdeclのライブラリの場合はLibrary、stdcallならWinLibraryを使用します。&lt;br /&gt;load()の引数にはDLL名を指定しますが、システムディレクトリか実行ファイルのあるディレクトリ以外にあるDLLの場合は、フルパスで指定する必要があります。ユニットスクリプトにDLLを同梱する場合は、ユニット初期化関数内での「this.directory.file()」でユニットのディレクトリ内のファイルを取得すればいいでしょう。&lt;br /&gt;&lt;br /&gt;次に、ライブラリオブジェクトの「proc」メソッドでラッパー関数を生成します。&lt;br /&gt;下記は、Mouseユニット内で定義されているラッパー関数定義の一例です。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var SetCursorPos=user32.proc("SetCursorPos",[Int,Int],Int);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;user32というのはNILScriptにあらかじめ用意されているグローバル変数で、user32.dllのライブラリオブジェクトが格納されています。&lt;br /&gt;proc()の第1引数は、DLL内に定義されている関数の識別名です。大抵は、C言語用ヘッダやドキュメントに書かれている名前と一致するはずですが、WindowsのAPIの中には、末尾に「A」や「W」が付く場合があります。&lt;br /&gt;第2引数は、引数の型を表すオブジェクトの配列です。Int/UInt/Short/UShort/Char/UChar/Double/Floatなどのプリミティブ型の他、バイト配列へのポインタを表すMBStringや、Unicode文字配列へのポインタを表すWideStringなどが用意されています。プリミティブ型の引数には数値を、MBString/WideStringを指定した引数には文字列やnullを指定します。&lt;br /&gt;第3引数には、同様にして返り値の型を指定します。&lt;br /&gt;&lt;br /&gt;上記のようにしてラッパー関数を生成しておけば、「SetCursorPos(100,100)」のようにすることで、ラップした関数を呼び出せます。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-4974723819725721151?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/4974723819725721151/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_1389.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4974723819725721151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/4974723819725721151'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_1389.html' title='DLLなどのネイティブコード関数の呼び出し'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-6446725507722939575</id><published>2010-08-12T13:30:00.002+09:00</published><updated>2010-08-31T18:45:59.860+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ファイル'/><category scheme='http://www.blogger.com/atom/ns#' term='ウィンドウ'/><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>ウィンドウへのファイルドロップを生成するdropFiles()</title><content type='html'>NILScriptのWindowユニットには、他プロセスの所有するウィンドウ上の入力欄の内容を操作したり、ボタンを押したりして自動操作を行う機能も用意されていますが、世の中にはエクスプローラなどからのドラッグ&amp;amp;ドロップでしかファイルの指定を受け付けてくれないソフトがあったりします。&lt;br /&gt;そこで、ウィンドウへのファイルドロップをエミュレートする「dropFiles()」というメソッドが用意されています。&lt;br /&gt;以下は、その使用例です。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var w=require("Window").Window.find("Notepad");&lt;br /&gt;if(w){&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;w.dropFiles(Main.script).activate(true);&lt;br /&gt;}else{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;run('notepad "'+Main.script+'"');&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;最初の行で、ウィンドウクラス名が「Notepad」であるウィンドウを検索して、見つかればそのWindowオブジェクトを「w」変数に代入しています。&lt;br /&gt;次のif文で、ウィンドウが見つかったかどうかに応じて分岐しており、見つからなかった場合は新規にnotepadにスクリプトファイルを与えて起動し、見つかった場合はスクリプトファイルのドロップをエミュレートした後ウィンドウをアクティブ化しています。&lt;br /&gt;Main.scriptというのは、自プロセスで実行されているスクリプトファイルを表すFileオブジェクトです。&lt;br /&gt;&lt;br /&gt;なお、dropFiles()には、配列で複数のファイルを渡したり、第2,第3引数でドロップされるX/Y座標も指定することも出来ます。また、ドロップするファイルはFile/Directoryオブジェクトではなく単なるフルパス文字列で指定しても構いません。&lt;br /&gt;&lt;br /&gt;「開く」メニューなどによるファイル指定方法が用意されているソフトでも、ドロップで指定した方が1ステップで済んで便利ですので、自動化ツールを作成する時には是非dropFiles()を活用してください。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-6446725507722939575?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/6446725507722939575/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/dropfiles.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6446725507722939575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6446725507722939575'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/dropfiles.html' title='ウィンドウへのファイルドロップを生成するdropFiles()'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-6734024780261710327</id><published>2010-08-12T12:58:00.000+09:00</published><updated>2010-08-12T12:58:07.240+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>他プロセスのコマンドラインを取得</title><content type='html'>NILScriptのProcessオブジェクトには、他のプロセスのコマンドライン文字列を取得する「commandline」プロパティが用意されています。&lt;br /&gt;これを使用すれば、特定のファイルを開いているプロセスを強制終了するなどの機能も簡単に実現できるでしょう。&lt;br /&gt;&lt;br /&gt;Windowsには、他プロセスのコマンドラインを取得するAPIが用意されていないため、commandlineの取得は特殊な方法で実現されています。&lt;br /&gt;自プロセスのコマンドライン文字列を取得するのに使う「GetCommandLine」というAPIの関数アドレスが、同一環境上の全てのプロセスで一定であることを利用して、「ReadProcessMemory」というAPIで対象プロセスのメモリ内容を取得し、そこからコマンドライン文字列が格納されているアドレスを辿って読み取るのです。&lt;br /&gt;ただし、UAC環境下で別の権限で実行されているプロセスなどのコマンドライン文字列は取得できません。これはWindowsVista以降のタスクマネージャに追加されたコマンドライン文字列表示機能でも同様のようです。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-6734024780261710327?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/6734024780261710327/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_4597.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6734024780261710327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6734024780261710327'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_4597.html' title='他プロセスのコマンドラインを取得'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-3138325467743780132</id><published>2010-08-12T04:36:00.001+09:00</published><updated>2010-08-12T04:40:47.153+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>値を列挙するジェネレータの使い方</title><content type='html'>NILScriptが提供するクラスには、SpiderMonkey1.7で追加された「ジェネレータ」というオブジェクトを返すプロパティやメソッドが数多く存在します。&lt;br /&gt;ジェネレータとは、値を順に出力するオブジェクトです。&lt;br /&gt;&lt;br /&gt;値を配列として返す場合と違い、最初に全ての要素を生成する必要がないので、値が列挙されるごとに画面表示を行って体感速度を向上させられたり出来ます。&lt;br /&gt;また、条件に一致する値を一つだけ検索する場合などに、要素が見つかった時点で値の列挙を打ち切ることも出来ます。&lt;br /&gt;&lt;br /&gt;ジェネレータは、通常は下記のようにのようにfor...in文で使用します。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;for(let p in Process.all){&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(p.name=='ng.exe'){&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;println(p.commandline);&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;この例では、「Process.all」というプロパティで取得できるジェネレータが列挙するProcessオブジェクトをそれぞれ「p」という変数に代入して「{}」内の処理を実行します。&lt;br /&gt;実行してみると、「ng.exe」で実行中のプロセスのコマンドラインが表示されるはずです。&lt;br /&gt;&lt;br /&gt;しかし、NILScriptで用意されているジェネレータの拡張メソッドを使うと、ループを使用せずに様々な反復処理を効率よく記述できる場合があります。&lt;br /&gt;例えば、前述の例は、拡張メソッドを使うと以下のように記述できます。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Process.all.filter('name','ng.exe').map('commandline').execute(println);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ここでは、最終的にグローバルに定義済みのprintln関数に渡されていますが、「execute(function(){})」のようにして任意の処理を実行させることも可能です。&lt;br /&gt;&lt;br /&gt;なお、ジェネレータではなく配列が必要な場合などは「Process.all.toArray()」のようにすると、配列に変換できます。&lt;br /&gt;また、逆に配列などをジェネレータに変換する「$G()」という関数も用意されています。&lt;br /&gt;&lt;br /&gt;ジェネレータには、他にも多数の拡張メソッドが定義されており、同梱の「doc\base_stdex.txt」で説明されています。&lt;br /&gt;全てを使いこなす必要はありませんが、filter()やmap()、execute()、toArray()などは、覚えておくと役に立つでしょう。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-3138325467743780132?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/3138325467743780132/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_2229.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3138325467743780132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3138325467743780132'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_2229.html' title='値を列挙するジェネレータの使い方'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-6641792599816584884</id><published>2010-08-12T03:09:00.000+09:00</published><updated>2010-08-12T03:09:57.394+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>使い回したい機能をユニットスクリプトにする</title><content type='html'>大がかりなスクリプトをいくつか書いていると、前に書いた処理を使い回したくなることがあります。このような場合は、NILScriptにおけるライブラリである「ユニット」を作成しておいて、必要な場所で「require()」などで読み込んで使うようにすると良いでしょう。&lt;br /&gt;&lt;br /&gt;ユニットスクリプトは、NILScriptの実行ファイルと同じディレクトリにある「lib」ディレクトリ内にディレクトリを作って、そこに作成します。&lt;br /&gt;このディレクトリ内にあるディレクトリ名には「HTTP._test」のように、「.」に続いて謎の文字列が付加されていますが、これはユニットのバージョンを区別するものです。&lt;br /&gt;「require("HTTP")」のようにバージョンの部分を省略して読み込んだ場合、辞書順で並び替えた時に一番後に来るバージョンのユニットが読み込まれます。バージョン部分も含めた名前を指定してrequire()を呼べば、任意のバージョンを使うことも可能です。&lt;br /&gt;バージョンアップで仕様変更された時に、旧バージョンと新バージョンを共存させて使い分けたりするために、このような仕様が用意されています。&lt;br /&gt;作成したユニットを公開するつもりが特になければ、バージョン部分は付けなくても構いません。&lt;br /&gt;&lt;br /&gt;ユニットのディレクトリの中には、ユニットのバージョンを除く名前部分に拡張子「.ng」を付けたファイル名でスクリプトファイルを作成します。このスクリプトファイルには、ユニットの初期化を行う関数を記述します。&lt;br /&gt;関数が呼び出される時のthisは、require()が返すUnitクラスのインスタンスオブジェクトです。基本的に、以下のようにしてクラスなどを定義し、ユニットのメンバとして公開します。クラスだけでなく、単なるオブジェクトや値、関数なども公開できます。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(function(){&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var MyClass=new Class({&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;});&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;this.MyClass=MyClass;&lt;br /&gt;})&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;一旦varで変数に代入してからthisのメンバに代入しているのは、ユニットスクリプト内の処理からそのクラスを参照しやすくするためです。&lt;br /&gt;クラスの定義方法については、NILScriptに同梱の「doc\base_class.txt」や、同梱のユニットスクリプトの実例を参照してください。&lt;br /&gt;&lt;br /&gt;なお、ユニットスクリプトに記述された関数内では、「this.directory」でユニットスクリプトのあるディレクトリを表すDirectoryオブジェクトを参照できます。&lt;br /&gt;これを使用することで、ユニットに同梱したファイルのフルパスを得たり、内容を読み込んだり出来ます。&lt;br /&gt;例えば、「HTTPD」ユニットでは、スクリプトの最初の方で「var jQuery=this.directory.file('jquery.js').load();」として、ページ中に埋め込むjQueryのスクリプトを読み込んでいます。&lt;br /&gt;File/Directoryオブジェクトの使い方については、NILScriptに同梱の「doc\base_io.txt」を参照してください。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-6641792599816584884?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/6641792599816584884/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_12.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6641792599816584884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6641792599816584884'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_12.html' title='使い回したい機能をユニットスクリプトにする'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-9041943130081531030</id><published>2010-08-12T00:30:00.001+09:00</published><updated>2010-08-12T00:30:20.266+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>Window.observe()でウィンドウの表示などに応答</title><content type='html'>NILScriptでは、「Window」ユニットに用意されている機能を使って、自前のGUIウィンドウを表示したり、他のプログラムの持つウィンドウを操作したり出来ます。&lt;br /&gt;&lt;br /&gt;多くの機能が用意されているWindowクラスですが、中でも特徴的なのはウィンドウの生成や表示を監視してコールバック関数を実行してくれる「Window.observe()」でしょう。&lt;br /&gt;この機能では、イベントの発生をシステムから通知してもらうシェルフックという仕組みを使用しているため、ループやタイマーでウィンドウの状態を監視するのに比べて低負荷で素早い応答が可能になっています。&lt;br /&gt;&lt;br /&gt;次のスクリプトは、Window.observe()を使用したスクリプトの例です。&lt;br /&gt;ここでは、ウィンドウの表示を監視し、条件に一致するウィンドウだったらそのウィンドウを閉じるという処理を行っています。&lt;br /&gt;==の後の文字列は、それぞれ実行ファイル名とウィンドウタイトルの条件を指定しています。これを変更すれば、不要なダイアログなどを自動で閉じるツールとして使えるでしょう。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Main.createNotifyIcon();&lt;br /&gt;var Window=require('Window').Window;&lt;br /&gt;Window.observe('show',function(e){&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if((e.window.ownerProcess.name=='notepad.exe')&amp;amp;&amp;amp;(e.window.title=='行へ移動')){&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;e.window.close();&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Window.observe()の第1引数はイベント名で、以下の物を指定できます。&lt;br /&gt;&lt;br /&gt;&lt;dl&gt;&lt;dt&gt;activate&lt;/dt&gt;&lt;dd&gt;新たなウィンドウがアクティブになったとき。&lt;/dd&gt;&lt;dt&gt;create&lt;/dt&gt;&lt;dd&gt;ウィンドウが生成されたとき。&lt;/dd&gt;&lt;dt&gt;destroy&lt;/dt&gt;&lt;dd&gt;ウィンドウが破棄されたとき。&lt;/dd&gt;&lt;dt&gt;show&lt;/dt&gt;&lt;dd&gt;表示されたとき。なお、ツールチップなどのウィンドウでも発生する。&lt;/dd&gt;&lt;dt&gt;hide&lt;/dt&gt;&lt;dd&gt;非表示になったとき。&lt;/dd&gt;&lt;dt&gt;redraw&lt;/dt&gt;&lt;dd&gt;タイトルバーの内容が変更されたときなど。変更前と同じ内容の時もある。&lt;/dd&gt; &lt;/dl&gt;&lt;br /&gt;第2引数には、イベントが発生した時に実行されるコールバック関数を指定します。&lt;br /&gt;この関数の第1引数には、「window」メンバにイベント発生元のウィンドウを表すWindowオブジェクト、「event」メンバに発生したイベント名が格納されたオブジェクトが渡されます。&lt;br /&gt;Windowオブジェクトに用意されている機能については、NILScriptに同梱の「doc\Window.txt」を参照してください。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-9041943130081531030?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/9041943130081531030/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/windowobserve.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/9041943130081531030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/9041943130081531030'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/windowobserve.html' title='Window.observe()でウィンドウの表示などに応答'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8409305668248459553</id><published>2010-08-11T16:39:00.002+09:00</published><updated>2010-08-11T16:39:46.533+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='解説'/><title type='text'>ユニット(拡張ライブラリスクリプト)の読み込み方法</title><content type='html'>NILScriptでは、主要な機能以外の多くの機能は「ユニットスクリプト」というライブラリになっており、実行時に必要になった時点で動的に読み込んで使うようになっています。&lt;br /&gt;ユニットというのはDelphiに倣った呼称で、「ライブラリ」や「モジュール」にしなかったのは、DLLなどと混同されないようにするためです。&lt;br /&gt;今回は、ユニットで定義されているクラスを利用するためのいくつかの方法について説明します。&lt;br /&gt;&lt;br /&gt;最も推奨される方法は「require()」です。この関数は、引数で指定したユニットを読み込んで、Unitクラスのインスタンスオブジェクトを返します。ユニットが提供するクラスなどは、このオブジェクトのメンバとして格納されています。&lt;br /&gt;なお、同じユニットを複数回require()した場合、読み込みや初期化が行われるのは最初の1回だけで、以降は1回目の返り値が使い回されます。&lt;br /&gt;ユニットが提供するクラスを複数回使用する場合は、このオブジェクトを変数に代入しておくとより効率的ですが、1回しか参照しない場合は「require("HTTPD").HTTPD.create(/*...*/);」のように、直接配下のクラスの機能を呼び出しても構いません。&lt;br /&gt;提供されるクラスが1つだけのユニットを使う時や、使いたいクラスが1つだけの場合は、「var Clipboard=require("Clipboard").Clipboard;」のように、使いたいクラス自体を変数に代入してもいいでしょう。&lt;br /&gt;また、分割代入という方法を使えば、「var {Keyboard,Key}=require("Keyboard");」のようにして、複数のクラスをローカル変数に代入することも可能です。&lt;br /&gt;ユニットで定義されている名前とは別の名前の変数に代入したい場合は、「var {Keyboard:KB,Key}=require("Keyboard");」のようにすることも出来ます。この場合、Keyboardクラスは「KB」というローカル変数に代入されます。&lt;br /&gt;&lt;br /&gt;一方、最も手軽な方法は、「use()」です。こちらは、引数で指定した名前のユニットで提供されているメンバをグローバル変数として展開します。&lt;br /&gt;use()は手軽な反面、既存のグローバル変数を上書きしてしまうので、注意が必要です。&lt;br /&gt;ユニットが提供するクラスの中には、標準状態でグローバルに定義されているクラスや、他のユニットから展開されたクラスと同じ名前のクラスが存在する可能性があるからです。&lt;br /&gt;use()は、数行程度の簡単なスクリプトでしか使わない方がよいでしょう。特に、自作のユニットスクリプトの中で使うのは絶対に避けてください。&lt;br /&gt;&lt;br /&gt;ユニットが提供するクラスを、グローバル変数としてではなくローカル変数として展開する方法として、「eval(Unit())」という書き方も用意されています。&lt;br /&gt;「Unit」を関数として呼び出すと、引数で指定した名前のユニットを読み込んで各メンバをローカル変数に代入するという内容のスクリプト文字列が返されます。これをeval()することで、その場所のローカル変数に展開するのです。&lt;br /&gt;この時、「var」による関数スコープではなく、「let」によるブロックスコープが使用されます。&lt;br /&gt;既存のグローバル変数と重複する名前のクラスが定義されているユニットを手軽に使いたい場合などに利用するといいでしょう。&lt;br /&gt;ただし、何のブロックの内側でもないトップレベルで使用すると、グローバル変数を上書きしてしまうので注意してください。&lt;br /&gt;&lt;br /&gt;また、応用的な方法として「with(reqiure()){/*...*/}」という書き方も出来ます。&lt;br /&gt;この場合、withブロックの中ではrequire()が返したUnitオブジェクトのメンバをローカル変数のように利用できます。&lt;br /&gt;比較的手軽で安全なので、覚えておくとよいでしょう。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8409305668248459553?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8409305668248459553/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_2026.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8409305668248459553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8409305668248459553'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_2026.html' title='ユニット(拡張ライブラリスクリプト)の読み込み方法'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-302108212345740341</id><published>2010-08-11T06:10:00.003+09:00</published><updated>2010-08-19T23:50:30.167+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='クリップボード'/><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>ClipboardでHTML形式を読み書きする</title><content type='html'>NILScriptには、クリップボードの読み書きを行うClipboardユニットが用意されています。&lt;br /&gt;Clipboardユニットでは、単なるテキスト形式以外にも、ブラウザ上のWebページをコピーした時に格納されるHTML形式や、エクスプローラなどでファイルをコピーした時の形式なども操作できます。&lt;br /&gt;これらの中でも特に役に立つのが、HTML形式の読み書きでしょう。&lt;br /&gt;&lt;br /&gt;Webページの内容をコピーしてテキストエディタに貼り付けた場合、テキストとして表示されていなかったリンク先のURLなどは失われてしまいますが、ClipboardユニットのHTML形式読み取り機能を利用すれば、コピーされたHTMLを文字列として読み取ることが出来ます。&lt;br /&gt;例えば、Webページ上のリンク集などをコピーした状態で以下のような式を使用すれば、コピーされたHTMLからリンクされていたURLを配列として抽出できます。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;require("Clipboard").Clipboard.html.html.grep(/&amp;lt;a [^&amp;gt;]*href="([^"]*)"/i).map("1").toArray()&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;これを応用すれば「コピーした範囲にあるリンクを全て開く」などの機能を実現できます。&lt;br /&gt;なお、grep()やmap()などは、SpiderMonkeyの「ジェネレータ」の拡張機能としてNILScriptで用意されているものです。詳細はNILScriptに同梱の「doc\base_stdex.txt」を参照してください。&lt;br /&gt;&lt;br /&gt;また、以下のようにすれば、指定したHTMLをHTML形式としてクリップボードにコピーすることも出来ます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;require("Clipboard").Clipboard.html="&amp;lt;b&amp;gt;NILScript&amp;lt;/b&amp;gt;"&lt;/blockquote&gt;&lt;br /&gt;これをブログの投稿画面などのWYSIWYG編集欄や、一部のワープロソフトなどに貼り付ければ、HTML内の文字装飾やレイアウト、リンクなどが反映されます。&lt;br /&gt;&lt;br /&gt;これらの機能をHotstrokesなどと組み合わせて利用すれば、Webブラウジングや文書の編集などを効率化させられるでしょう。&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-302108212345740341?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/302108212345740341/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/clipboardhtml.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/302108212345740341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/302108212345740341'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/clipboardhtml.html' title='ClipboardでHTML形式を読み書きする'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-5503974560116814999</id><published>2010-08-11T04:42:00.003+09:00</published><updated>2010-08-11T06:43:48.541+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>真のマルチスレッド</title><content type='html'>NILScriptでは、HTTPDの応答処理やキー・マウスのフックなど、様々な処理がマルチスレッドで並列実行されるようになっています。&lt;br /&gt;また、Thread.create()というメソッドを使用すれば、任意の関数を新規スレッドで実行させられます。&lt;br /&gt;これにより、HTTPの通信など時間のかかる処理を行っている間に、その処理の完了を待つ必要がない他の処理を進めたりできます。&lt;br /&gt;&lt;br /&gt;スクリプト実行環境のマルチスレッドというと、スクリプトエンジンが独自に複数の処理を切り替えながら少しずつ実行することで並列実行されているように見せる疑似マルチスレッドと、OSのスレッドの仕組みを利用して並列実行を行う真のマルチスレッドなど、いくつかの方式がありますが、NILScriptでは真のマルチスレッドが使用されています。&lt;br /&gt;これは、NILScriptで利用しているJavaScriptエンジンのSpiderMonkeyが、いくつかの点に注意するだけで簡単に真のマルチスレッドでの利用が出来るようになっているおかげです。&lt;br /&gt;&lt;br /&gt;NILScriptでは、多くの処理を外部のDLLが提供する関数を利用して実現していますが、そんな関数の中には処理に時間のかかる物も少なくありません。もし疑似マルチスレッドしか用意されていなかったら、データの読み込みなどを行っている間にキーボードフックの応答処理が実行できずに操作不能になるなど、様々な問題に見舞われることでしょう。&lt;br /&gt;こうした問題に悩まされることなく様々な機能を実現するためには、真のマルチスレッドで実行できることが非常に重要なのです。&lt;br /&gt;&lt;br /&gt;真のマルチスレッドには、マルチコアCPUなどの性能を引き出せるという利点もあります。実際のスレッドが一つしかない疑似マルチスレッドでは、一度に使われるコアは一つだけになっていまうので、デュアルコアCPUであれば50%までの性能しか引き出せませんが、各スレッドを別のコアで並列実行できる真のマルチスレッドでは、100%の性能を引き出せる場合もあるのです。&lt;br /&gt;SpiderMonkeyでは、使われなくなったデータを解放するGCの際に他のスレッドを一時停止してしまうので、スクリプト部分での処理が多いとあまり高速化できない場合がありますが、外部DLLに画像処理などの時間がかかる処理をさせる場合は、CPUのコアの数だけスレッドを生成して並列実行させることで、CPUの性能の限界まで高速実行させられるでしょう。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-5503974560116814999?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/5503974560116814999/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_4736.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5503974560116814999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/5503974560116814999'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_4736.html' title='真のマルチスレッド'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8063966178143362692</id><published>2010-08-11T00:29:00.000+09:00</published><updated>2010-08-11T00:29:58.824+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>キーボード・マウスのフック</title><content type='html'>Hotstrokesの内部処理の内、キーボードやマウスを扱う部分は「Keyboard」「Mouse」というユニットで定義されており、それぞれ単独で利用することも可能です。&lt;br /&gt;&lt;br /&gt;これらのユニットでは、ユーザーの操作がシステムに受理される前に特定の処理を呼び出して、何らかの処理を行ったり操作の受理をブロックすることなどが出来る「フック」という仕組みを利用する機能が提供されています。&lt;br /&gt;これらの機能を利用すれば、あらゆるキー操作に一括してある処理を割り当てたり、マウスの移動が発生するごとに処理を実行させるなど、Hotstrokesでは出来ないようなスクリプトも実現可能です。&lt;br /&gt;&lt;br /&gt;このようなキー・マウスフックの機能を標準で利用できるスクリプト実行環境はあまり多くありませんので、フックを用いたツールを手軽に自作したい人などは、NILScriptを試してみるといいでしょう。&lt;br /&gt;NILScriptに同梱の「sample」ディレクトリには、全てのキー操作の情報をコンソールに逐次出力する「keyboard_hook.ng」や、マウスが移動した時にその操作を無効にして上下左右が逆の操作を発生させる「sample/mouse_hook.ng」などのスクリプト例が用意されているので、参照してみてください。&lt;br /&gt;&lt;br /&gt;なお、これらの機能を利用したスクリプトでは、あらゆる操作が不能になってしまうような危険なバグが発生する可能性があることに注意してください。&lt;br /&gt;仮想PCやテスト用のPCなど、再起動する羽目になっても良いような環境で十分にテストをすることが望ましいでしょう。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8063966178143362692?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8063966178143362692/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_11.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8063966178143362692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8063966178143362692'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post_11.html' title='キーボード・マウスのフック'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-8200270000042645797</id><published>2010-08-10T23:54:00.000+09:00</published><updated>2010-08-10T23:54:30.716+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hotstrokes'/><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>Hotstrokesのプラグイン機構</title><content type='html'>Hotstrokesでは、プラグイン機構によりキー名の定義などを追加することも可能になっています。&lt;br /&gt;標準では、マウスのボタン操作やカーソル移動をストロークとして扱うプラグインなどが用意されており、マウスジェスチャ的な操作への動作割り当ても可能です。&lt;br /&gt;その他、プラグインを作成すれば、タブレットやジョイスティックなどのデバイスの操作を独自のキーとして扱うことも可能になるでしょう。&lt;br /&gt;&lt;br /&gt;更に、プラグイン機構では、条件別割り当てで使用する条件や、動作割り当ての動作として定義する処理なども定義できるようになっています。&lt;br /&gt;特定のソフトに関する条件や動作の定義をまとめたプラグインを作成して公開しておけば、他の人はそれを導入して操作・条件・動作の組み合わせを記述するだけで簡単に望みの機能を利用できるはずです。&lt;br /&gt;Hotstrokesでは、難しい定義をなるべく簡単に記述できるようにするような配慮は特に行われていませんが、これは条件や動作の定義は十分にスキルのある人がプラグインとして公開することを想定しているからです。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-8200270000042645797?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/8200270000042645797/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/hotstrokes_10.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8200270000042645797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/8200270000042645797'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/hotstrokes_10.html' title='Hotstrokesのプラグイン機構'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-3179135561167483677</id><published>2010-08-10T23:53:00.001+09:00</published><updated>2010-08-13T03:14:55.709+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hotstrokes'/><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>マルチストローク対応ホットキー定義機能「Hotstrokes」</title><content type='html'>NILScriptの機能の中でも比較的初期に実装され、代表的な機能であると思われている感があるのが「Hotstrokes」ですが、実はドラゴンボールの技に例えると「太陽拳」くらいの、たまに活躍するけどそれほど重要ではないという感じのポジションにあったりします。&lt;br /&gt;しかし、せっかく作ったのですから、主な特徴について紹介しようと思います。&lt;br /&gt;実際の使用例や詳細な仕様については、NILScriptのアーカイブに同梱されている「sample\Hotstrokes.ng」や「doc\Hotstrokes.txt」を参照してください。&lt;br /&gt;&lt;br /&gt;Hotstrokesの基本的な機能は、特定のキー操作が行われた時にスクリプトで定義された処理を実行する「ホットキー」的なものですが、複数のキー操作からなるストローク列に対する動作割り当てを簡単に記述できるようになっているのが特徴です。&lt;br /&gt;複数のキー操作というのは、例えばEmacsなどで見られる「C-x C-c」のような2ストロークキーや、「Ctrlキーの2連打」などのようなものです。また、あるキーを押してから他のキーを押さずに放すタップ操作なども、「押す」と「放す」の2つの操作からなる複数ストローク操作と言えます。(通常のホットキーは、押し下げた瞬間に発動するのが一般的です。)&lt;br /&gt;その他、各ストロークを一定時間内に行ったり、「長押し」など一定時間待機してから続きの操作を行うなどの操作も、"Ctrl+C"のような基本的なホットキー定義と同じように、一つの定義文字列で指定できます。&lt;br /&gt;&lt;br /&gt;また、既存のキーをCtrlやShiftのようなモディファイアキーとして再定義することも可能です。「mod1」のような同名のキーをいくつでも定義できる他、単に押してからすぐ放した時は本来のキーの動作を発生させる「ワンショットモディファイア」などと呼ばれる機能も簡単に定義可能です。&lt;br /&gt;&lt;br /&gt;操作が行われた時に実行される動作の定義には、NILScriptの関数を指定できるので、ウィンドウを閉じるなどの操作をしたり別のキー操作を発生させるだけでなく、様々な動作を定義可能です。&lt;br /&gt;また、アクティブウィンドウの種類などの条件に応じて動作を変える条件別割り当ても可能です。条件もNILScriptの関数で柔軟に定義可能です。&lt;br /&gt;&lt;br /&gt;「谺の隠れ家(&lt;a href="http://echokoda.y0r.net/archives/category/soft/nilscript"&gt;http://echokoda.y0r.net/archives/category/soft/nilscript&lt;/a&gt;)」というサイトでは、Hotstrokesを利用して「下駄配列」や「月配列」などの仮名入力を定義するスクリプトが公開されているので、Hotstrokesの応用例に興味がある人は是非参照してみてください。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-3179135561167483677?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/3179135561167483677/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/hotstrokes.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3179135561167483677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/3179135561167483677'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/hotstrokes.html' title='マルチストローク対応ホットキー定義機能「Hotstrokes」'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-2588962178476524791</id><published>2010-08-10T22:37:00.001+09:00</published><updated>2010-08-11T00:36:16.736+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='周辺ツール'/><title type='text'>スクリプト編集に使うテキストエディタ</title><content type='html'>NILScriptのスクリプトは、テキストエディタであればWindows標準のメモ帳でも作成できないことはありませんが、より高機能なテキストエディタを使用した方が快適です。&lt;br /&gt;&lt;br /&gt;NILScriptの作成には、「VxEditor(&lt;a href="http://dr-x.jimdo.com/"&gt;http://dr-x.jimdo.com/&lt;/a&gt;)」というエディタが使用されています。&lt;br /&gt;「{」の直後で改行したり行頭で「}」を入力することで自動的にインデントを行うスマートインデントや、3カテゴリまでのキーワード群を定義可能な色分け表示など、プログラミングを快適にする機能が多数用意されています。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;また、JavaScriptに似たDMonkeyというスクリプト言語を利用したマクロ機能が搭載されており、様々な機能を追加可能です。&lt;/div&gt;&lt;div&gt;特に、「VxEditor &amp;amp; DMonkey布教ページ(&lt;a href="http://lukewarm.s41.xrea.com/"&gt;http://lukewarm.s41.xrea.com/&lt;/a&gt;)」の「VxEditor用DMS」で公開されている「dabbrev」や「インクリメンタルサーチ」、「VxEditor &amp;amp; DMonkey関連アップローダー」の081番で公開されている単語ジャンプなどは、プログラミングの際に非常に役立っています。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;これらのマクロの多くは、VxEditorとよく似たタブ型エディタの「JmEditor」でも使用できるので、高解像度のモニタでいくつものウィンドウを並べて編集したい人以外は、そちらを使うと良いかもしれません。&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_wiFD7NiUNAg/TGFTvqBc-kI/AAAAAAAAABY/kQFmtxIIQzc/s1600/20100810222716.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_wiFD7NiUNAg/TGFTvqBc-kI/AAAAAAAAABY/kQFmtxIIQzc/s320/20100810222716.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;VxEditor &amp;amp; DMonkey布教ページ&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;さて、NILScriptでは、基本的な機能以外はユニットスクリプトとして分割されていますが、それぞれのユニットはどんなに長くても一つのスクリプトにまとめられ、細かい処理内容に応じて分割されたりはしていません。&lt;/div&gt;&lt;div&gt;これは、先に挙げたマクロの機能を最大限に活用するためです。&lt;/div&gt;&lt;div&gt;関連するコードが一つのファイルにまとまっていれば、インクリメンタルサーチや同一単語間ジャンプでどこにでも素早く移動できるのです。&lt;/div&gt;&lt;div&gt;また、テキスト中の単語からカーソル位置の単語に先頭一致する単語を列挙して候補として表示し省入力を実現するdabbrevでも、ファイルを分割しない方が補完できる単語が多くなります。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;どこに何が書かれているかを知らない人にとっては、分割されていない長大なスクリプトファイルを読み解くのは大変だと思われるかも知れませんが、「new Class」を含む行を検索したりすれば、大まかな構成はすぐに把握できるでしょう。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-2588962178476524791?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/2588962178476524791/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2588962178476524791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/2588962178476524791'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/blog-post.html' title='スクリプト編集に使うテキストエディタ'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wiFD7NiUNAg/TGFTvqBc-kI/AAAAAAAAABY/kQFmtxIIQzc/s72-c/20100810222716.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-1746510674886884916</id><published>2010-08-10T10:16:00.000+09:00</published><updated>2010-08-10T10:16:04.765+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='機能紹介'/><title type='text'>HTTPD</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;NILScriptに用意されている機能の中で最も特徴的なのが、Webサーバ機能を実現する「HTTPD」です。&lt;/div&gt;&lt;div&gt;単にローカルにあるファイルを公開するだけでなく、リクエスト内容に応じて動的にWebページを生成して返すことも可能です。&lt;/div&gt;&lt;div&gt;また、ブラウザ上のJavaScriptからNILScript側の機能を呼び出すための機能も用意されており、HTMLによる自由度の高い画面表示とNILScriptの多彩な機能を連携させたアプリケーションを作成可能です。&lt;/div&gt;&lt;div&gt;ブラウザからアクセスして利用するため、設定画面などをブックマークしておいて素早く呼び出せるなど、通常のGUIアプリケーションでは出来ない使い方も可能です。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;HTTPDの機能を試すには、NILScriptのアーカイブに含まれる「start_httpd.ng」を実行してください。サンプルのWebサーバスクリプトが起動し、ブラウザでドキュメントの検索・閲覧ページが表示されるはずです。&lt;/div&gt;&lt;div&gt;このスクリプトには、将来的には自作スクリプトの管理やアップデート情報の閲覧などの機能も追加され、NILScriptに関するポータルサイト的な物となる予定です。&lt;/div&gt;&lt;div&gt;HTTPDを利用したプログラムを作ってみたい場合は、アーカイブ内の「sample\HTTPD.ng」にあるサンプルスクリプト本体や、HTTPDのドキュメントを参考にしてください。&lt;/div&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_wiFD7NiUNAg/TGCJ8oWqhAI/AAAAAAAAAAU/2kqsFcmtbFM/s1600/20100810080619.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_wiFD7NiUNAg/TGCJ8oWqhAI/AAAAAAAAAAU/2kqsFcmtbFM/s320/20100810080619.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;HTTPDによって公開されたドキュメント閲覧ページ&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;「Script console」のリンクからは、NILScriptのスクリプトを簡単に実行するためのコンソールページを表示できます。下部の入力欄にスクリプトを入力してボタンを押すと、入力されたスクリプトがHTTPDに送信され、実行結果(最後に評価された式の値)やエラーが返信され、ログとして表示されます。&lt;/div&gt;&lt;div&gt;スクリプトは専用のスレッド上で実行され、定義した変数などは次回実行時に引き継がれるので、対話型インタプリタのような感覚で利用できます。&lt;/div&gt;&lt;div&gt;簡単なコードを試してみたい場合などに役立つでしょう。&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_wiFD7NiUNAg/TGCKzlWOYKI/AAAAAAAAAAc/sxsYZrkPIjE/s1600/20100810080955.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_wiFD7NiUNAg/TGCKzlWOYKI/AAAAAAAAAAc/sxsYZrkPIjE/s320/20100810080955.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;スクリプトコンソールのページ&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;このコンソールはHTTPDのプラグイン機構で実装されており、処理の本体は「plugins\HTTPD\ScriptEvaluator\ScriptEvaluator.ng」内に記述されています。スクリプト内容を見れば、NILScriptによってサーバ側関数の呼び出しがラップされて、HTTPのリクエストなどを意識することなく連携処理を記述できているのが分かるはずです。&lt;/div&gt;&lt;div&gt;また、スクリプト実行環境の部分はライブラリ化されており、「lib\ScriptEvaluator._test\ScriptEvaluator.ng」にあります。こちらでは、マルチスレッドでの同期処理機能などの使用例が見られます。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;なお、NILScriptのHTTPDは、ローカルネットワーク上から1人もしくは小数のユーザーがアクセスして利用することのみを想定しているため、インターネット上に公開して不特定多数のユーザーに利用してもらう用途には向いていません。&lt;/div&gt;&lt;div&gt;これは、NILScriptではネットサービス上から必要な情報を収集して様々に活用するプログラム群の作成を優先的な目標としているためです。&lt;/div&gt;&lt;div&gt;わざわざネットサービス型のプログラムを作成するのは、不特定多数のユーザーの投稿を利用した集合知的な機能を実現したい場合か、広告を掲載して収入を得たい場合などが主だと思われますが、広告を無視して情報を抽出するツールを使用してアクセスする人が増えれば、サーバ負荷ばかり増えて収入は減ってしまいます。&lt;/div&gt;&lt;div&gt;そうなると、NILScriptのHTTPDに不特定多数からのアクセスを捌くための機能を充実させたとしても、大した使い道が無く無駄になってしまうでしょう。&lt;/div&gt;&lt;div&gt;そのような理由から、今後も大規模ネットサービス公開向けの機能が積極的に実装される予定はありません。どうしても欲しいという人は、自分で拡張ライブラリを作成してください。&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-1746510674886884916?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/1746510674886884916/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/httpd.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/1746510674886884916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/1746510674886884916'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/httpd.html' title='HTTPD'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_wiFD7NiUNAg/TGCJ8oWqhAI/AAAAAAAAAAU/2kqsFcmtbFM/s72-c/20100810080619.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-576000796195395635.post-6489530533088798467</id><published>2010-08-10T07:52:00.001+09:00</published><updated>2010-08-10T07:53:57.520+09:00</updated><title type='text'>NILScriptとは</title><content type='html'>NILScriptは、下記のURLで配布されているJavaScriptベースのスクリプト実行環境です。&lt;br /&gt;テキストエディタなどでプログラムを記述し、保存したファイルパスをコマンドライン引数に与えて実行することで、様々な処理を実行させられます。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lukewarm.s151.xrea.com/nilscript.html"&gt;http://lukewarm.s151.xrea.com/nilscript.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ファイルやテキストの処理と言った基本的な機能から、HTTP通信などのインターネット関連の機能、ウィンドウやキーボード、マウスの自動操作など、多くの機能が用意されています。&lt;br /&gt;DLLなどの関数を呼び出したり、メモリ上に確保されたバイト列を操作する機能が用意されているので、標準では用意されていない機能も実現しやすくなっています。&lt;br /&gt;&lt;br /&gt;NILScriptの最大の特徴にして長所と言えるのが、スクリプトエンジン部分にMozilla Firefoxなどに搭載されている「SpiderMonkey」というJavaScriptエンジンを採用していることです。&lt;br /&gt;JavaScriptは、数あるスクリプト言語の中でも特にC言語に似た仕様を持つ言語ですので、JavaScript自体には馴染みがなくても、C++やJava、C#など、C言語風の構文を持つ言語の使用経験があれば、戸惑うことなく使用できるはずです。&lt;br /&gt;&lt;br /&gt;NILScriptは、これからプログラミングを習得しようとしている人にもお薦めです。&lt;br /&gt;テキストなどを表示するだけのプログラムではなく、自分が欲しいツールを作りながらであれば、飽きたり挫折することなく学習を続けられるはずです。&lt;br /&gt;NILScriptでC言語風の構文に慣れておけば、C++やJava、C#などの言語で高度なプログラムを作りたくなった時にも、スムーズに習得できるでしょう。&lt;br /&gt;&lt;br /&gt;一方、プログラミングの経験がなく、今後も本格的に習得するつもりは一切無いけれど、便利な機能を利用したいという人は、NILScriptよりも他のスクリプトユーティリティを使った方がいいかもしれません。&lt;br /&gt;JavaScriptには、変数名などの識別子を大文字・小文字の別まで正しく記述しなければならなかったり、文の後に「;」を記述しなければならないなど、プログラミング未経験者にとって一見理不尽に面倒臭く感じられる仕様が少なくないのに対し、独自仕様のスクリプトエンジンを搭載したスクリプトユーティリティでは、こうしたプログラミング未経験者への配慮が手厚い傾向にあります。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/576000796195395635-6489530533088798467?l=nilscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilscript.blogspot.com/feeds/6489530533088798467/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://nilscript.blogspot.com/2010/08/nilscript.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6489530533088798467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/576000796195395635/posts/default/6489530533088798467'/><link rel='alternate' type='text/html' href='http://nilscript.blogspot.com/2010/08/nilscript.html' title='NILScriptとは'/><author><name>NILScript</name><uri>http://www.blogger.com/profile/02240077852472584982</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_wiFD7NiUNAg/TGC9a7B2IvI/AAAAAAAAAAw/gFvlHhg_Bcc/S220/nilscript.png'/></author><thr:total>0</thr:total></entry></feed>
