プロが教える店舗&オフィスのセキュリティ対策術

Visual Basic を用いてネットワーク上の他のパソコンのディスク上にあるファイルの有無をチェックするのにDir関数を用いています。

If Dir("\\192.168.24.50\共有データ\aaa.csv") <> "" Then

指定したIPアドレスのパソコンと繋がっていればDir関数はすぐに終了するのですが、繋がっていなければDir関数は約30秒終了しません。
指定したIPアドレスのパソコンと繋がっていなくてもDir関数をすぐに終了したいのですが、何か方法はないでしょうか。

下記方法が可能であれば、ファイルの有無チェックが即座にできそうに思えますが、小生には方法がわかりません。
・Dir関数の前に繋がっているかを即座に判断できる方法。
・Dir関数のタイムアウト設定を行う方法。
・Dir関数を用いずにファイルの有無チェックが即座にできる方法(関数)
何か良い解決案があれば教えて下さい。お願いします。

A 回答 (2件)

少々検索など調べてみましたが、DirやGetAttrに対するタイムアウトは存在しないようですね。


推測混じりですが、共有フォルダをマウント(厳密には違う意味ですが、イメージが伝わるかと造語的に使っています)するまでの、タイムアウトが影響しているのだと思われます。
簡単に検索してみた限りでは情報が見つからなかったので、それが変更できるか否か簡単か否かも不明ですが、それが簡単に変更できるとして、OS全体に影響を与えることや、反映されるまで時間が掛かるなど(OS再起動後に有効など)がかなり高い確率で予想されるため、調査に時間を掛ける必要はないと感じました。

SMB/CIFSプロトコルを自前で実装することで、もしかすると若干早く対象PCにアクセス可能か否か判断できる可能性はあります。
http://www.atmarkit.co.jp/fwin2k/serial/index/in …
http://www.atmarkit.co.jp/fwin2k/network/baswinl …
膨大な労力が予測される割に、得るものは少ないと予測されるため、小生であれば選択しません。(暇なときに、趣味のプログラムの延長でなら楽しめるかも知れません、というレベルですね)

実現可能性が若干高いのは、pingコマンドを発行して対象PCの存在チェックぐらいです。
とは言えこれも、ファイアウォールなどのセキュリティ対策によって応答が返らない可能性や、作成するソフトがウィルスと誤認される可能性などを考えると実現不可能ですね。

上にだらだらと、できないことばかり並べたのは、ここまで調査したので実現不可能だと判明しましたと、業務のプログラム作成の際にクライアントに説明する際の小生の癖です(クライアントもプログラムについて判る人なので)。

で、代替え案としては、
1)カーソルを砂時計にしてアプリ画面は操作不能にして、『待つしかないです、待たないためには対象PCの電源は入れっぱなしにしてください』、あるいは『(サーバーなどの)必ず起動しているマシンにデータを入れましょう』と説明します。
魔法の呪文『仕様です』ですね。

2)待つのは仕方ないとして、アプリケーションが固まってしまうのがフリーズしたかと勘違いされるを避けるために、プログレスウィンドウを表示します。
VBで普通に作るとマルチスレッドではないため、プログレスの表示も固まってしまいます。
プログレス表示専用の別EXEを作成して、起動して最前面表示、Dirの応答が返ったあと(ファイルを開いてから)そのEXEを終了させます。
『困ったときのプログレス』ですね。

3)アプリケーション起動時に一度チェックします。
アプリ起動時には、少々時間が掛かるものです。ユーザーさんの納得も得られやすい。
もちろん、アプリケーション起動後、対象のファイルが必要になるまでに、対象のPCの電源を落とされることもあるでしょうが、待たなければならない可能性は減らせます。
プログレス代わりのスプラッシュを表示します。

4)必ず時間がかかるようにします。
早い時、遅い時があれば、遅い時にはイライラします。ファイルが存在し即次の処理に移れる場合でもタイマーなどで時間を調節して、わざと時間が掛かるようにします。
早い時、遅い時の時間差を調節する目的です。感覚的に言えば、遅い時が30秒としたら、早い時は20秒とかですね。

5)『データを保存してあるパソコンが起動していることを確認してください。対象のパソコンが起動していない場合、応答までに時間が掛かります』と、注意書きを表示する。
対象ファイルを開く処理が頻繁でなければ、メッセージボックスでOKキャンセルでも良いですね。
頻繁で、ボタンクリックで開く場合などは、ボタンの横に赤字で大きいフォントで入れるなど。
『ちゃんと説明書いてるじゃないですか』と逃げます。

逃げや欺瞞の案ばかりですね。

理想で言えば、対象ファイル(CSV)をDB化して、データベースサーバーへの接続ですね。SQLサーバーも無料のものがありますし。
次善はTCP/IPで通信するアプリで、ファイルのデータを読み取り送受信するサーバープログラムが対象PCに常駐していて、データを使用するプログラムはクライアントとしてそのサーバープログラムに接続するって形ですかね。
    • good
    • 0
この回答へのお礼

とても親切な回答、ありがとうございます。
又、タイムアウトの有無の調査&代替案の検討等、感謝致します。
今回、開発しているシステム構成ですが、データ収集用パソコンのCSVファイルをデータ表示用パソコンが取得(5秒周期)し、表示するという仕組みです。
他のパソコンは接続は接続せず、2台のパソコンだけがローカルでLANケーブルに接続している状態です。(セキュリティソフト等も動作していません。)
基本的に2台のパソコンは常に接続しているはずですが、エラー処理として未接続時の確認で表示用パソコンのDir関数が終了しない為に画面がしばらくロック状態に陥りました。
データ表示用パソコンもデータ収集を行っている為、データ収集用パソコンと未接続の場合でも、画面をロックするわけにはいきません。
そこで、いくつか教えていただいた案の中で「Dir関数の前にpingコマンドの発行」が有効だと思いました。
pingコマンドのサンプルプログラムを用いて自宅パソコンで試したのですが、繋がっている/繋がってないに関わらず、pingコマンドはすぐに完了しました。休み明けに会社のシステムでpingコマンドが有効か試してみようと思います。
本当に親切なアドバイス、ありがとうございました。

お礼日時:2008/11/23 17:11

VB6の頃であれば、Win32APIのGetFileAttributeを利用して、ファイルの有無チェックをしていましたね。


ネットワークに対しては行っていませんが、フロッピー(当時は現役でした)に対しては、Dirよりも速度が速かった記憶があります。
VB6標準のGetAttrを使用しなかった理由は、エラー処理の簡単さだったと思います。

.Net以降にも使えるワザかどうか、ネットワークに対して有効かどうかは不明です。
    • good
    • 0
この回答へのお礼

早速の回答、ありがとうございます。
小生のWindows アプリケーションの知識が乏しく、Win32APIのGetFileAttributeの使用方法がわからなかった為、GetAttrを使用して試しましたが、Dir関数と同様に繋がってないパソコンに対しては30~40秒位、GetAttr関数が終了するのに時間を要しました。
(使用しているバージョンはVB6です。)

お礼日時:2008/11/23 07:57

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!