前回、Notes 10.x 以降、LotusScript の NotesHTTPRequest クラスを使用したファイルのダウンロード方法を紹介しました。ただ、このメソッドは、64 KB 以上のファイルがダウンロードできない問題がありました。今回はその回避策の一つを紹介します。
その方法は、Windows API の一つである、Windows インターネット(WinINet API)を使用する方法です。
Windows インターネット(WinINet API)とは?
Microsft Learn によると、Microsoft Windows インターネット (WinINet) アプリケーション プログラミング インターフェイス (API) を使用すると、アプリケーションは FTP や HTTP などの標準インターネット プロトコルにアクセスできるとのことです。
実行の要件としては、Windows NT 4.0 以降、または Windows Me/98/95 が必要となっています。いにしえの呪文である理由がわかりますね。
詳しくは以下のサイトを参照ください。
サンプルプログラム(スクリプトライブラリ)
まず、WinINet API をコールする部分をまとめたスクリプトライブラリ lsHttpDownload を作成します。
以下は、(Declarations) に記述する API 関数の定義です。使用している API 関数は4つです。
'WinINet API関数の定義 Declare Function InternetReadFile Lib "wininet.dll" ( Byval hFile As Long, lpBuffer As Any, Byval lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" ( Byval sAgent As String, Byval lAccessType As Long, Byval sProxyName As String, Byval sProxyBypass As String, Byval lFlags As Long) As Long Declare Function InternetOpenUrl Lib "wininet.dll" Alias "InternetOpenUrlA" ( Byval hInternetSession As Long, Byval sUrl As String, Byval sHeaders As String, Byval lHeadersLength As Long, Byval lFlags As Long, Byval lContext As Long) As Long Declare Function InternetCloseHandle Lib "wininet.dll" ( Byval hInet As Long) As Integer |
続いて、同じく (Declarations) に記述する定数の宣言です。
'User_agent Private Const WI_AGENT_NAME = "WinINetNotes" 'Proxy設定はデフォルトを使用 Private Const WI_PROXY = "" 'レジストリの設定を使う Private Const WI_ACCESSTYPE = 0 'INTERNET_FLAG_RELOAD( 0x80000000 ) Private Const WI_FLAGS = &H80000000 'InternetReadFile で一度に読み込むサイズ Private Const WI_READ_BUFFSIZE = 1024 |
そして、ダウンロードする関数の本体は次の通りです。
Public Function HttpDownload(Byval vsUrl As String, Byval vsFileName As String) As Long Dim abyRecvData() As Byte Dim lInetHandle As Long 'インターネットハンドル Dim lUrlHandle As Long 'URLハンドル Dim iReturn As Integer 'InternetReadFile の戻り値 Dim lReadSum As Long '受信したデータの総サイズ 兼 バッファへのポインタ Dim lReadSize As Long '受信したデータのサイズ(1回分) Dim iFP As Integer Dim i As Integer On Error Goto ErrProc '入力チェック If vsUrl = "" Then Exit Function If vsFileName = "" Then Exit Function 'インターネットハンドルを作成 lInetHandle = InternetOpen(WI_AGENT_NAME, WI_ACCESSTYPE, WI_PROXY, "", 0) If lInetHandle = 0 Then Exit Function 'URLハンドルを作成 lUrlHandle = InternetOpenUrl(lInetHandle, vsUrl, "", 0, WI_FLAGS, 0) If lUrlHandle = 0 Then Error 9000, "INetハンドルが取得できませんでした。" '書き込むファイルの準備 iFP = Freefile() Open vsFileName For Binary Access Write As iFP 'ファイルのダウンロード Do 'バッファエリア確保 & 初期化 Redim abyRecvData(WI_READ_BUFFSIZE-1) iReturn = InternetReadFile(lUrlHandle, abyRecvData(0), WI_READ_BUFFSIZE, lReadSize) lReadSum = lReadSum + lReadSize '終了判断 If (lReadSize = 0) Or (iReturn = 0) Then Exit Do 'サイズ調整 If lReadSize < WI_READ_BUFFSIZE Then ReDim Preserve abyRecvData(lReadSize - 1) End If 'ファイルに書き込み For i = Lbound(abyRecvData) To Ubound(abyRecvData) Put #iFP, ,abyRecvData(i) Next Loop Close #iFP ExitProc: If lUrlHandle <> 0 Then InternetCloseHandle(lUrlHandle) If lInetHandle <> 0 Then InternetCloseHandle(lInetHandle) HttpDownload = lReadSum Exit Function ErrProc: Print Err & ":" & Error$ & " (line:" & Erl & ")" Resume ExitProc End Function |
郵便番号データのダウンロード
それでは、このライブラリを使用したメインルーチンです。前回ダウンロードでエラーが出た全国版のデータでテストします。
Option Declare Use "lsHttpDownload" Sub Initialize Dim sFileName As String Dim sURL As String 'パラメータの設定 sFileName = "ken_all.zip" sURL = "https://www.post.japanpost.jp/zipcode/dl/oogaki/zip/" & sFileName 'ダウンロードの実行 Call HttpDownload(sURL, "c:\lotus\" & sFileName) End Sub |
実行すると、次のようにファイルが作成されます。64 KB を越えるファイルですが、正常にダウンロードできており、zip 圧縮の回答できました。
まとめ
Windows インターネット(WinINet API)を使用する方法は、64 KB 以上のファイルがダウンロードできない問題の暫定的な解決策として紹介しました。
今回の方法では、LotusScript から直接 API をコールしました。よって、ロケーションで行うプロキシ設定など、ノーツクライアントのインターネットの接続設定をすっ飛ばして接続します。ブラウザからは接続できるけど、Notes 経由では接続できない場合でも利用できます。
そもそも、このような状況に陥ることが問題ではあるのですが...
0 件のコメント:
コメントを投稿