DOBON.NET DOBON.NETプログラミング掲示板過去ログ

フォルダ共有チェック

環境/言語:[XP VB.NET2002]
分類:[.NET]

再び質問させてください。

指定したフォルダが共有なのかどうかチェックするプルグラムを作りたいのですが、どうしてもうまくいきません。
先日フォルダを共有するというので質問させていただいたのですが、そちらを応用してもチェックがうまくいかないのです。
このAPIはフォルダの共有まではチェックしてくれないのでしょうか?

ここではlngWin32apiResultCodeの値が87でかえってきてしまいます。
どなたか分かる方いたらお願いします。


Dim lngWin32apiResultCode As Integer
Dim strServerName As String
Dim strDevice As Integer
Dim lngType As Integer
Dim gchPath As GCHandle
' サーバー名を設定(空文字の場合はローカルコンピュータ)
strServerName = ""
' 選択されたデバイス名設定
gchPath = GCHandle.Alloc("C:\Documents and Settings\jb4\デスクトップ\sample", GCHandleType.Pinned)
strDevice = gchPath.AddrOfPinnedObject().ToInt32()

' デバイスが共有されているかどうかをチェック
lngWin32apiResultCode = NetShareCheck(vbNullString, strDevice, lngType)
' 共有のチェックに成功したときは
If lngWin32apiResultCode = NERR_Success Then
MsgBox("共有されています。")
Else
MsgBox("共有されていません。")
Call ShareDel()
End If


Module

'共有チェック
Declare Function NetShareCheck Lib "netapi32.dll" _
(ByVal servername As String, _
ByVal device As Integer, _
ByVal dwtype As Integer) As Integer
Public Const STYPE_DISKTREE As Integer = 0
Public Const NERR_Success As Integer = 0
  • 題名: Re[1]: フォルダ共有チェック
  • 著者: 小野@どっとねっとふぁん
  • 日時: 2004/11/18 13:17:33
  • ID: 7495
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
■No7487に返信(はなさんの記事)

> 指定したフォルダが共有なのかどうかチェックするプルグラムを
> 作りたいのですが、どうしてもうまくいきません。

言語も違うし、考え方も違う(WMIを利用)ので、とりあえず参考情報として。
「共有フォルダをリストする方法」
http://blogs.users.gr.jp/dotnetfan/articles/5226.aspx
? ‥‥あ、そっか(ぽむ)

 NetShareCheck 第三引数が ByVal で宣言されてますけど、これを ByRef に変更してください。こちらではそれで動作しました。
#ただ、親階層上のフォルダが共有されていると、指定したフォルダが直接共有されていなくても NERR_Success を返すようでしたが。



※以下余談です。

 恐らく今回も vbvbvb.com のコードを参考にされたのだと思います。
 こちらの宣言は

Declare Function NetShareCheck Lib "netapi32.dll" _
(ByVal servername As String, _
ByVal device As String, _
dwtype As Long) As Long

と、第三引数に ByVal も ByRef もついてませんよね?
 VB6 のとき、 ByVal / ByRef を省略すると ByRef として扱われました。しかし、 VB.NET では省略すると ByVal として扱われます。
 IDE 上でコーディングしていると ByVal が自動的に挿入されるので(まだ)気付き易いとは思うのですけど、知らなければそうもいきませんよね。これから VB6 のコードを参考にするときは意識してみてください。

 ということなので。
 第二引数はそのまま String で大丈夫ですよ。<最初そのままやって上手くいかなかったから、試行錯誤されてたように見えたので。
 もしこのままいくのでしたら、 GCHandle ( gchPath ) は忘れずに Free してあげてくださいませ。
#転記漏れなだけかもですけど(^_^;)


 なお、エラーコード 87 は ERROR_INVALID_PARAMETER として定義されています。その意味するところは『パラメータが間違っています。』です。

Win32エラーコード一覧
http://www.skz.or.jp/ir9/sheela/prog/ayu/win32err.htm


#更に余談。
#前回も今回も本当は API の宣言に MarshalAs 属性をつけるべきだったり。
#余裕ができたらお調べになることをオススメします(^^)
こんにちは。
返信遅くなってすみません。
たびたび質問ですが、いつも丁寧に答えていただいて本当にありがとうございます。

>  NetShareCheck 第三引数が ByVal で宣言されてますけど、これを ByRef に変更してください。こちらではそれで動作しました。
> #ただ、親階層上のフォルダが共有されていると、指定したフォルダが直接共有されていなくても NERR_Success を返すようでしたが。
>

深山さんに教えていただいた方法でByValに変更してしてみたところ、見事に成功しました!!
ありがとうございます><

>  VB6 のとき、 ByVal / ByRef を省略すると ByRef として扱われました。しかし、 VB.NET では省略すると ByVal として扱われます。
>  IDE 上でコーディングしていると ByVal が自動的に挿入されるので(まだ)気付き易いとは思うのですけど、知らなければそうもいきませんよね。これから VB6 のコードを参考にするときは意識してみてください。

私はByRefの存在を今回初めて知りました。
どういう使い分けをするのかこれから調べて勉強したいと思います。
CheckではなんでByValではダメだったのかきちんと理解していきたいと思います。

>  ということなので。
>  第二引数はそのまま String で大丈夫ですよ。<最初そのままやって上手くいかなかったから、試行錯誤されてたように見えたので。
>  もしこのままいくのでしたら、 GCHandle ( gchPath ) は忘れずに Free してあげてくださいませ。
> #転記漏れなだけかもですけど(^_^;)

転記漏れでした・・・^^;



> #前回も今回も本当は API の宣言に MarshalAs 属性をつけるべきだったり。
> #余裕ができたらお調べになることをオススメします(^^)

こちらの学習も一つ一つ理解しながら進んでいきたいと思います。
毎回細かく教えていただいて本当に感謝しています><
答えだけでなく、なぜそうなるのかとか初心者にもとても分かりやすくてリンクも貼っていただいているので、もっと先の勉強も一緒にできるので、どんどん理解が深まっていっています。
今回も力になっていただき、本当にありがとうございましたmm
解決済み!
たびたびすみません。
先日解決にチェックをしたのですが、うまくいかないことがあります。。。

第二引数がStringでいいとありましたので変えたのですが、共有しているものも共有されていないことになってしまいます。
さらにIntegerでしてみるとすべて共有されていますときます。


Declare Function NetShareCheck Lib "netapi32.dll" _
(ByVal servername As String, _
ByVal device As String, _
ByuRef dwtype As Integer) As Integer

どうしたらいいでしょうか?
質問ばかりでごめんなさい。
> 第二引数がStringでいいとありましたので変えたのですが、共有しているものも共有されていないことになってしまいます。
> どうしたらいいでしょうか?
> 質問ばかりでごめんなさい。

 いえ、こちらこそ申し訳ないですm(__)m
 第二引数を String にしただけのパターンでも動作確認したつもりだったのですけど、どうやら勘違いしていたようで(汗)
<今試してみたらこちらでも同様の結果となりました。
# servername で問題が起きなかったのは、空文字を指定してたからだったのかも(///)


    Declare Unicode Function NetShareCheck Lib "netapi32.dll" ( _
        ByVal servername As String, _
        ByVal device As String, _
        ByRef dwtype As Integer) As Integer

のように Unicode を明示、または

    Declare Auto Function NetShareCheck Lib "netapi32.dll" ( _
        ByVal servername As String, _
        ByVal device As String, _
        ByRef dwtype As Integer) As Integer

のように自動判別にする、或いは

    Declare Function NetShareCheck Lib "netapi32.dll" ( _
        <System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)> ByVal servername As String, _
        <System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)> ByVal device As String, _
        ByRef dwtype As Integer) As Integer

のように MarshalAs 属性を指定することで動作すると思います。色々試してみてくださいませ。
#そう言えば以前、よねKENさんが興味深い実験をされてました。参考まで。
#‥‥って、却って混乱させてしまうかしら(^_^;)

[Ref2] GetPrivateProfileString関数の様々な宣言法によるWin2000、Win98での実行結果の成否
http://www5b.biglobe.ne.jp/~yone-ken/VBNET/Reference/ref2_GetPrivateProfileString.html



#ところで全然関係ないことなのですけど。
#(それが自分にとって必要のないことだったとしても)レスしてくださった方に対して何の反応も示さないのはどうかと思いますよ〜。
#↑そんな風に感じるのは古い人間だけ?(ーー;)
すみません、大変遅くなってしまいましたmm

まず、小野さんへ。
レスしてくださったのに、大変失礼なことをしてしまって本当にすみませんでした。せっかく教えていただいたのに、ついつい目先の作業だけにとらわれていました。他の方に言われてからお礼を言うとか失礼だと思いますが、本当にごめんなさい。

深山さん、きちんと注意していただいてありがとうございます。


そして今回も教えていた頂いてありがとうございます。

> Declare Unicode Function NetShareCheck Lib "netapi32.dll" ( _
> ByVal servername As String, _
> ByVal device As String, _
> ByRef dwtype As Integer) As Integer
>
> のように Unicode を明示、または
>
> Declare Auto Function NetShareCheck Lib "netapi32.dll" ( _
> ByVal servername As String, _
> ByVal device As String, _
> ByRef dwtype As Integer) As Integer
>
> のように自動判別にする、或いは
>
> Declare Function NetShareCheck Lib "netapi32.dll" ( _
> <System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)> ByVal servername As String, _
> <System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)> ByVal device As String, _
> ByRef dwtype As Integer) As Integer
>
> のように MarshalAs 属性を指定することで動作すると思います。色々試してみてくださいませ。

unicodeを明示したり、自動判断にさせたり、色々検討してみたのですが、
やっぱりStringとIntegerの違いで実行結果が変わってしまいます。。。
エラーコード一覧を見たりして検討しているのですが、うまくいきません。
MarshalAs については未だ勉強中です。難しいですね。。
もうしばらく色々検討してみたいと思います。


> #そう言えば以前、よねKENさんが興味深い実験をされてました。参考まで。
> #‥‥って、却って混乱させてしまうかしら(^_^;)
>
> [Ref2] GetPrivateProfileString関数の様々な宣言法によるWin2000、Win98での実行結果の成否
> http://www5b.biglobe.ne.jp/~yone-ken/VBNET/Reference/ref2_GetPrivateProfileString.html
>
>
こちらも拝見させていただきました。
内容が難しかったのですが、ちゃんと理解したいと思います。
> unicodeを明示したり、自動判断にさせたり、色々検討してみたのですが、
> やっぱりStringとIntegerの違いで実行結果が変わってしまいます。。。
> エラーコード一覧を見たりして検討しているのですが、うまくいきません。

 あらら、上手くいかないですか(汗) うーん、何が違うのでしょうね‥‥。

 念のために確認ですけど、宣言を String に変えたときは呼び出し側のほうも

> lngWin32apiResultCode = NetShareCheck(vbNullString, strDevice, lngType)
   ↓
lngWin32apiResultCode = NetShareCheck(vbNullString, "C:\Documents and Settings\jb4\デスクトップ\sample", lngType)

のような感じに変えてらっしゃいますよね?
>  あらら、上手くいかないですか(汗) うーん、何が違うのでしょうね‥‥。
>
>  念のために確認ですけど、宣言を String に変えたときは呼び出し側のほうも
>
>>lngWin32apiResultCode = NetShareCheck(vbNullString, strDevice, lngType)
>    ↓
> lngWin32apiResultCode = NetShareCheck(vbNullString, "C:\Documents and Settings\jb4\デスクトップ\sample", lngType)
>
> のような感じに変えてらっしゃいますよね?

変えていませんでした・・・
すみませんでしたmm
変更したら、見事に成功しました!
最後まで丁寧に教えていただいてありがとうございました><
本当に助かりました!ありがとうございましたmm
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板