はじめまして、いつも参考にさせていただいています。
現在、wininetのFtpGetFileを使用してサーバよりファイルをダウンロードしようとしているのですが、
FtpPutFileはうまくいくのですが、FtpGetFileの方はうまくいきません。
Putはできているので、原因はFtpGetFileにあるのでしょうが、
問題点がよくわかりません。
どこを直せばいいのか、ご教授願います。
環境はWinXPのVB.NETです。
よろしくお願いします。
***** 以下コード *****
Public Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" ( _
ByVal hFtpSession As Integer, _
ByVal lpszRemoteFile As String, _
ByRef lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal dwFlags As Integer, _
ByVal dwContext As Integer) As Boolean
======= 以下メイン処理 ===========
Dim hOpen As Integer
Dim hFtpSession As Integer
Const INTERNET_FLAG_RELOAD As Integer = &H80000000
Const INTERNET_FLAG_TRANSFER_BINARY As Short = &H2S
Const INTERNET_NO_CALLBACK As Short = 0
hOpen = InternetOpen("vb wininet", INTERNET_OPEN_TYPE_DIRECT, vbNullString, vbNullString, 0)
hFtpSession = InternetConnect(hOpen, "FtpServer", INTERNET_INVALID_PORT_NUMBER, _
"FtpUser", "FtpPass", INTERNET_SERVICE_FTP, nFlag, 0)
FtpGetFile(hFtpSession, "/xxx/xxxx/yyyy.ini", "c:\yyyy.ini", True, 0, _
INTERNET_FLAG_TRANSFER_BINARY Or INTERNET_FLAG_RELOAD, INTERNET_NO_CALLBACK)
取りあえず err.LastDllErrorとInternetGetLastResponseInfoで
エラーの原因を分析することが先決です。
ねろ様、ご回答ありがとうございます。
InternetGetLastResponseInfoなのですが、使い方が悪いのか情報取得できませんでした。
下記のような感じで使用しているのですが、何処に問題があるのでしょうか?
Dim strBuffer As String
Dim intLength As Integer
InternetGetLastResponseInfo(Err.LastDllError, vbNullString, intLength)
strBuffer = New String(Chr(0), intLength + 1)
InternetGetLastResponseInfo(Err.LastDllEroor, strBuffer, intLength)
MsgBox(strBuffer)
InternetGetLastResponseInfoを使用する前のErr.LastDllErrorは"123"で、
strBufferの値は""でした。
先ず
>Err.LastDllErrorは"123"
エラーの番号だけでは何のエラーが発生したかわかりませんよね。
FormatMessageでエラーメッセージを取得します。
ちなみにFormatMessage取得した結果123は
「ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。」
です。
心当たりは?
>InternetGetLastResponseInfoなのですが、使い方が悪いのか情報取得できませんでした。
WinInetのエラーは 12000以上です、すなわちWinInetのエラーでは無いからでは。
InternetGetLastResponseInfoは、そういうことだったのですね。
FormatMessage、こちらでも確認致しました。
ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っているということは、
プログラム上の問題ではなく、
FtpGetFileに渡している第2,第3引数の値が間違っているって事ですかね?
これは何度も確認して間違ってはいないようなのですが・・・
(元々はVB6で作成されたものをVB.NETにアップグレードしたものなので、
引数の値に問題は無いと思います)
FtpFindFirstFileで「"/xxx/xxxx/yyyy.ini"」が見つかるかどうか調べてみたらいかがですか?
>FtpGetFile(hFtpSession, "/xxx/xxxx/yyyy.ini", "c:\yyyy.ini",False, 0, _
INTERNET_FLAG_TRANSFER_BINARY Or INTERNET_FLAG_RELOAD, INTERNET_NO_CALLBACK)
iniファイルってbinaryだっけ、それと「INTERNET_FLAG_RELOAD」FTPでキャッシュから読み込まれる
ことはあったっけ。
5番目の引数の ByVal dwFlagsAndAttributes As Integer の0って何だっけ。
良くわからないけど、取りあえず一回これでやってみよう。
FtpGetFile(hFtpSession, "/xxx/xxxx/yyyy.ini", "c:\yyyy.ini",False, 32, 1, 0)
FtpFindFirstFileで確認して、こちらの方は大丈夫でした。
iniファイルはASCIIですね。というよりも間違いだらけ?(汗
VB6のソースも見直したほうが良さそうですね・・・
FtpGetFile(hFtpSession, "/xxx/xxxx/yyyy.ini", "c:\yyyy.ini",False, 32, 1, 0)
でやってみても、やはり駄目でした。
同じエラーメッセージが出ます。
FtpSetCurrentDirectoryでGetするパスに移動して、ファイル指定だけで
Getしてみて下さい。
クライアントの方もフォルダーに移動して、ファイル名だけ指定で。
サーバがLinax日本語版だとwininet.dllの関数達は
誤動作してました。
英語版だと平気なんですけど。
回避策はftpコマンドをプログラムで組み立てて
バッチファイルに書込んで起動すれば・・・・
かなり原始的ですが・・・
余計な情報だったらすいません。
>ねろ様
やはり駄目でした。
とりあえず、わからないAPIよりもjavaでFTP通信するプログラムを
以前作った物があるので、それを流用するか、
Socketを使った方法で作成したらうまくいったので、どちらかでやろうかと思います。
>でヴぃけい様
回答ありがとうございます。
サーバはAIXで、今までVB6で作成したwininet.dllの関数が動いてますので、
それに関しては問題ないと思います。
答えてくださった方々、ありがとうございました。
引数の宣言が間違っています。
Public Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" ( _
ByVal hFtpSession As Integer, _
ByVal lpszRemoteFile As String, _
ByVal ⇒ ByRef lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal dwFlags As Integer, _
ByVal dwContext As Integer) As Boolean
ってか、もう遅いかな〜
おお! 違ってる、しかもエラーコードどうり。
宣言はチェックしなかったような気がする。(^^;
> おなまえさん
その宣言も間違っているような。 As Boolean → As Long ですね。
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200410/04100037.txt
VB.NETですから
>As Boolean → As Long
では無く、
As Boolean → As Integer
又は
As Boolean → As Int32
ですか。
おぉっと。今回は VB.NETでしたっけか。失礼。
フォローありがとうございます。>ねろさん
もし、Boolean型で実装したいなら、VB.NET では
『<MarshalAs(UnmanagedType.Bool)> ByVal failIfExists As Boolean』
のように書いてあげれば OK ですかね。(戻り値も同様)
# そういえば、.NET の Boolean型って何バイトなんだろう。
# http://www.microsoft.com/japan/msdn/library/ja/vblr7/html/vagrpdatatype.asp
# を見ると、2バイトっぽいけれど、Marshal.SizeOf() で調べると 4 が返された……。