前回ブログからの続きで、
DeleteFolderメソッドを実行すると フォルダ名までも消されてしまう
問題の解決策を試してみる。
ということで、前回ブログのスクリプトに変更を加えたのがこちら。
//
// フォルダ削除実験スクリプト2 WSH(JScript)
//
// FileSystemObject オブジェクトの作成
var FSO = WScript.CreateObject("Scripting.FileSystemObject");
// GetFolderメソッドからフォルダ名を抽出
// 実際は、きちんとリストしないといけませんが
// ここでは省略して最初に見つかったひとつのサブフォルダだけを扱います。
folderNameEnu = new Enumerator( FSO.GetFolder(".").SubFolders );
var DelFolderName = folderNameEnu.item();
// 消されちゃうんであれば、もう一個 余計に準備しておく。
var DelFolderName2 = DelFolderName;
// 削除前にフォルダ名の表示
WScript.Echo( "削除するフォルダは " + DelFolderName2 + " です。");
// フォルダの削除
FSO.DeleteFolder(DelFolderName, true);
// 結果の表示
WScript.Echo( "削除したフォルダは " + DelFolderName2 + " です。");
ご注意:このスクリプトを実行すると、カレント・フォルダの下にあるサブフォルダをひとつ、
実際に削除してしまいますので、お取り扱いには十分にご注意ください。
これは DeleteFolderメソッドに対して、
引数として与えたフォルダ名の文字列が消されてしまうのであれば、
消される前に それを控えておけばよいであろうと、
ということで単に、
var DelFolderName2 = DelFolderName;
の一行を加えてみた。
ところがその実行結果は前回と変わらず、やはり、
フォルダ名が消されてしまって、
フォルダ削除後のフォルダ名表示ができなかった。
この種の問題は いわゆる「値渡し」 と 「参照渡し」の問題で、
これについては、マイクロソフトの JScript ドキュメント「
JScript: データのコピー、受け渡し、および比較」に記載されている。
このページの説明によると「値渡し」とは
値渡しによるコピーや受け渡しでは、コンピュータのメモリ内に空間が新しく確保され、元の値がそこへコピーされます。
それぞれの値は別の値と見なされるため、値渡しした後で元の値を変更しても、コピーされた値に影響は及びません (逆の場合も同様です)。
一方、「参照渡し」とは、
参照渡しによるコピーや受け渡しでは、実際に作成されるのは元の項目へのポインタですが、そのポインタを、あたかもコピーされた項目であるかのように扱うことになります。この場合は、元の項目に変更を加えると、元の項目とコピーされた項目の両方が変更されます (逆の場合も同様です)。実際存在する項目は 1 つだけで、"コピーされた項目" は、データへのもう 1 つの参照に過ぎません。
と説明されている。
そしてJScript の文字列の場合は
文字列の場合は、コピーや受け渡しは参照渡しで行われますが、比較は値渡しで行われます。
となっている。つまり JScriptにおいて 「=」を用いて
文字列変数に文字列変数を代入したとしても
それは、元の文字列へのポインタがひとつ増えただけであり、
実際に存在する文字列はひとつしかないわけである。
そのため、今回 追加した一行は全くの無駄ということになってしまう。
【参考リンク】
カテゴリー:
プログラミング
22:33
| コメント (0)
| トラックバック (0)
前回ブログからの続きで、
WSHによるバックアップ・スクリプトの開発中に
フォルダを削除する際にハマッタこと。
実際に書いたバックアップ用のスクリプトはもっと長いのだが、
この フォルダの削除に関する失敗部分だけを抜き出して
このブログで解説してみようと思う。
ここで私がプログラムしたいと思ったのは、
削除したフォルダの名前をログに記録しておくことだった。
ちなみに、WSHにおけるイベント・ログの作成方法については、
@ITの解説記事
「運用 Windows管理者のためのWindows Script Host入門」の
アプリケーション・イベント・ログの作成
に詳しく解説してある。
以下のスクリプト例では、実験を簡単にするために、
GetFolderメソッドから得たフォルダ名の最初のひとつのみを扱っている。
実際に動作させているバックアップ・スクリプトでは
きちんとリストにして全てのサブフォルダ名について処理している。
また、この例では イベント・ログに書き込む代わりに
画面に表示するように変更している。
//
// フォルダ削除実験スクリプト1 WSH(JScript)
//
// FileSystemObject オブジェクトの作成
var FSO = WScript.CreateObject("Scripting.FileSystemObject");
// GetFolderメソッドからフォルダ名を抽出
// 実際は、きちんとリストしないといけませんが
// ここでは省略して最初に見つかったひとつのサブフォルダだけを扱います。
folderNameEnu = new Enumerator( FSO.GetFolder(".").SubFolders );
var DelFolderName = folderNameEnu.item();
// 削除前にフォルダ名の表示
WScript.Echo( "削除するフォルダは " + DelFolderName + " です。");
// フォルダの削除
FSO.DeleteFolder(DelFolderName, true);
// 結果の表示
WScript.Echo( "削除したフォルダは " + DelFolderName + " です。");
ご注意:このスクリプトを実行すると、カレント・フォルダの下にあるサブフォルダをひとつ、
実際に削除してしまいますので、お取り扱いには十分にご注意ください。
で、このスクリプトを実行してみると
削除したかったフォルダは見事に削除されているのであるが、
削除後、そのフォルダ名が画面に表示されないのである。
どうも、DeleteFolderメソッドは、フォルダを削除した際に、
そのフォルダ名のインスタンスまでも削除してしまっているようだ。
削除前に、フォルダ名をログに書き込んでしまえば それで問題ないのだが、
自分としては、フォルダの削除が完了したことを確認してからログに記録したいと思った。
しかし、このように ファイル名がなくなってしまっては
ログに書き込むこともできない。
次に、単純な解決方法を試してみたのだが
それについては次回のブログで。
【参考リンク】
カテゴリー:
プログラミング
22:52
| コメント (0)
| トラックバック (0)
WSH で JScript を使って
ファイルのバックアップを自動で行うスクリプトを書いていたのだが
そこでの調査結果をまとめておく。
今回 作ったバックアップ・スクリプトは
現在のフォルダを 別ドライブへ名前に日付をつけてコピーしておき、
何日か経って古くなった分は自動的に削除する、
といった仕様にしてみた。
WSH で ファイルやフォルダのコピーに関しては WSHの
ファイルおよびフォルダをコピーする のページに解説してある。
この解説にもあるとおり、ファイルをコピーしたり等の ファイルの操作には、
FSO (File System Object)
を使用する必要がある。
ともかく、ファイル操作をする前には、おまじないとして
var FSO = WScript.CreateObject("Scripting.FileSystemObject");
というオブジェクトの作成をしておき、あとは
FSO.CopyFile("c:\\COMPlusLog.txt", "c:\\x\\");
のように FSO オブジェクトのメソッド ひとつで ファイルのコピーが可能となる。
注意点としては、ファイル名の指定では、
英語環境ではバックスラッシュ「\」、日本語環境では円マーク「¥」を
2つ重ねないといけないということ。
フォルダ全体をコピーしたい場合も、
CopyFolder メソッド
を使えば、簡単にフォルダ単位のコピーができてしまう。
今回の場合、ここで与えるコピー先のフォルダ名に現在の日付データを加えるようにしただけだ。
削除に関しても
DeleteFile メソッド
や
DeleteFolder メソッド
を利用すれば簡単にできてしまう。
ところが、削除すること自身には問題はなかったのだが、
それとは別の思わぬ 落とし穴にはまってしまった。
それは次回のブログとさせてもらおう。
【参考リンク】
カテゴリー:
プログラミング
22:52
| コメント (0)
| トラックバック (0)
ちょっとした WSHスクリプト を JScript で書いていた際に、
文字列を右側から指定文字数だけ取り出す関数がほしくなった。
マイクロソフトの「JScript」のページ から、それらしいメソッドを探したのだが、
文字列内の、指定位置からの指定された長さを持つ部分を返す
substr メソッド とか、
文字列内の指定された位置にある文字列を返す
substring メソッド とかは
あるのだが、
文字列を右側から指定文字数だけ取り出すメッソドは見つからなかった。
VBScriptであれば、
Right 関数 というのがあって、単にこれを呼べばよいのだが、JScriptには存在していないようだった。
で、しょうがないので作ったのが以下の関数。
//
// 文字列を右側から指定文字数だけ取り出す関数
//
function right( str, n ) {
l = str.length;
if (n>l) n=l;
return( str.substring(l-n,l) );
}
strTest='ABCDEFG';
WScript.echo( strTest );
WScript.echo( right(strTest,3) );
もっとクールなソリューションがあるのかもしれないが、
とりあえず動いているのでよしとしよう。
それにしても、今回の状況を考えると、
WSHでスクリプトを書く際は、
素直に 「VBScript」を使った方が幸せなのかもしれないと感じた。
【参考リンク】
カテゴリー:
プログラミング
22:14
| コメント (1)
| トラックバック (0)
昨日のブログで、WSHが wscript.exe や cscript.exe により
実行されているところまでわかった。
これらはデフォルトでも、VBScript と JScript という
2つの言語に対応しているのだが、
果たして どうやってそれらを見分けているのだろうか。
解析するために、簡単な実験を行ってみた。
実験の準備として、
「Jtest.js」という名前を付けて
WScript.echo("Hello World!");
「Vtest.vbs」という名前を付けて
WScript.echo "Hello World!"
という2つのファイルを準備した。
これくらい短いプログラムでは、
違いとしては、関数の引数を括弧で囲むかどうかぐらいだ。
上記2つのファイルを ウィンドウズ・エクスプローラーから
ダブルクリックすると、エラーもなく、「Hello World!」が表示される。
当たり前だが 全く同じ結果となる。
次に、それぞれのファイルの拡張子を
「Jtest.js」を「Jtest.vbs」に、
「Vtest.vbs」を「Vtest.js」に変更してみる。
前述と同じように、ウィンドウズ・エクスプローラーから
ダブルクリックして、これら2つのファイルを実行してみると、
「Jtest.vbs」を実行させると
「Microsoft VBScript compilation error」というエラー表示が、
「Vtest.js」を実行させると、
「Microsoft JScript compilation error」というエラー表示になった。
このことから、wscript.exe や cscript.exe は
引数として与えられた実行ファイルの拡張子を見て、
どの言語として処理するべきかを判断していると
考えられる。
また、ついでに実験してみると、
「.js」の代わりに「.jse」、
「.vbs」の代わりに「.vbe」は利用できるようである。
カテゴリー:
プログラミング
22:26
| コメント (0)
| トラックバック (0)
昨日のブログでは JavaScript(JScript)を使って「Hello World!」を表示させてみたが、
その際、出来上がった「test.js」というファイルを ダブルクリックして実行してみた。
果たしてこのスクリプトを実際に実行しているのは何者なのだろうか?
調べてみると、WSH を実行するには2つの方法があり、
それぞれに専用のコマンドが用意されている。
ひとつは「wscript.exe」で、もうひとつが「cscript.exe 」である。
その違いは 前者はGUIベース、後者はコンソール・ベース となっている。
通常、エクスプローラー上でダブルクリックした際には
GUIベースの「wscript.exe」が実行されている。
その証拠に、今回作った「test.js」を
エクスプローラからダブルクリックすると、
「Windows Script Host」というタイトルが付いた小さなウィンドウが開いて
その中に「Hello World!」と表示された。
確認のためウィンドウズ・エクスプローラーの「ツール」メニューから
「フォルダ オプション(Folder Options)」を選んで
「ファイル タイプ (File Type)」タブをみてみると、
拡張子「.js」と「.vbs」のOpenアクションは
確かに「WScript.exe」にリンクされている。
また、「.jse」や「.vbe」も同様に「WScript.exe」に
リンクされていることが確認できる。
一方、「cscript.exe 」を使ってコンソール・ベースで実行するためには
コマンド・プロンプトに入って、そのファイルがあるディレクトリに行ってから
cscript test.js
とする。
すると、そのコマンド・プロンプト内で
上記コマンドに引き続き「Hello World!」とテキストで表示される。
【参考リンク】
カテゴリー:
プログラミング
22:03
| コメント (0)
| トラックバック (0)
WSH を使った 最も基本的なプログラミングをしてみる。
私も今までに いくつかのコンピュータ・プログラミング言語のお勉強をしてきたが、
その際のお決まりのプログラムが「Hello World!」と言う文字列を画面に表示する方法である。
今回も、この古き良き業界のしきたりにのっとって、
WSH で 「Hello World!」を表示してみることにする。
前のブログでも書いたとおり、
WSH では、VBScript と JavaScript(JScript) の 2つの言語処理系を備えいている。
巷の解説記事のほとんどは VBScript について書いてあるのだが、
あえてここでは、Jscript を使ってやってみる。
ノートパッドでも、TeraPad でも なんでもいいので、適当なテキスト・エディターを立ち上げて
WScript.echo("Hello World!");
と打ち込み、または、上記の行をカット&ペーストしてから
そのファイルに「test.js」という名前を付けて
適当なディレクトリ(ホルダー)に保存する。
打ち込む際は行末の「;」をお忘れなきように。
後は、ウィンドウズ・エクスプローラー(Windows Explorer)上で
その「test.js」というファイルを ダブルクリックすると、
「Windows Script Host」というタイトルが付いた小さなウィンドウが開いて
その中に「Hello World!」と表示されているハズである。
【参考リンク】
カテゴリー:
プログラミング
22:24
| コメント (0)
| トラックバック (0)