[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/08/12(Fri) 09:32
投稿者名:
Eメール:
URL :
タイトル:
Inetを利用したDIRについて
はじめまして。
タイトルの件についてご助言を下さい。

【やりたい事】
 FTPサイトへ接続し、ディレクトリ移動を行った後に、
 ローカルにあるファイルをアップロードする。
 正常にアップロードされたか確認するために、DIRでファイル名と
 SIZEでファイルサイズを取得して、ローカルファイルと比較。
 一致すれば正常にアップロード完了と判断。

【起きている現象】
 ・DIR部分でStateChangedに12が戻ってこない為
  待機ループで無限ループが発生してしまう。

【参考情報】
 ・ただし、DIRコマンド箇所にて一度ブレイクを挟むと
  正常に動作する。

 ・SIZE部分はStateChangedに12は戻ってくるが、
  正常にサイズを取得できない。

  ただし、これもSIZEコマンド箇所にてブレイクを挟むと
  正常にサイズを取得する事が可能。

 ・アップロード処理やディレクトリ移動処理など行わずに
  DIRとSIZEだけを実行した場合は、特にブレイクを打たずとも
  正常に動作。

【ソース】
Private Sub Command1_Click()
Dim strData As String

    With Inet1
        .URL = "ftp://test"
        .AccessType = icFTP
        
        '仮想ディレクトリに移動
        .Execute , "CD webTEST"
        Do While .StillExecuting = True
            DoEvents
        Loop

        'ファイルのアップロード
        .Execute , "PUT c:\TEST\test.tif test.tif"
        Do While .StillExecuting = True
            DoEvents
        Loop
        
    .Execute , "DIR"      ←ここで一旦ブレイクすると正常に動作
        Do While .StillExecuting
            DoEvents
        Loop
        strData = .GetChunk(1024, icString)
        
        .Execute , "SIZE test.tif" ←ここで一旦ブレイクすると正常に動作
        Do While .StillExecuting
            DoEvents
        Loop
        strData = .GetChunk(1024, icString)
        
        '接続を抜ける
        .Execute , "close"
        .Execute , "quit"      
    End With
End Sub


長くなりまして、誠に申し訳ありませんが
ご助言頂けますよう、よろしくお願い致します。

投稿時間:2005/08/13(Sat) 13:15
投稿者名:Starfish
Eメール:
URL :
タイトル:
Re: Inetを利用したDIRについて
> 【起きている現象】
>  ・DIR部分でStateChangedに12が戻ってこない為
>   待機ループで無限ループが発生してしまう。

 DIRとかだと、データが1回だけとは限らないと思いますので、icResponseReceived (8)
がきているのでは?

ヘルプより
>StateChanged イベント
>
>一般に、StateChanged イベントは、GetChunk メソッドを使用してデータを
>取得するかどうかを判断するために使用されます。この判断を行うには、
>Select Case ステートメントを使用し、接続の状態が icResponseReceived (8)
>または icResponseCompleted (12) かどうかを調べます。


> 【参考情報】
>  ・ただし、DIRコマンド箇所にて一度ブレイクを挟むと
>   正常に動作する。

 GetChunk メソッドは、StateChanged イベント内で使用します。と書いてあります。
それ以外で、使用すると正しく取得できるかどうかわかりませんよ。

ヘルプより
>GetChunk メソッド
>GetChunk メソッドは、StateChanged イベント内で使用します。
>State プロパティが icResponseCompleted (12) に設定されている場合は、
>GetChunk メソッドを使用してバッファの内容を取得してください。

投稿時間:2005/08/22(Mon) 11:05
投稿者名:
Eメール:
URL :
タイトル:
Re^2: Inetを利用したDIRについて
Starfishさん、レスが遅くなり申し訳ありません。
帰省の為、ネット繋げませんでしたorz

>DIRとかだと、データが1回だけとは限らないと思いますので、icResponseReceived (8)
がきているのでは?

はい。
ログを見るとその部分で止まっているようです。

となるとDIRの場合は戻り値12(StillExecuting=Flase)による
待機は行えないという事なんでしょうね。。

>GetChunk メソッドは、StateChanged イベント内で使用します。と書いてあります。
それ以外で、使用すると正しく取得できるかどうかわかりませんよ。

と、言われているように根本的なロジックに問題がありそうですね。

教えて頂いた情報を基に、再度ロジックを組みなおしてみたいと思います。

お礼のレスが遅れてしまい、本当に申し訳ありません。
ありがとうございました。

投稿時間:2005/08/22(Mon) 17:14
投稿者名:
Eメール:
URL :
タイトル:
Re^3: Inetを利用したDIRについて
Starfishさんのアドバイスを参考に
GetChunk部分などをStateChangedに移したりしたのですが
やはり動作しませんでした。

Inet上でFTP接続し、
DIRのみを行う場合は正常に動作します。
(この時、最終的には戻り値12が返って来ていました)

もちろんSIZEのみを行う場合も正常に動作します。

しかし、上記二つのロジックを一度に行うと、
直前のロジックでは正常に12が返ってきているので、
"最後の要求が実行中"のエラーは発生しないのですが
やはり動作しません。
(DIR⇒SIZEの場合、DIRは取れるがSIZEが取れない)
(SIZE⇒DIRの場合、SIZEは取れるがDIRで12が戻らず無限ループ)

何かオブジェクトの解放等が必要なのでしょうか?

私の方でも引き続き調査しますが、
どんな些細なヒントでも構いませんので
ご助言の程、よろしくお願い致します。

投稿時間:2005/08/22(Mon) 17:30
投稿者名:ガッ
Eメール:
URL :
タイトル:
Re^4: Inetを利用したDIRについて
> Starfishさんのアドバイスを参考に
> GetChunk部分などをStateChangedに移したりしたのですが
> やはり動作しませんでした。
>
> Inet上でFTP接続し、
> DIRのみを行う場合は正常に動作します。
> (この時、最終的には戻り値12が返って来ていました)
>
> もちろんSIZEのみを行う場合も正常に動作します。
>
> しかし、上記二つのロジックを一度に行うと、
> 直前のロジックでは正常に12が返ってきているので、
> "最後の要求が実行中"のエラーは発生しないのですが
> やはり動作しません。
> (DIR⇒SIZEの場合、DIRは取れるがSIZEが取れない)
> (SIZE⇒DIRの場合、SIZEは取れるがDIRで12が戻らず無限ループ)
どこで無限ループしているのでしょうか…?
StateChangedイベントで、
"コマンドが完了したら正常に12が帰ってくる"という性質を利用して、
.StillExecutingを監視し続けるのを止めてみては?
…もっとするならば、1回目のコマンド呼び出しだけStateChangedイベントの外でやって、
2回目以降のコマンド呼び出しはStateChangedイベントの中で行うとか…

> 何かオブジェクトの解放等が必要なのでしょうか?
Inetオブジェクトを再作成するのですか…
最終手段にしておきましょう。

> 私の方でも引き続き調査しますが、
> どんな些細なヒントでも構いませんので
> ご助言の程、よろしくお願い致します。
Inetはあまりいい話を聞きませんねぇ…止めちゃいます?(ぇ
あいにく手元に実験できる環境がないので本当につまらないことしか書けませんが、
・icResponseCompletedの時にすべてのデータを受け取っているか?
  →すべてのデータを受け取らないで、.StillExecuteメンバがFalseに変化するかどうかも確かめると
いいか
も。
  そしたら、すべてのデータを受け取って、変化するかどうかを見る。
  …まぁ、別にしなくてもいいですけどねぇ…

長文失礼しました。

投稿時間:2005/08/22(Mon) 17:46
投稿者名:
Eメール:
URL :
タイトル:
Re^5: Inetを利用したDIRについて
ガッさん、ご助言ありがとうございます。

> どこで無限ループしているのでしょうか…?
DIRを使用した際に、StateChangedイベントが完了しなくなる為
待機状態が延々と続いてしまいます。
(尚、DIRのみを実行した場合は正常に12が返ってきました)

.Execute , "DIR"
Do While .StillExecuting
  DoEvents
Loop
↑このループが抜けれません。


> StateChangedイベントで、
> "コマンドが完了したら正常に12が帰ってくる"という性質を利用して、
> .StillExecutingを監視し続けるのを止めてみては?
この場合、どのようにしてVBの処理を待機させるのでしょうか?
12が戻るまでVBのメインロジックを待機させないと行けないのですが
私の方でもStillExecutingを使用せずに、StateChanged内で
12が戻るまでループとかも試したのですが駄目でした。

> …もっとするならば、1回目のコマンド呼び出しだけStateChangedイベントの外でやって、
> 2回目以降のコマンド呼び出しはStateChangedイベントの中で行うとか…
StateChanged内でSIZEを実行するという事でよろしいでしょうか?
さっそく試してみたいと思います。


> Inetオブジェクトを再作成するのですか…
> 最終手段にしておきましょう。
ためしにInetを一度クローズして切断し、再度接続しなおしても
現象変わらずでした。

また、もうひとつInetオブジェクトを貼り付けてInet1とInet2で
処理を分けてみましたが、やはり駄目でした。

> Inetはあまりいい話を聞きませんねぇ…止めちゃいます?(ぇ
そうしたいのは山々なんですけどw
Inetしか使えない状態な物でorz

> あいにく手元に実験できる環境がないので本当につまらないことしか書けませんが、
> ・icResponseCompletedの時にすべてのデータを受け取っているか?
>   →すべてのデータを受け取らないで、.StillExecuteメンバがFalseに変化するかどうかも確かめると
> いいか
> も。
>   そしたら、すべてのデータを受け取って、変化するかどうかを見る。
>   …まぁ、別にしなくてもいいですけどねぇ…

一応、現在はGetChunkで取得するデータが0になるまで
処理をまわす様にしてますので、おそらく全てのデータを
取得出来てはいると思うのですが
もし、認識間違いなどありましたらご指摘下さい。


> 長文失礼しました。
いえいえ、本当にありがとうございました。
引き続き、調査したいと思います。


#やはりブレイクを打つと上手く動作するんです。。
 処理が早すぎるのかと思って、空ループとか入れてみたんですが
 やはり駄目でしたorz

投稿時間:2005/08/24(Wed) 00:54
投稿者名:Starfish
Eメール:
URL :
タイトル:
Re^6: Inetを利用したDIRについて
 StateChangedイベントで、どういうコードを書いているか見えないんですが、
たとえば、以下のようなコードでうまくいかないでしょうか?
 ヘルプを参考にしていますが、実際に動かしてみていないので、おかしいところが
あるかもしれませんが。

Dim mBlnFinish As Boolean
Dim mstrData As String

Private Sub Command1_Click()
Dim strData As String

    With Inet1
        .URL = "ftp://test"
        .AccessType = icFTP

        '仮想ディレクトリに移動
        .Execute , "CD webTEST"
        Do While .StillExecuting = True
            DoEvents
        Loop
        
        'ファイルのアップロード
        .Execute , "PUT c:\TEST\test.tif test.tif"
        Do While .StillExecuting = True
            DoEvents
        Loop

        mstrData = ""
        mBlnFinish = False
        .Execute , "DIR"
        Do While mBlnFinish = False
            DoEvents
        Loop
        Do While .StillExecuting    ' 念のため
            DoEvents
        Loop
        ' mstrData にDIRの結果が入っているのでここで処理する

        mstrData = ""
        mBlnFinish = False
        .Execute , "SIZE test.tif"
        Do While mBlnFinish = False
            DoEvents
        Loop
        Do While .StillExecuting
            DoEvents
        Loop
        ' mstrData にSIZEの結果が入っているのでここで処理する

        '接続を抜ける
        .Execute , "close"
        .Execute , "quit"
    End With
End Sub

Private Sub Inet1_StateChanged(ByVal State As Integer)
Dim vtData As Variant ' データを入れる変数。
Dim bDone As Boolean
    
    Select Case State
    ' ... その他の場合は省略します。

   Case icResponseReceived, icResponseCompleted

   ' 最初のチャンクを取得します。
        vtData = Inet1.GetChunk(1024, icString)
        DoEvents
        Do While Not bDone
            DoEvents
            mstrData = mstrData & vtData
            DoEvents
            ' 次のチャンクを取得します。
            vtData = Inet1.GetChunk(1024, icString)
            If Len(vtData) = 0 Then
                bDone = True
            End If
        Loop

        If State = icResponseCompleted Then
            mBlnFinish = True
        End If
        
    End Select
  
End Sub

投稿時間:2005/08/24(Wed) 10:20
投稿者名:
Eメール:
URL :
タイトル:
Re^7: Inetを利用したDIRについて
ご助言、ありがとうございます。
提示して頂いたソースを試した所、一回目のCDで移動するタイミングで
GetChunk部分にて"最後の要求が実行中です"エラーが発生しました。

おそらくcase分の条件にicResponseReceivedが含まれているからだと思います。
(icResponseCompletedが戻るまで、次の処理要求は実行できない為)

>StateChangedイベントで、どういうコードを書いているか見えないんですが、
現在の状況はこのような感じです。

Private Sub Command1_Click()
    Dim strData As String
    
    With Inet1
      .URL = "ftp://test"
        .AccessType = icFTP
    End With

    Inet1.Execute , "CD webTEST"
    '待機処理
    Do While Inet1.StillExecuting
        DoEvents
    Loop
    
    Inet1.Execute , "PUT C:\TEST\test.tif test.tif"
    Do While Inet1.StillExecuting
        DoEvents
    Loop
    
    Inet1.Execute , " CLOSE"
    Inet1.Execute , " QUIT"

    With Inet1
      .URL = "ftp://test"
        .AccessType = icFTP
    End With

  'とりあえず両方はあきらめて、サイズだけでも取得しようとしています。
    Inet1.Execute , " SIZE test.tif"
    Do While Inet1.StillExecuting = True
        DoEvents
    Loop
  
End Sub


Private Sub Inet1_StateChanged(ByVal State As Integer)
Dim vtData As Variant ' データを入れる変数。
Dim strData As String: strData = ""
Dim bDone As Boolean: bDone = False

Select Case State
    Case icResponseCompleted
   ' 最初のチャンクを取得します。
        vtData = Inet1.GetChunk(1024, icString)
        DoEvents

        Do While Not bDone
            DoEvents
            strData = strData & vtData
            DoEvents
            ' 次のチャンクを取得します。
            vtData = Inet1.GetChunk(1024, icString)
            If Len(vtData) = 0 Then
                bDone = True
            End If
        Loop
        'ここで値取得してログに出力

    Case icError
    'エラー処理
End Select
End Sub


現在、少し進展(?)して、サイズが取得できる事が
"可能な時も"発生するようになりました^−^;

上記コマンドボタンを実行すると、もちろんサイズは取得出来ないのですが
続けてもう一度実行すると正常に取得できます。

つまり実行する事に、取れたり取れなかったりといった具合です。

最初はアップロードしたファイルだから、認識できないのかと疑いましたが
既存のファイルをSIZEで取得した場合も同様の現象が発生することから
アップロードファイル事態に問題があるわけではなさそうです。

ためしに、ファイルサイズに値が戻ってくるまでループしてみましたが
予想通りというかなんというか無限ループに陥りましたorz

引き続き調査を行いますので、
何かお気づきの点などございましたら、
ご助言の程、よろしくお願い致します。

投稿時間:2005/08/24(Wed) 11:14
投稿者名:ガッ
Eメール:
URL :
タイトル:
Re^8: Inetを利用したDIRについて
私のデバッグ方法…参考になるかな…?
★をつけたところを追加します。

> Private Sub Command1_Click()
>     Dim strData As String
>      
>     With Inet1
>       .URL = "ftp://test"
>         .AccessType = icFTP
>     End With
>
debug.? "A:CD webTEST" '★
>     Inet1.Execute , "CD webTEST"
debug.? "B:CD webTEST" '★
>     '待機処理
>     Do While Inet1.StillExecuting
>         DoEvents
>     Loop

debug.? "A:PUT C:\TEST\test.tif test.tif" '★
>     Inet1.Execute , "PUT C:\TEST\test.tif test.tif"
debug.? "B:PUT C:\TEST\test.tif test.tif" '★
>     Do While Inet1.StillExecuting
>         DoEvents
>     Loop
debug.? "done" '★

>     Inet1.Execute , " CLOSE"
>     Inet1.Execute , " QUIT"
>
>     With Inet1
>       .URL = "ftp://test"
>         .AccessType = icFTP
>     End With
>
>   'とりあえず両方はあきらめて、サイズだけでも取得しようとしています。
>     Inet1.Execute , " SIZE test.tif"
>     Do While Inet1.StillExecuting = True
>         DoEvents
>     Loop
>    
> End Sub
>
> Private Sub Inet1_StateChanged(ByVal State As Integer)
> Dim vtData As Variant ' データを入れる変数。
> Dim strData As String: strData = ""
> Dim bDone As Boolean: bDone = False
>
> Select Case State
>     Case icResponseCompleted
>    ' 最初のチャンクを取得します。
debug.? "StateChanged:recv start" '★
>         vtData = Inet1.GetChunk(1024, icString)
>         DoEvents
>
>         Do While Not bDone
>             DoEvents
>             strData = strData & vtData
>             DoEvents
>             ' 次のチャンクを取得します。
>             vtData = Inet1.GetChunk(1024, icString)
>             If Len(vtData) = 0 Then
>                 bDone = True
>             End If
>         Loop
debug.? "StateChanged:recv comp" '★
>         'ここで値取得してログに出力
>
>     Case icError
>     'エラー処理
> End Select
> End Sub
デバッグ出力としては、
A:CD webTEST
B:CD webTEST
StateChanged:recv start
StateChanged:recv comp
A:PUT C:\TEST\test.tif test.tif
B:PUT C:\TEST\test.tif test.tif
StateChanged:recv start
StateChanged:recv comp
done
となっているはずですが、どうなるでしょう?

> つまり実行する事に、取れたり取れなかったりといった具合です。
微妙ですねぇ…

> 最初はアップロードしたファイルだから、認識できないのかと疑いましたが
> 既存のファイルをSIZEで取得した場合も同様の現象が発生することから
> アップロードファイル事態に問題があるわけではなさそうです。
>
> ためしに、ファイルサイズに値が戻ってくるまでループしてみましたが
> 予想通りというかなんというか無限ループに陥りましたorz
ちゃんとStateChangedイベントで受信処理を無限ループになりますか?
…そうなると、やっぱりInetの内部処理がアヤシイですねぇ…

> 引き続き調査を行いますので、
> 何かお気づきの点などございましたら、
> ご助言の程、よろしくお願い致します。
現在私もInetコントロールを使ってHTMLをダウンロードするプログラムを作って使っていますが、
以下の点で困っているのです(ぃぇ、別に解決しようとしているわけではなくて…)
1 ExecuteでGETメソッドを使って非同期にダウンロードを開始する
2 Inetコントロールをおいたウィンドウをリサイズしたり、ダブルクリックしたり、移動したり
  出来なくなる(!
  →ダウンロードが完了すると元通り。
(もしかしたら、Executeの内部で自力でウィンドウメッセージを処理していて、マウス系のイベントを

害していたりするかも…)
次に作るなら、こんなコントロール使うよりも他のを使おうかな…とかも考えていたり(orz
で、叶さんの問題もイベントに関するものなのでもしかしたら私の問題と根本は同じだったりするかも

れません。
→あきらめる、と…(TT

※参考URL
hhttp://homepage1.nifty.com/MADIA/vb/vb_bbs2/200409_04090078.html

※戯言
VB6はシングルスレッド→InetコントロールがVBに所属するとなると、スレッドは増えやせない?→
けど非同期に実行できているので、タイマーとか使っているのかな?→
内部でウィンドウメッセージで処理してる?それともコールバック関数使ってる?→
あやすぃー……

長文しつれいしましたー

投稿時間:2005/08/24(Wed) 11:48
投稿者名:
Eメール:
URL :
タイトル:
Re^9: Inetを利用したDIRについて
度々、ありがとうございます。
さっそくガッさんのデバッグ方法を試してみた所
以下のような結果となりました。

【イミディエイト表示】
A:CD webTEST
B:CD webTEST
StateChanged:recv start
StateChanged:recv comp
A:PUT C:\TEST\test.tif test.tif
B:PUT C:\TEST\test.tif test.tif
StateChanged:recv start
StateChanged:recv comp
done
StateChanged:recv start
StateChanged:recv comp

startとcompが最後にもう一度走っているのが気になりますが
サイズを取得できない場合、出来る場合共に
イミディエイトに表示される流れの結果は一緒でした。

> 次に作るなら、こんなコントロール使うよりも他のを使おうかな…とかも考えていたり(orz

本当、出来ることならInetではなく他の方がお勧めしているような
モジュールを使いたいのですけど^−^;

どうしてもInetしか使用できない状況なのがつらい所です。

> →あきらめる、と…(TT

はっきりとこのロジックじゃInetは動かないという情報があれば
その方向で話を進言したいとも考えているのですけどね;

単体じゃ動く、取れたり取れなかったりするけど取れる時もある。
となると、自分の作り方が悪いだけで、どうにかしたら
出来るんじゃないかという思いがあってorz


> ※参考URL
> hhttp://homepage1.nifty.com/MADIA/vb/vb_bbs2/200409_04090078.html

ありがとうございます。
参考に見させて頂きます。

教えて頂いたデバッグのやり方をいろいろ試しながら
引き続き調査したいと思います。

投稿時間:2005/08/25(Thu) 17:13
投稿者名:
Eメール:
URL :
タイトル:
解決しました
StarFishさん、ガッさん
お力添えありがとうございました。

無事、ファイル名、サイズとも正常に取得する事が出来ました。
原因は環境にあったようです。

開発環境の為、一台のノートPCにてFTPサイトを作成し
ループバックを使用して開発を行っていたのですが、
ふと思い立って、別の端末を用意し、
実際にLANにて環境を構築した状態で
開発環境から、別端末へのFTP接続を行ったら
普通に動作しました。

INetを使用して開発を行う場合、実際にネットワーク環境を
作らないと、誤動作の原因になるようですorz

お力添えを頂いた方、ありがとうございました。
サイト管理者様、長いスレになってしまい
誠にご迷惑をお掛けしました。

以上で解決としたいと思います。

ありがとうございました。