Felicaリーダ及びメール送信トリガーの作成(トリガー編)



GitHub

【概要】:
Felica Lite-Sのユーザ定義情報を読み取り、メール送信のトリガーを引くURLを吐き出して、Webサービスにアクセスするクライアントです。 C#のWPFで実装します。

GUI:MainWindow.xaml

<Window x:Class="FelicaLiteSAspNet.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FelicaLiteSAspNet"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button x:Name="Write" Content="書出" HorizontalAlignment="Left" Margin="411,289,0,0" VerticalAlignment="Top" Width="75" Click="Write_Click"/>
        <Button x:Name="Read" Content="読込" HorizontalAlignment="Left" Margin="321,214,0,0" VerticalAlignment="Top" Width="75" Click="Read_Click"/>
        <Button x:Name="MailSend" Content="メール送信" HorizontalAlignment="Left" Margin="411,214,0,0" VerticalAlignment="Top" Width="75" Click="MailSend_Click"/>
        <TextBox x:Name="Userid" HorizontalAlignment="Left" Height="23" Margin="109,60,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
        <TextBox x:Name="Password" HorizontalAlignment="Left" Height="23" Margin="109,107,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
        <TextBox x:Name="Account" HorizontalAlignment="Left" Height="23" Margin="109,153,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
        <TextBox x:Name="Domain" HorizontalAlignment="Left" Height="23" Margin="262,153,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
        <Label x:Name="LAt" Content="@" HorizontalAlignment="Left" Margin="234,153,0,0" VerticalAlignment="Top" Width="23" Height="23" RenderTransformOrigin="0.121,0.58"/>
        <Label x:Name="LUserid" Content="ユーザID" HorizontalAlignment="Left" Margin="31,60,0,0" VerticalAlignment="Top" Width="64"/>
        <Label x:Name="LPassword" Content="パスワード" HorizontalAlignment="Left" Margin="31,107,0,0" VerticalAlignment="Top" Width="64"/>
        <Label x:Name="LMailaddress" Content="メールアドレス" HorizontalAlignment="Left" Margin="31,153,0,0" VerticalAlignment="Top" Width="73"/>
        <TextBox x:Name="Line" HorizontalAlignment="Left" Height="23" Margin="39,253,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="258"/>
        <ComboBox x:Name="Bank" HorizontalAlignment="Left" Margin="329,253,0,0" VerticalAlignment="Top" Width="53"/>
        <Label x:Name="LName" HorizontalAlignment="Left" Margin="39,19,0,0" VerticalAlignment="Top" RenderTransformOrigin="1.152,0.675" Width="190"/>
    </Grid>
</Window>


コードMainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FelicaLiteSAspNet
{
    /// 
    /// MainWindow.xaml の相互作用ロジック
    /// 
    public partial class MainWindow : Window
    {
        [DllImport("MyFelicaLiteS.dll")]
        public extern static IntPtr FelicaRW_main(int block, Byte[] wData, bool read);
        [DllImport("MyFelicaLiteS.dll")]
        public extern static IntPtr GetName();
        [DllImport("MyFelicaLiteS.dll")]
        public extern static IntPtr GetData();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int MultiByteToWideChar(int codepage, int flags, IntPtr utf8, int utf8len, StringBuilder buffer, int buflen);

        int bankNum = 0;

        public MainWindow()
        {
            InitializeComponent();

            for(int i=0;i<16;i++)
                Bank.Items.Add(i);

            Bank.SelectedIndex = 0;
        }

        unsafe private void Write_Click(object sender, RoutedEventArgs e)
        {
            bankNum = Bank.SelectedIndex;

            Byte[] wData = Encoding.ASCII.GetBytes(Line.Text);

            FelicaRW_main(bankNum, wData, false);

            MessageBox.Show("書き込みが完了しました");
        }

        unsafe private void Read_Click(object sender, RoutedEventArgs e)
        {
            FelicaRW_main(0, null, true);

            IntPtr po = GetData();
            String str = Marshal.PtrToStringAnsi(po);

            String[] args = str.Split(',');

            po = GetName();

            int len = MultiByteToWideChar(65001, 0, po, -1, null, 0);

            if (len == 0)
                throw new System.ComponentModel.Win32Exception();

            var buf = new StringBuilder(len);

            len = MultiByteToWideChar(65001, 0, po, -1, buf, len);

            String name = buf.ToString();

            LName.Content = name;
            Userid.Text = args[2];
            Password.Text = args[3];
            Account.Text = args[0];
            Domain.Text = args[1];

        }

        private void MailSend_Click(object sender, RoutedEventArgs e)
        {
            String url = @"http://konekophoto.azurewebsites.net/FelicaMail?user_id=" + Userid.Text + "&password=" + Password.Text + "&mail_address=" + Account.Text + "@" + Domain.Text;

            var client = new WebClient();
            client.OpenRead(url);

        }
    }
}


【手順】:
Visual Studioで、C#のWPFアプリケーションのプロジェクトを作ります。





【詳細】:

1.コーディング解説


今回作成するアプリケーションの実行には、前回作成したライブラリが必須です。
実行ファイルと同じフォルダに入れて、参照可能な状態にしておいてください。
ライブラリがないとエラーになりますのでご注意ください。


実装に移る前に、プロジェクトのプロパティを開いてアンセーフコードの実行を許可します。






実装FelicaMail.aspx.cs

        [DllImport("MyFelicaLiteS.dll")]
        public extern static IntPtr FelicaRW_main(int block, Byte[] wData, bool read);
        [DllImport("MyFelicaLiteS.dll")]
        public extern static IntPtr GetName();
        [DllImport("MyFelicaLiteS.dll")]
        public extern static IntPtr GetData();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int MultiByteToWideChar(int codepage, int flags, IntPtr utf8, int utf8len, StringBuilder buffer, int buflen);

ライブラリで作ったクラス関数をインポートします。
記法は、下記の通りです。

[DllImport("ライブラリ名")]
public extern static <戻り値> メソッド名(引数1, 引数2, 引数3...);

メソッド名は、ライブラリのDEFファイルでEXPORTSに記載した関数名を書きます。

unsafe private void Read_Click(object sender, RoutedEventArgs e)
{
    FelicaRW_main(0, null, true);

    IntPtr po = GetData();
    String str = Marshal.PtrToStringAnsi(po);

    String[] args = str.Split(',');

    po = GetName();

    int len = MultiByteToWideChar(65001, 0, po, -1, null, 0);

    if (len == 0)
        throw new System.ComponentModel.Win32Exception();

    var buf = new StringBuilder(len);

    len = MultiByteToWideChar(65001, 0, po, -1, buf, len);

    String name = buf.ToString();

    LName.Content = name;
    Userid.Text = args[2];
    Password.Text = args[3];
    Account.Text = args[0];
    Domain.Text = args[1];

}



IntPtr po = GetData();
IntPtrは、汎用のポインタ型です。

String str = Marshal.PtrToStringAnsi(po);
ポインタ文字列をAnsiエンコードで受け取りString型に格納します。

String[] args = str.Split(',');
strの中身は、上図"GetDataメソッドの戻り値(IntPtr型)の文字列オーダー"に示すように、
カンマで区切ったパラメータが入っていますので、Split(',')で分割し配列に入れます。

po = GetName();
ポインタ文字列をUTF-8エンコードで受け取りString型に格納します。
その際、少しばかり細工をしています。

private void MailSend_Click(object sender, RoutedEventArgs e)
{
    String url = @"http://konekophoto.azurewebsites.net/FelicaMail?user_id=" + Userid.Text + "&password=" + Password.Text + "&mail_address=" + Account.Text + "@" + Domain.Text;

    var client = new WebClient();
    client.OpenRead(url);

}


ライブラリを使用して取得したパラメータを、上図リクエストパラメータに埋め込んでURL文字列を作ります。

var client = new WebClient();
client.OpenRead(url);
URL文字列を引数として、WebClientを発行します。


どうですか?メールは指定したメールアドレスの受信トレイに入っているでしょうか?

お疲れさまでした。
これにて、終了となります。