マシン名によるファイル検索をするには?

解決


さめ児  2004-06-08 18:45:59  No: 113788  IP: [192.*.*.*]

はじめまして、"さめ児"です。

今、私はマシン名による共有フォルダの取得なるものを作成しています。
手順としては、
    1,リストボックスにワークグループ内にあるマシン名を全て取得
    2,リストボックスに表示されたマシン名を選択(1台〜複数台)
    3,ファイル名の指定(*.*,*.txtなど)
    4,「検索」ボタン押下後、リストビューにファイル名,作成日時,フルパス表示
    5,リストビューに表示したファイルの中から他のファイルにコピー、貼り付け

今、現在、2,3の部分で躓いています。
どうぞアドバイスの方、宜しくお願いします。

環境:Windows2000、VB6.0 SP4

編集 削除
とろ  2004-06-09 11:23:03  No: 113789  IP: [192.*.*.*]

>今、現在、2,3の部分で躓いています。
リストボックスの使い方が分からないということでしょうか?
MSDNはご覧になりましたでしょうか?

編集 削除
さめ児  2004-06-09 13:16:35  No: 113790  IP: [192.*.*.*]

そうです。
Helpをみても、取得の仕方が良く分かりません。
また、2〜5まで、分からなくなってきました。
一応、4については組んでいるのですが、マシンの共有フォルダを見に行ってないようなので・・・
アドバイスの方、宜しくお願いします。

編集 削除
とろ  2004-06-09 14:14:38  No: 113791  IP: [192.*.*.*]

ListBoxで複数のアイテムを選択できるようにするにはMultiSelectプロパティ
の値をTrueにセットします。
MSDNに記載されているMultiSelectプロパティの使用例を抜粋しておきます。

Private Sub Form_Load()
   Dim I         ' 変数を宣言します。
   ' リスト ボックス コントロールにスクリーン フォント名を表示します。
   For I = 0 To Screen.FontCount - 1
      List1.AddItem Screen.Fonts(I)
   Next I
End Sub

Private Sub Command1_Click()
   Dim I         ' 変数を宣言します。
   ' リストの全項目をクリアします。
   List2.Clear
   ' 項目が選択されていれば、2 番目のリスト ボックス コントロールに追加します。
   For I = 0 To List1.ListCount - 1
      If List1.Selected(I) Then
         List2.AddItem List1.List(I)
      End If
   Next I
End Sub

編集 削除
さめ児  2004-06-09 15:18:55  No: 113792  IP: [192.*.*.*]

リストボックスについては、"とろ"さんのお陰で解決できました。

次に、「3,ファイル名の指定(*.*,*.txtなど)」ですが、

ファイル名の指定をし、検索ボタンを押下しても、マシン名直下の共有フォルダ名が取れていないために、なにもListViewに表示されません。

どうすれば、いいでしょうか?

アドバイス、宜しくお願いします。

編集 削除
とろ  2004-06-09 15:40:42  No: 113793  IP: [192.*.*.*]

問題は何ですか?
共有フォルダの列挙の仕方が分からないということですか?
問題を明確にすることが完成への第一歩です。

編集 削除
さめ児  2004-06-09 16:02:07  No: 113794  IP: [192.*.*.*]

現状:マシン名、ファイル名指定後、検索ボタンを押下するが、リストビューに何も表示されない。

原因:マシン名は取得しているが、直下の共有フォルダを取得できていない。

質問:マシン直下にある共有フォルダの取得方法がわかりません。
"lngFindFileHandle = FindFirstFile(strPath & mstrSearchFile, wfd)"のstrpathに、「マシン名+共有フォルダ名」が格納されていればリストビューに表示できるようなのですが、組み方がわかりません。

編集 削除
とろ  2004-06-09 16:12:40  No: 113795  IP: [192.*.*.*]

参考にしてみてください

http://vbvbvb.com/jp/gtips/0251/gNetShareEnum.html

編集 削除
さめ児  2004-06-09 17:14:53  No: 113796  IP: [192.*.*.*]

確かに、実行すると、ローカルのみ取得できてますね。

ネットワークの場合は、下記の部分を変更すればできそうですね。
    
' サーバー名を設定(空文字の場合はローカルコンピュータ)
    strServerName = _
        StrConv("", _
                vbUnicode)
    Do
        ' 共有リソースを列挙
        lngWin32apiResultCode = _
            NetShareEnum(strServerName, _
                          2, _
                          lngBufPtr, _
                          MAX_PREFERRED_LENGTH, _
                          lngEntriesRead, _
                          lngTotalEntries, _
                          lngResumeHandle)

編集 削除
さめ児  2004-06-09 17:57:41  No: 113797  IP: [192.*.*.*]

なぜか取得できません。

サーバー名:MARLU(コンボボックスに入力したサーバー名)→combo1
マシン名:Same(リストボックスで選択したマシン名)→list1

これらをどこに設定すればいいのでしょう?

編集 削除
とろ  2004-06-09 18:47:24  No: 113798  IP: [192.*.*.*]

トレースすれば何故取得できていないか分かるでしょう。
また、変数をウォッチすれば引数にどんな値がわたっているかも分かります。

おそらくNetShareEnumがエラーとなっていると思うんですが
そのエラーコードは調べましたか?

編集 削除
さめ児  2004-06-09 19:03:23  No: 113799  IP: [192.*.*.*]

「NetShareEnum」ではサーバー名、マシン名は設定したので取れましたが、
「' リソースの列挙に成功したときは」

If (lngWin32apiResultCode = NERR_Success) Or _
           (lngWin32apiResultCode = ERROR_MORE_DATA) Then

の部分で抜けてしまいました。

編集 削除
とろ  2004-06-09 19:13:48  No: 113800  IP: [192.*.*.*]

抜けたのはlngWin32apiResultCodeがNERR_SuccessでもERROR_MORE_DATAでも
なかっただからということは分かりますよね?
としたらlngWin32apiResultCode値は何ですか
lngWin32apiResultCodeがNetShareEnumの戻り値です。
その値が分かれば、その値が何を意味しているのかを調べれば何故取得できなかった
のかも分かってくるはずです。

編集 削除
さめ児  2004-06-09 19:36:22  No: 113801  IP: [192.*.*.*]

有難う御座います。
調べてみます。

編集 削除
さめ児  2004-06-09 20:05:58  No: 113802  IP: [192.*.*.*]

今、会社にいるので、一時退出します。
帰宅後、報告したいと思います

編集 削除
さめ児  2004-06-10 08:58:32  No: 113803  IP: [192.*.*.*]

「lngWin32apiResultCode値=53」
昨日、どうやっても"0"にならないのが分かりませんでした。

編集 削除
とろ  2004-06-10 11:11:19  No: 113804  IP: [192.*.*.*]

おつかれさまです。
エラーコード値が分かったら下記URLで原因を調べてみましょう

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes__0-499_.asp

「The network path was not found.」って書いてありますね。
引数を確かめてみましょう

編集 削除
さめ児  2004-06-10 11:34:17  No: 113805  IP: [192.*.*.*]

今、調べてみましたが、「ERROR_BAD_NETPATH」となっていました。
これは、サーバー設定に問題があるのでしょうか?
それとも、他に原因があるのでしょうか?

編集 削除
とろ  2004-06-10 12:08:16  No: 113806  IP: [192.*.*.*]

「ネットワークパスが見つかりませんでした」って書いてありますね。
NetShareEnumの引数を確かめてみましょう

編集 削除
さめ児  2004-06-10 13:09:59  No: 113807  IP: [192.*.*.*]

strServerName = _
        StrConv("MARLU", vbUnicode)
とすると、
lngWin32apiResultCode = _
            NetShareEnum(strServerName, _
                          1, _
                          lngBufPtr, _
                          MAX_PREFERRED_LENGTH, _
                          lngEntriesRead, _
                          lngTotalEntries, _
                          lngResumeHandle)
の「strServerName」が"M・A・R・L・U"となってしまってました。
これが、原因ですか?

また、他の引数には、
lngBufPtr→0
MAX_PREFERRED_LENGTH→-1
lngEntriesRead→0
lngTotalEntries→0
lngResumeHandle→0

編集 削除
とろ  2004-06-10 14:08:01  No: 113808  IP: [192.*.*.*]

「ネットワークパスが見つかりませんでした」って書いてありますね。
つまりMARLUという名前のコンピュータがネットワーク上に見つからない
ということです。

編集 削除
さめ児  2004-06-10 14:23:32  No: 113809  IP: [192.*.*.*]

では、どうすればいいのしょうか?
「MARLU」→ サーバー名
「SAME」→ 自身PC名
「共有」→ 共有フォルダ名
なのですが、どうすればいいのでしょうか?

編集 削除
うにぃ  2004-06-10 14:42:26  No: 113810  IP: [192.*.*.*]

>strServerName = StrConv("MARLU", vbUnicode)
がいらないのではないかと思います。

編集 削除
さめ児  2004-06-10 14:46:28  No: 113811  IP: [192.*.*.*]

strServerName = _
        StrConv("MARLU", vbUnicode)

  「"MARLU"」は、サーバー名だったので、PC名を格納しているList1.textを設定すると、エラーは出ませんが、「lngEntriesRead」には、全く関係の無いフォルダ名が入ってしまっている。
  「SAME」直下の共有フォルダは4つしか存在しないはずなのに、7つもデータが返ってきてしまう。 

これは、どうしてですか?

編集 削除
とろ  2004-06-10 16:36:42  No: 113812  IP: [192.*.*.*]

返ってくるのは共有フォルダだけではありません。
共有リソース(プリンタ等も含む)なのでタイプで判断
して下さい。
本家のヘルプを書いておきます。

http://msdn.microsoft.com/library/en-us/netmgmt/netmgmt/netshareenum.asp?frame=true

一つ一つパラメータの意味をよく理解しながらプログラミングしてください。

編集 削除
岡田 之仁  2004-06-13 10:18:48  No: 113813  IP: [192.*.*.*]

MSDNのヘルプでは・・・
ServerNameのところで、
This string must begin with \\.
とあります。これは、UNC名にしろと言うことでは
ないしょうか?

よって、
strServerName = "\\MARLU"
と言うことになりますが。

尚、ADSIで実現する方法では・・・
    Dim FileService As IADsFileService
    Dim FileShare As IADsFileShare
    Dim ComputerName As String
    
    List3.Clear
    
    ComputerName = List2.List(List2.ListIndex)
    
    Set FileService = GetObject("WinNT://" & ComputerName & "/LanmanServer")

    If FileService.Class = "FileService" Then
        For Each FileShare In FileService
            If Right$(FileShare.Name, 1) <> "$" Then
                List3.AddItem FileShare.Name
                'Debug.Print FileShare.Path
            End If
        Next
    End If

ちょっと乱暴なコードですが、これで取得できました。
環境や動作させるマシンで問題があるかもしれませんが。

参考までに。

以上。

編集 削除
さめ児  2004-06-15 14:14:53  No: 113814  IP: [192.*.*.*]

有難う御座いました。
正常に表示することができました。

編集 削除