Windows TIPS
[Scripting]
  Windows TIPS TOPへ
Windows TIPS全リストへ

よく利用するジョブをスクリプトレットでコンポーネント化する

解説をスキップして操作方法を読む

山田 祥寛
2004/09/18
 
対象OS
Windows NT
Windows 2000
Windows XP
Windows Server 2003
多くのWSHスクリプトを記述していると、同じようなロジックを繰り返し記述するような局面が出てくる。
しかし部品化をするにもVisual BasicやC++など、本格的なプログラム言語を使用しなければならないのでは、あまりに敷居が高い。
スクリプトレットを利用することで、使い慣れたVBScriptやJScriptなどのスクリプト言語を利用してCOMコンポーネントを開発することができる。
 
解説

 このWindows TIPSでもさまざまなWSH(Windows Scripting Hosts)のコードを紹介してきた。恐らく多くのロジックを記述しているうちに、複数のコードから頻繁に使用する定型的なロジックが必ず出てくるはずだ。当然のことながら、このようなコードを個々の「.wsf」ファイルに記述するというのは、開発生産性/保守性いずれの観点から見ても好ましいものではない。

 しかし部品化を行うといっても、それだけのためにいちいちVisual BasicやC++のような本格的なプログラミング言語を利用しなければならないとしたら、少し大げさすぎる。スクリプト言語くらいしか書けないというレベルの管理者にとっては、敷居が高すぎる。また、WSHスクリプトを記述する際に主に採用されるVBScriptとVisual Basicは、比較的構文が似ているとはいえ、細部では異なる点も少なくない。既存のコードから共通のコードを切り出してコンポーネント化したいという場合に、そうした構文の違いを意識しながら、いちいちコードを書き換えていかなければならないというのは、とても面倒である。このような理由から、WSHスクリプトにおいて共通コードがあることを知りながら、なかなか部品化には踏み切れずにいたという諸氏も多いのではないだろうか。

 そこで本稿では、「スクリプトレット(ScriptLets)」というしくみを利用して、Windows TIPS「テンプレートを元に複数のメールを一括配信する」で紹介したコードからメール送信部を取り出し、メール送信コンポーネントを構築する方法について紹介する。スクリプトレットを簡単にいうと、COMコンポーネントをスクリプト言語で作成するための技術だ。スクリプトレットを利用することで、VBScriptやJScriptで記述したコードを任意のWSHスクリプトやVBA(Visual Basic for Application)、ASP(Active Server Pages)などのコードから共通して呼び出すことができるようになる。

 なお本TIPSでは、主にスクリプトレット固有の構文について解説する。メール送信ロジックにかかわる詳細や、サンプルの実行に必要な環境の準備については、先のTIPSを併せて参照いただきたい。


操作方法

手順1―テキスト・エディタでスクリプトレットのコードを入力する

 まずはテキスト・エディタ(メモ帳でも何でもよい)を開き、以下のコードを入力してほしい。なお「<!--〜-->」で囲まれた部分は、コードの意味を解説するためのコメント部分なので、省略してもよい。コメントには、スクリプトレットの簡単な説明を入れておいた。

※ファイルmail.wsc

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<!--スクリプトレット・コンポーネントは、XML構文にのっとって記述する必要がある。<package>要素は、スクリプトレット・コンポーネントのルート要素になる-->
<package>
  <!--1個のファイルに複数のコンポーネントを含めることができる。<component>要素は、個々のコンポーネントを定義する。複数コンポーネントを定義する場合は、<component>要素を並列に記述すればよい-->
  <component id="sendmail">
    <!--エラー処理の属性を宣言。エラーメッセージ出力の有無(error属性)、デバッグモードの有効/無効(debug属性)を指定。デバックモードが無効の場合、スクリプト・デバッガを起動できない-->
    <?component error="True" debug="True" ?>
    <comment>メール転送コンポーネント</comment>
    <!--<registration>要素は、コンポーネントの登録情報(プログラムID、バージョン番号、リモートから呼び出し可能か、備考)を定義する。ここで定義された情報は、後でレジストリ登録を行う際に使用される-->
    <registration progid="Wings.Sendmail" version="1" remotable="True"
      description="メール転送コンポーネント" />
    <!--コンポーネント内で定義されたメソッドの構成を宣言する。ここでは、configFile(設定ファイルへのパス)、data(配信リストを格納したAccessファイルへのパス)という2つの引数を受け取るTransformメソッド(内部の関数名はTransfer)を宣言する。dispid属性に0が指定された場合、該当するメソッドは「既定のメソッド」と見なされ、メソッド名を略記することができる-->
    <public>
      <method name="Transform" internalName="Transfer" dispid="0">
        <parameter name="configFile" />
        <parameter name="data" />
      </method>
    </public>
    <!--スクリプトレット・コンポーネント内で使用するオブジェクトの宣言-->
    <object id="objBsp" progid="Basp21" />
    <object id="objDb"  progid="ADODB.Connection" />
    <object id="objFs"  progid="Scripting.FileSystemObject" />
    <!--具体的なコードの記述。上記の<method>要素における記述は、あくまでメソッドの外枠を宣言したにすぎないので、実際のビジネスロジックは<script>要素配下に実装する必要がある-->
    <script language="VBScript">
    <![CDATA[
    Sub Transfer(configFile,data)
      Set objTs=objFs.OpenTextFile(configFile)
      strSrv=objTs.ReadLine()
      strFrm=objTs.ReadLine()
      strSbj=objTs.ReadLine()
      strBdy=""
      Do While Not objTs.AtEndOfStream
        strBdy=strBdy & objTs.ReadLine() & Chr(13) & Chr(10)
      Loop
      objDb.Provider="Microsoft.Jet.OLEDB.4.0"
      objDb.Mode=1
      objDb.ConnectionString=data
      objDb.Open()
      Set rs=objDb.Execute("SELECT * FROM mail")
      Do While Not rs.EOF
        strTo =rs("email")
        strTmp=strBdy
        For i=0 To rs.Fields.Count-1
          strTmp=Replace(strTmp,"$" & rs.Fields.Item(i).Name & "$", rs.Fields.Item(i).Value)
        Next
        lngRst=objBsp.SendMailEx("send.log", strSrv, strTo, strFrm, strSbj, strTmp, "")
        rs.MoveNext
      Loop
      objDb.Close()
    End Sub
    ]]>
    </script>
  </component>
</package>

 スクリプトレットの基本的な構造や使い方などについては、以下の資料なども参考にしてほしい。

 スクリプトレットの実行ファイルは拡張子「.wsc」(Windows Scripting Components)とする必要がある。ファイル名自体は何でもよいが、ここでは「mail.wsc」という名前で保存しておこう。

 一般的なCOMコンポーネントが使用に先立ってレジストリに登録しておく必要があったように、スクリプトレット・コンポーネントもまた、あらかじめレジストリに登録しておく必要がある(登録には管理者権限が必要)。具体的には、エクスプローラでスクリプトレットのファイルを右クリックし、ポップアップ・メニューから[登録]を選択する。ただしレジストリへの登録後もファイルは削除してはいけないので(登録時の場所にずっと置いておく必要がある)、あらかじめスクリプト登録用のフォルダなどを作成して、保存しておくとよいだろう。

スクリプトレット・コンポーネントの登録
スクリプトレット・コンポーネントを利用するには、最初にレジストリに登録しておく必要がある。いったん登録したコンポーネントは、解除するまでファイルの移動や削除指定をしてはいけないので、専用のフォルダを作って管理するとよいだろう。
  これを選択してスクリプトレット・コンポーネントを登録する。
  一度登録されたコンポーネントを解除するには、これを実行する。

 登録が完了すると、次のようなダイアログが表示されるはずである。

スクリプトレット・コンポーネントの登録完了の通知
コンポーネントの登録が正常に完了すると、このようなダイアログが表示される。

手順2―テキスト・エディタでWSHスクリプトのコードを入力する

 次に、上で作成したスクリプトレット・コンポーネントを利用するためのWSHスクリプトを作成しておこう。あえて注意すべき点があるとしたら、<object>要素のprogid属性に指定するプログラムIDは、スクリプトレット・コンポーネントの<registration>要素で指定したそれに対応していなければならない、という点だ。スクリプトレットだからといって、何ら特別なことはなく、通常のコンポーネントを利用するのとまったく同じ要領で利用できることが分かるはずだ。

※ファイルmail.wsf

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job id="MailTrans">
<?job error="True" debug="True" ?>
<object id="objMail" progid="Wings.Sendmail" />
<script language="VBScript">
<![CDATA[
  objMail.Transform "mail.dat","mail.mdb"
  WScript.Echo("送信が完了しました!")
]]>
</script>
</job>
</package>

 以上で準備は完了だ。後は、先のWindows TIPS「テンプレートを元に複数のメールを一括配信する」の「手順5―WSHのコードを実行する」と同様の手順でWSHスクリプトを実行し、指定された配信先にメールが送信されることが確認できれば成功だ。End of Article
「Windows TIPS」


Windows Server Insider フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Windows Server Insider 記事ランキング

本日 月間