【Perl】PARでexe化するときにファイルを追加する


【Perl】Win32::GUI::LoftでGUIプログラミング」」ではThe GUI Loftを使ってGUIアプリケーションを書いた。

作成したアプリケーションを配布するときにはPAR::Packerでexe化すると便利なのだが、スクリプトファイル(拡張子.pl)の他にGUI定義ファイル(拡張子.gld)もパッケージしないといけない。まずはパッケージ内部のgldファイルを読み込めるようにスクリプトを訂正しよう。

#!/usr/bin/perl
use strict;
use warnings;
use FindBin;
use Path::Class;
use Win32::GUI::Loft;

my $gld = "testGUI.gld";
my $scalar = $INC{ "PAR.pm" }
    ? PAR::read_file( $gld )
    : file( $FindBin::Bin, $gld )->slurp;
my $design = Win32::GUI::Loft::Design->newScalar(
    $scalar, $gld );
my $win = $design->buildWindow;
$win->btnButton1->Change( -onClick => sub { -1 } );
$win->Show;
Win32::GUI::Dialog;

ハイライトした部分が変更点だ。Perlの小ネタ集に書いたが、%INCハッシュの要素を調べることでPARモジュールを読み込んでいるかどうかがわかる。

これによってexe化したファイルから起動しているのかどうか判定しているわけだ。その上で、PAR::read_file関数1を使ってファイルを読み込んでいる。

 

スクリプトを変更した上で、exe化を実行する。

C:\> pp -a testGUI.gld -o testGUI.exe testGUI.pl

-aオプションによってパッケージにファイルを追加している。後は作成したtestGUI.exeを配布するだけだ。

応用

YAMLで書いた設定ファイルをパッケージに追加する場合を考える。

開発中は同じディレクトリにある設定ファイル(config.yml)を読み込み、配布するときにはパッケージに組み込んでしまう。このとき、設定ファイルを読み込んでハッシュリファレンスとして参照するコード例は次のようになる。

testYAML.pl

#!/usr/bin/perl
use utf8;
use strict;
use warnings;
use errors -with_using;
use FindBin;
use Path::Class;
use Term::Getch;
use YAML::Syck;

binmode STDOUT => ":raw :encoding(cp932)";
binmode STDERR => ":raw :encoding(cp932)";

# ファイルのエンコードはCP932
# 改行コードは\x0D\x0Aとする
my $config_file = "config.yml";

# try〜catch構文についてはこちら
# https://blog.delphinus.dev/2010/01/use-errors.html
my $option = try {
    # Unicodeを含んだファイルを読むときのおまじない
    local $YAML::Syck::ImplicitUnicode = 1;

    # 同じディレクトリにファイルがあった場合
    my $file = file( $FindBin::Bin, $config_file );
    if ( -f $file ) {
        my $fh = $file->openr;
        $fh->binmode( ":crlf :encoding(cp932)" );
        LoadFile $fh;

    # exe化したパッケージ内にファイルがあった場合
    } elsif ( $INC{ "PAR.pm" } ) {
        my $yaml = PAR::read_file( $config_file );
        Load decode( cp932 => $yaml );

    # それ以外はエラー
    } else {
        throw Error $config_file . "が見つかりません";
    }

} catch Error using {
    # $_には何らかのエラーメッセージが含まれている
    print <<EOM;
設定ファイルが読み込めません : $_
何かキーを押してください
EOM

    # 何かキーを押したら終了する
    # Term::Getchの使い方はこちら
    # https://blog.delphinus.dev/2010/03/perl-input-from-prompt.html
    my $char;
    1 while ! ( $char = getch );
    exit;
};

# メインルーチン実行
&main( $option );

sub main {
    my $option = shift;
    print $option->{test} . "\n";
    print $option->{test_ja} . "\n";
}

config.yml

---
test: Hello, World!
test_ja: こんにちは、世界!

PAR::Packerでexe化

C:\> pp -a config.yml -o testYAML.exe testYAML.pl

実行例

C:\> testYAML
Hello, World!
こんにちは、世界!

  1. これはArchive::Zip::Member::contents関数のラッパーである。 

コメントを残す