新城@筑波大学情報です。こんにちは。

Outlook が作る winmail.dat に含まれている添付ファイルを取出
す Ruby スクリプトを書いてみました。次のようにして使います。

(1) 添付ファイルの一覧の表示
    % winmail.rb winmail.data ls

(2) 添付ファイルの取出し
    % winmail.rb winmail.data extract

実行するには、Ruby 本体の他に次のライブラリが必要です。

    Ruby TNEF library
    http://raa.ruby-lang.org/project/tnef/

このファイルを取ってきて、適当な場所に置いて、require でかか
るようにします。

このスクリプトはファイル名に漢字が含まれていても、大丈夫です。
MacOSX で作ったので、 UTF-8 で試しましたが、他のシステムでた
とえば EUC になっていても動くでしょう。頭にある漢字コードの
設定を適当に修正します。Shift-JIS なら、Kconv::SJIS です。

端末の文字コードとファイル名の文字コードは別に設定できます。

\\ 新城 靖 (しんじょう やすし) \\
\\ 筑波大学 電子・情報       \\

----------------------------------------------------------------------
#!/usr/bin/env ruby
#
# Yasushi Shinjo <yas@is.tsukuba.ac.jp>
# Created on 2008/06/06

require "kconv.rb"
require "~/lib/ruby/tnef.rb" # fix the path of tnef.rb

# To get "tnef.rb", visit the following web sites:
# http://raa.ruby-lang.org/project/tnef/
# http://www.zweknu.org/technical/index.rhtml?s=p%7c15

WINMAIL_FILENAME_CODE = Kconv::UTF8
#WINMAIL_TERMINAL_CODE = Kconv::EUC
WINMAIL_TERMINAL_CODE = Kconv::JIS

def usage()
        comname = File.basename($0)
        $stderr.printf("Usage: %% %s filename subcommand [options]\n",comname)
        $stderr.printf("subcommands:\n")
        $stderr.printf("    ls\n")
        $stderr.printf("    extract\n")
        exit( 1 )
end

def main(argv)
        if( argv.length < 2 )
            usage()
        end
        filename = argv.shift()
        file = File.open( filename )
        tnef = TNEF.new( file )
        cmd = argv.shift()
        case cmd
        when "ls"
            cmd_ls( tnef, argv )
        when "extract"
            cmd_extract( tnef, argv )
        else
            usage()
        end
end

def cmd_ls( tnef, argv )
        attachments = tnef.attachments
        attachments.each { |a|
            filename = Kconv.kconv( a.long_filename, WINMAIL_TERMINAL_CODE )
            printf("%s\n",filename)
        }
end

def cmd_extract( tnef, argv )
        attachments = tnef.attachments
        attachments.each { |a|
            filename = Kconv.kconv( a.long_filename, WINMAIL_FILENAME_CODE )
            file = File.open( filename,"w" )
            file.write( a.data )
            file.close()
        }
end

main(ARGV)