TKMP.DLLを利用してメールのチェックをしたい。

タグの編集
投稿者 hiroyuki  (社会人) 投稿日時 2016/11/26 10:16:38
hiroyukiと申します。

TKMP.DLLを利用してメールのチェックをしたいのですがどのようにコードを書けばいいのかさっぱりわかりません。大変恐縮ですがサンプルのコードを教えていただけないでしょうか。


他の掲示板でも同じ質問をしましたが、「自分で調べるように」と全て断られました。
そこでたどり着いたのがココの掲示板です。
何卒よろしくお願いします。


http://uwa.potetihouse.com/samplecode/tkmp/uidcheck.html
ココのサイトを参考にしました。


Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        '接続情報 
        Dim server As String = "pop.ae.auone-net.jp"
        Dim port As Integer = 110
        Dim userid As String = "a789133385"
        Dim pass As String = "v2wr2ipe"

        'サーバへの接続用クラスを作成する 
        Dim address As System.Net.IPAddress = System.Net.Dns.GetHostByName(server).AddressList(0)
        Dim logon As New TKMP.Net.BasicPopLogon(userid, pass)
        Dim pop As New TKMP.Net.PopClient(logon, address, port)

        '接続開始 
        If Not pop.Connect() Then
            System.Windows.Forms.MessageBox.Show("接続失敗")
            Return
        End If

        'このあたりからわかりません 
        Dim ui As New UID
        'ファイルからUIDを読み込む 
        Dim itm() As String = ReadUID()
        ' 未読メールの取得 
        Dim mails As ArrayList = ui.NoReadMails(pop, itm)
        '未読メールの表示 
        MsgBox(mails.ToString())

        '取得したUIDの保存 
        SaveUID(mails)

        '切断 
        pop.Close()
    End Sub

End Class

Class UID
    '接続済みのクライアントクラスと、読み出し済みUIDリストを引数に渡すと、 
    '未読メールのクラス一覧を返します 
    Public Function NoReadMails(ByVal PopClient As TKMP.Net.PopClient,
                                ByVal ReadUIDList() As StringAs TKMP.Net.MailData()
        '一時格納用のコレクション 
        Dim mails As New System.Collections.ArrayList
        'メールボックスの全てのメールを検査する 
        Dim mail As TKMP.Net.MailData
        For Each mail In PopClient.MailDatas
            Dim read As Boolean = False
            '読み出し済みUIDと一致するものを確認する 
            Dim UID As String
            For Each UID In ReadUIDList
                If mail.UID.Equals(UID) Then
                    read = True
                    Exit For
                End If
            Next UID
            If Not read Then
                '未読をコレクションに追加する 
                mails.Add(mail)
            End If
        Next mail

        'コレクションから配列へ変換 
        Dim mailarray As TKMP.Net.MailData() =
                           CType(mails.ToArray(GetType(TKMP.Net.MailData)), TKMP.Net.MailData())

        Return mailarray
    End Function
End Class



環境はVS 2015 Community
win7
です。


投稿者 PS/55  (社会人) 投稿日時 2016/11/26 12:06:54
そもそもうーわーさんとこにサンプルあるのに何を聞くというの?
投稿者 hiroyuki  (社会人) 投稿日時 2016/11/26 14:20:58
お返事有難う御座います。


そのサンプルのサイトを教えてください。
あと当方メールの仕組みは全くの無知です。
よろしくお願いします。
投稿者 YuO  (社会人) 投稿日時 2016/11/26 16:14:18
コード中のパスワードが本物であるのであれば,すぐさまパスワードを変更する事をお勧めします。


で,「メールのチェック」というのは何を意味していますか。
この言葉だけけではやりたいことがわかりません。
他のサイトで「自分で調べるように」と書かれた,というのは,単純に質問の意味が多義にとれるので,そこからまず一意に絞ることが面倒に思われたのかもしれません。


もし,前回チェックした時から現在までに新しく来たメールが存在するかを知りたいのであれば,NoReadMailsメソッドがそれをそのままやっています。
これは「新しく来たメール」の一覧を取得するものなので,戻り値のLengthが0でなければ新しく来たメールが存在する事になります。


UIDが何か,といった話であれば,POP3というプロトコルについての知識が必要になります。
例えば,@ITの以下のページ
http://www.atmarkit.co.jp/ait/articles/0106/05/news001.html
などが参考になるかと思います。
というか,hiroyukiさんが参考にしたとされる,Tokiさんのページの冒頭にもUIDについて書いてありますね。

> あと当方メールの仕組みは全くの無知です。

せめてPOP3プロトコルを勉強してください。
自分の管轄にないサーバーとやりとりをする以上,ある程度の知識は必須になります。
今回の場合だと,UIDの話を知らないと毎回全てのメール情報を引き出すような,サーバーに無用な負担をかけるプログラムを作りかねません。
投稿者 hiroyuki  (社会人) 投稿日時 2016/11/26 19:02:34
お返事有難う御座います。

コードのメールアドレスは消し忘れましたので、パスワードを変更します。


「メールチェック」はYuOさんの言われる通り「前回チェックした時から現在までに新しく来たメールが存在するかを知りたい」の事です。


UIDについて少し勉強させていただきましたが「読み出し済みのUIDリスト」の作成方法がわかりません。


>せめてPOP3プロトコルを勉強してください。
頂いたURLを元に学習してみたいと思います。
投稿者 YuO  (社会人) 投稿日時 2016/11/26 20:37:10
> UIDについて少し勉強させていただきましたが「読み出し済みのUIDリスト」の作成方法がわかりません。

単純に,データを何らかの方法で保存しておいて,以前のデータを取得すればよいです。

終了までの間だけであれば,メモリにList(Of String)のオブジェクトでも用意しておけばよいでしょう。

終了後,再度起動時に以前のデータを読み出す必要があるのであれば,
File.WriteAllLinesとFile.ReadAllLinesあたりが楽に処理できるかと思います。
メールの数が多いのであれば,ファイルではなくデータベースの方がよいかもしれません。
そのあたりは,自由にUIDを保存して読み込めばよいです。
投稿者 hiroyuki  (社会人) 投稿日時 2016/11/26 21:57:37
たびたびのお返事ありがとうございます。



「読み出し済みのUIDリスト」の作成方法について、メモリにList(Of String)の入れ物を用意したりFile.WriteAllLinesとFile.ReadAllLinesを利用したりすることは想像できますが、これをどのように実装するとなると皆目見当がつきません。
この部分だけわかればかなりの進歩だと思います。
また、ヒントだけでもいいですのでご教示頂ければ幸いです。
投稿者 YuO  (社会人) 投稿日時 2016/11/27 03:13:35
普通に使うだけなんですけどね……。

例えば,Console Applicationとして次のようなコードを書けば,データの読み込み・保存が確認できます。
Option Explicit On
Option Strict On
Option Infer On

Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq

Module Module1

    Sub Main()
        Dim uidList = ReadUids().ToList()

        Console.WriteLine("[Read UIDs]")
        For Each uid In uidList
            Console.WriteLine($"    <{uid}>")
        Next
        Console.WriteLine()
        Console.WriteLine("[Input UIDs]")
        While True
            Dim uid = Console.ReadLine()
            If uid Is Nothing Then Exit While
            uidList.Add(uid)
        End While
        Console.WriteLine()
        Console.WriteLine("[Write UIDs]")
        For Each uid In uidList
            Console.WriteLine($"    <{uid}>")
        Next

        WriteUids(uidList.Distinct().ToArray()) ' 一応,Distinctかけて一意にしておく。 
    End Sub

    Function ReadUids() As String()
        If Not File.Exists("uid.dat"Then
            Return Array.Empty(Of String)
        End If
        Return File.ReadAllLines("uid.dat")
    End Function

    Sub WriteUids(uids As String())
        File.WriteAllLines("uid.dat", uids)
    End Sub
End Module
で,実際のMailDataクラスではどうすればよいかを考えて修正して,実際のコードに追加すればよいです。
# なお,上記のコードではImports文やOption文に関して,冗長に記述しています。

いきなり全てをやろうとせず,わからない部分だけについてこのように切り出して作成してみるとよいかと思います。
投稿者 hiroyuki  (社会人) 投稿日時 2016/11/27 17:42:23
ご親切有難う御座いました。

無事サーバーのすべてのUIDリストを取得できました。
後は、前回書き込んだファイルと照合して違う部分のみをNoReadMailsに渡せば完了です。

本文はC#で書いてありますので残りの部分はC#で完成させます。

本当に有難う御座いました。