[Perl] Win32GuiTest

2009/07/08Perl::MODimport

[Perl] Win32GuiTest

Windows操作を自動化してナニするためのmoduleです。

source codeからのbuildとinstall

まずはソースコードを拾ってきます。本家CPANのWin32::guitestからが良いでしょう。Ver.1.56が取得できます@2009年7月8日現在

サイトからもわかるように、VC++のコマンドラインバッチを走らせた後、下記のscriptを実行して、Makefileを生成させます。

perl makefile.pl

ここで、デフォルトのままですと、VC++のランタイムライブラリ(MSVCRT90.dll(VS2008ExpEdition))が必要になります。Active Perlのversionを合わせておくだけで、ほかのマシンにもmoduleを配るのであれば、ここでstatic linkを選択すべきです。

で、Makefile.PLを編集するのが妥当な気がするのですが、いまいちどうやってコンパイルオプションを引き出してきているのかがわかりませんでした。直接Makefileを編集することにします。

・変更前

CCFLAGS = -nologo -GF -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX
OPTIMIZE = -MD -Zi -DNDEBUG -O1

LDLOADLIBS =   oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp32.lib msvcrt.lib

・変更後

CCFLAGS = -nologo -GF -W3 -MT -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX
OPTIMIZE =  -Zi -DNDEBUG -O1

LDLOADLIBS =   oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp32.lib libcmt.lib

それぞれ位置はバラバラですが、シンボル名で検索すれば確実でしょう。編集が終わったら、makeします。

nmake

ちんたら文句言われますが、関数宣言してないとかそんなのですね。

実際にstatic linkされたか、dumpbinコマンドで確認しておきましょう。

>dumpbin /dependents blib\arch\auto\Win32\GuiTest\GuiTest.dll

Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file blib\arch\auto\Win32\GuiTest\GuiTest.dll

File Type: DLL

  Image has the following dependencies:

    perl510.dll
    KERNEL32.dll
    USER32.dll
    GDI32.dll

  Summary

        3000 .data
        5000 .rdata
        2000 .reloc
        1000 .rsrc
        1000 .shared
       1B000 .text

VCのdllは要求されていませんね。perlのdllを要求されていることから、少なくとも Perl 5.10以外では使えないことがわかります。Active Perlのversionを合わせておかないと、あとでppm installができません:)

次に、module testを行うわけですが、国際化対応していないのでNGになります。テストパターンは、Win32-GuiTest-1.56\tに入っています。関数電卓(calc)は、メニューやボタン名に漢字が使われるため、windowが見つからないといわれてしまいます。日本語仕様に合わせて修正しておきます。

・"02_calc.t"

#	MenuSelect("&View|&Scientific");
	MenuSelect("表示(&V)|関数電卓(&S)");

#	($hex) = FindWindowLike($calc, "Hex");
	($hex) = FindWindowLike($calc, "16 進");

#	($bin) = FindWindowLike($calc, "Bin");
	($bin) = FindWindowLike($calc, "2 進");

#	($oct) = FindWindowLike($calc, "Oct");
	($oct) = FindWindowLike($calc, "8 進");

#	($dec) = FindWindowLike($calc, "Dec");
	($dec) = FindWindowLike($calc, "10 進");

#	PushButton("Dec"); sleep 1;
	PushButton("10 進"); sleep 1;

#	PushButton("Hex"); sleep 1;
	PushButton("16 進"); sleep 1;

#	PushButton("Oct"); sleep 1;
	PushButton("8 進"); sleep 1;

#	PushButton("Bin"); sleep 1;
	PushButton("2 進"); sleep 1;

・"05_which.t"

# like(WhichExe("progman"),  qr/progman/i,  "progman");

Vista x64環境のせいか、これはスキップされます。

以上でテストはパスされるでしょう。それではインストールしてしまいましょう。

nmake install

配布用パッケージの作成

コマンドラインのzip/tarコマンドなどが必要になります。ない場合は、配布用ディレクトリの作成までで止めておき、windows標準の圧縮フォルダでzipファイルを作るという方法もあります。

nmake ppd
nmake distdir

Win32-GuiTest-1.56というディレクトリができているので、これをzipにします。

次に、Win32-GuiTestを開いて、下記のように修正します。

        <CODEBASE HREF="Win32-GuiTest-1.56.zip" />

ppdとzipとをセットで配布すればおkです。ただしActive perlのDocumentationでブラウズすることができません。htmlは入らない模様です。

使い方

build/install方法を書いてたら時間切れ…。目的を実現する前に力尽きるとは口惜しや・・・('A`


参考

[Perl] 基礎的な事項

2009/06/13Perl::基礎import

[Perl] 簡単な文法メモ

スカラー変数

汎用変数と思えばいいかな. 型定義は特に無い.(値/文字列/リファレンス(ポインタ))

my $hogehoge

初期化しない状態は未定義(undef)となります。値ならゼロ、文字列ならNULL扱いになります。演算時に評価されますが、use warningすると未初期化変数の演算といわれます。undefかどうかの判定は、下記の関数を利用することになります。

defined($hogehoge)

下記の比較演算子は使えません。

$hogehoge == undef $hogehoge eq undef

scope hogehoge;

スコープ'hogehoge'を定義する。

require Exporter;

@ISA, @classname::ISA = @qw(the_class):

SuperClassを定義します. this class IS-A the_class.もしくは、下記のように記述できます。

use the_class;
@thisclass::ISA = qw(the_class);
||>
↓
>||
use base qw(the_class);

配列操作

初期化
@hoge = ('hoge','hogehoge',...);
@hoge = ("hoge","hogehoge",...); ← 展開される
@hoge = qw ( hoge hogehoge ...); ← 展開される. 空白で区切られる.
参照
$hoge[0] # zero-origin
$#hoge   # indexの末尾が得られる
$hoge[-1] <=> $hoge[$#hoge]

ハッシュ操作

宣言

my %hash_name;
初期化
%hash = ( "key1" => value, "key2" => value);
または、一次元配列でkey,valueの順列。
%hash = (key1, value1, key2, value2)
%hash = (); # 空っぽになる. |ハッシュアクセス:
keys %hash # hashの持つキーを配列で取得する.
values %hash # 同, 値を配列で取得する.
exists $hash{'key'}; # そのキーが存在するか. 真/偽を返す. 未初期化と定義済みと判断可能.
delete $hash{key} # 指定したキー/値を削除する.

pack/unpack

syntax:

pack TEMPLATE, LIST
unpack TEMPLATE, LIST

templateの書式を以下に示します。

フォーマット 意味 フォーマット 意味
aASCII 文字列AASCII 文字列、足りない領域はスペース文字で埋める
bビット列 (昇ビット順)Bビット列 (降ビット順)
c符号付き char 値C符号なし char 値
d機種依存の倍精度浮動小数点数f機種依存の単精度浮動小数点数
h16進数文字列 (下位ビットが先)H16進数文字列 (上位ビットが先)
i符号付き int 値I符号なし int 値
l符号付き long 値L符号なし long 値
nネットワークバイト順序 (ビッグエンディアン) の short 値Nネットワークバイト順序 (ビッグエンディアン) の long 値
p文字列へのポインタP構造体 (固定長文字列) へのポインタ
s符号付き short 値S符号なし short 値
vVAXバイト 順序 (リトルエンディアン) の short 値VVAXバイト 順序 (リトルエンディアン) の long 値
uuuencode した文字列xヌル文字
X1バイト後退@絶対位置までヌル文字で埋める
  • フォーマット文字の後ろには、それを何回繰り返すかを示す数字COUNTを付けることができます。\COUNTに * を指定すると、残っているすべての要素を使います。
  • フォーマット文字(COUNTも含める)同士の間にはスペースを挟むことができます。
  • a、A、b、B、h、H以外のフォーマットは、第2引数LISTからCOUNTで指定された分の値を使います。
  • aやAというフォーマットに対してCOUNTを使うと、繰り返し数で示す長さの文字列となるように、\必要に応じてヌル文字かスペース文字を付け足します。
  • unpackするとき、Aは後続のスペース文字やヌル文字を取り除きますが、aはそのままにします。\同様に、bやBは、繰り返し数で示すビット長のビット列にパックします。
  • hやHは、そのニブル長のニブル列にパックします。
  • Pは、指定した長さの構造体へのポインタをパックします。
  • 実数 (floatとdouble) は、機種依存のフォーマットしかありません。\あるマシンで パックした浮動小数点数は、別のマシンでは読めない可能性があります。

split

区切り文字を指定して、stringを分割します。

@list = split(/\t/ , $var); // 区切りはTAB文字となっていることを見る.
@list = split(/[\t]/ , $var); // 区切りはTAB文字となっていることを見る.
 // 複数指定もできるが,区切り文字もリストに放り込まれる.

FileI/O

個人メモだから説明を端折ってもいいかな...\Cの標準関数 fopen/fclose みたいな感じで。出力は">"をつけて表す。

my @binhex;

 if ( ! open(fp, "<".$fname ) ) {
   printf("cannot open \"$fname\" \n");
   die ;
 }
 binmode( fp );
 while( read(fp, $buffer, $size_of_bytes) ){
   @binhex = unpack( "v32", $buffer ) ;        # divide little endian(short) x 32
 }


参考サイト

  • Smart Smartさん\非常にまとまっているサイト。Perl講座、HTML講座、JavaScript講座、SQL講座、注目技術・アクセス講座と幅広く展開されています。困った時は訪れるとよいかと思います。

Perl

2009/06/13Perlimport

[Perl] もくじ

便利なscript言語として、数年ほど前から、開発の補助ツールとしてPerlをかじっているけれども、備忘録を兼ねてメモを置いていくことにしました。

今までお世話になったWEBサイト様も多数ありましたが、自分のほしいものは自分でまとめておくに限りますしね。


環境としては、Windows x86またはx64 / Active Perl 5.10.0あたりを想定します。