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

フォルダを共有する

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

2004/11/12(Fri) 14:39:59 編集(投稿者)

初心者です。
ファイルの共有をプラグラムでしたいのですが、
ヘルプ等見てもよくわかりません。
いろんなサンプルを見ながら作ったものですが、どなたか分かる方いらっしゃったらよろしくお願いします。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim lngWin32apiResultCode As Long
Dim strServerName As String
Dim gchNetName As GCHandle
Dim gchRemark As GCHandle
Dim gchPath As GCHandle
Dim gchPassword As GCHandle
Dim udtShareInfo2 As SHARE_INFO_2
Dim lngParmErr As Long
Dim strNetName As String
Dim s As Integer
strNetName = TextBox1.Text
'Dim targetEncoding As Encoding = Encoding.Unicode
strServerName = " "    '空白でローカルコンピュータ指定
s = AscW(strServerName)  'unicode変換
MsgBox(s)
'targetEncoding = Encoding.GetEncoding(strServerName)
' 共有情報を設定
With udtShareInfo2
' 共有名
gchNetName = GCHandle.Alloc("ShareTest", GCHandleType.Pinned)
.shi2_netname = gchNetName.AddrOfPinnedObject().ToInt32()
' 共有タイプ
.shi2_type = STYPE_DISKTREE
' コメント
gchRemark = GCHandle.Alloc("test", GCHandleType.Pinned)
.shi2_remark = gchRemark.AddrOfPinnedObject().ToInt32()
' 最大ユーザー数
.shi2_max_uses = 1
' 共有フォルダ
gchPath = GCHandle.Alloc("C:\Documents and Settings\jb4\デスクトップ\新しいフォルダ", GCHandleType.Pinned)
.shi2_path = gchPath.AddrOfPinnedObject().ToInt32()
' パスワード
gchPassword = GCHandle.Alloc("hoge", GCHandleType.Pinned)
.shi2_passwd = gchPassword.AddrOfPinnedObject().ToInt32()
End With
' 指定したフォルダを共有
lngWin32apiResultCode = NetShareAdd(strServerName, 2, udtShareInfo2, lngParmErr)
' フォルダの共有に成功したときは
If lngWin32apiResultCode = NERR_Success Then
MsgBox(strNetName & "の共有を追加しました", MsgBoxStyle.Information)
Else
MsgBox(strNetName & "の共有に失敗しました", MsgBoxStyle.Exclamation)
End If

gchNetName.Free()
gchRemark.Free()
gchPath.Free()
gchPassword.Free()

End Sub

毎回lngWin32apiResultCodeの値が124となって失敗しています。
なせでしょうか?
> いろんなサンプルを見ながら作ったものですが、

 えっと‥‥↓のコードそのままのように見受けられるのですけど(^_^;)
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=12584&forum=7&0

 偶然かも知れませんが、こちらを参考にされてたという前提で話をさせて頂きます。


 リンク先にもあるように、戻り値 124 は ERROR_INVALID_LEVEL として定義されています。
その意味するところは『level パラメータで指定した値が無効です。』
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpnetmg/html/_win32_netshareadd.asp

 確かに level に 2 を指定するのは誤りではありません。が、その宣言に誤りがあります。

> Declare Function NetShareAdd Lib "netapi32.dll" (ByVal servername As Object, ByVal level As Long, ByRef buf As SHARE_INFO_2, ByRef parm_err As Integer) As Integer

とされてますけど、 level の型は Integer ですから。

---------------------------------------
(余談)
 このコードは vbvbvb.com にあったもの ※1 を .NET に書き換えた ※2 ものと思われますが、その際に Long → Integer し忘れた箇所があったのでしょうね。

※1 0285 | gNetShareAddDrive.vbp ドライブを共有する
http://vbvbvb.com/jp/gtips/0251/gNetShareAddDrive.html
※2 VarPtr, StrPtr, ObjPtr関数の代わりになるものは?
http://dobon.net/vb/dotnet/vb6/objptr.html
辺りを参考にしたんじゃないかなぁ、と。ご自身で構造体定義を書かれてたら GCHandle を使用しなければならない内容にはしないでしょうし。
 勿論、実際のところは判りませんが :-p

 尚、データのマーシャリングを行っているサンプルを探したところ、次のようなものが見つかりました。参考まで。
C# CODES SOURCES より
http://www.csharpfr.com/code.aspx?id=23474
---------------------------------------


 別の箇所で気になったのは
> strServerName = " "    '空白でローカルコンピュータ指定
でしょうか。
 ローカル コンピュータで行うときに servername に NULL を指定します。
サンプルを見る限り空文字でも大丈夫そうですが、空白では上手くいかないのではないかと。(未確認)


 もし最初に書いたリンク先の内容とは無関係でしたら、関数、構造体、定数の宣言部分も併せて投稿された方がレスがつき易いでしょう。
# No7329 の内容だけでは実行して試すことができませんよね?
深山さん、はじめまして。
お早い返答ありがとうございます。すいません。遅くなりましたmm
丁寧に教えていただいてありがとうございます。

>  えっと‥‥↓のコードそのままのように見受けられるのですけど(^_^;)
> http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=12584&forum=7&0

そうです。そちらのコードを参考にさせていただきました。

> その意味するところは『level パラメータで指定した値が無効です。』
>  確かに level に 2 を指定するのは誤りではありません。が、その宣言に誤りがあります。
>
>>Declare Function NetShareAdd Lib "netapi32.dll" (ByVal servername As Object, ByVal level As Long, ByRef buf As SHARE_INFO_2, ByRef parm_err As Integer) As Integer
>
> とされてますけど、 level の型は Integer ですから。

levelはIntegerではないといけないんですね、ありがとうございます。
ほかのLongのところもIntegerに変更しなければならないのでしょうか?

> ※1 0285 | gNetShareAddDrive.vbp ドライブを共有する
> http://vbvbvb.com/jp/gtips/0251/gNetShareAddDrive.html
> ※2 VarPtr, StrPtr, ObjPtr関数の代わりになるものは?
> http://dobon.net/vb/dotnet/vb6/objptr.html
> 辺りを参考にしたんじゃないかなぁ、と。ご自身で構造体定義を書かれてたら GCHandle を使用しなければならない内容にはしないでしょうし。
>  勿論、実際のところは判りませんが :-p

はい、そちらを参考にさせていただきました。

>  尚、データのマーシャリングを行っているサンプルを探したところ、次のようなものが見つかりました。参考まで。
> C# CODES SOURCES より
> http://www.csharpfr.com/code.aspx?id=23474
> ---------------------------------------

>  別の箇所で気になったのは
>> strServerName = " "    '空白でローカルコンピュータ指定
> でしょうか。
>  ローカル コンピュータで行うときに servername に NULL を指定します。
> サンプルを見る限り空文字でも大丈夫そうですが、空白では上手くいかないのではないかと。(未確認)

空文字でないとダメなんですよね。
でもunicodeに変換するときに
s = AscW(strServerName)
という関数を使ったのですが、空文字は変換されなくて、空白文字をいれてしてみたところを空文字に戻すのを忘れていました。
すいません。
ここを空文字で実行すると、「引数 'String' の長さは 0 より大きくなければなりません。」と出てきました。ほかにunicodeに変換する関数とかはあるのでしょうか?色々調べてみたのですが、見つからなくてこれにしました。

>  もし最初に書いたリンク先の内容とは無関係でしたら、関数、構造体、定数の宣言部分も併せて投稿された方がレスがつき易いでしょう。
> # No7329 の内容だけでは実行して試すことができませんよね?

すいません、こちらも載せるのを忘れていました。

Module Module1

Declare Function NetShareAdd Lib "netapi32.dll" (ByVal servername As Object, ByVal level As Integer, ByRef buf As SHARE_INFO_2, ByRef parm_err As Integer) As Integer
Structure SHARE_INFO_2
Dim shi2_netname As Integer
Dim shi2_type As Integer
Dim shi2_remark As Integer
Dim shi2_permissions As Integer
Dim shi2_max_uses As Integer
Dim shi2_current_uses As Integer
Dim shi2_path As Integer
Dim shi2_passwd As Integer
End Structure
Public Const STYPE_DISKTREE As Short = 0
Public Const NERR_Success As Short = 0

End Module

です。
> お早い返答ありがとうございます。すいません。遅くなりましたmm
> 丁寧に教えていただいてありがとうございます。

 どういたしまして(^^)
‥‥と言いたいところですけど、お役に立てなかったようですね(汗)< Integer に変えただけでは駄目だったようで申し訳ありませんm(__)m
#あ、時間については気になさらないでくださいな。掲示板でのやり取りですから、タイムラグはあって当然ですもの。
#一週間とか空いたら話は別ですけど :)

 閑話休題。
 NetShareAdd の第一引数が(何故か) Object で宣言されてますけど、これを String に変更してくださいませ。
こちらではこれで共有に成功しました。


> ほかのLongのところもIntegerに変更しなければならないのでしょうか?

 いけない、ということはないでしょうけど、その方が望ましいでしょう。
 NetShareAdd の戻り値は Integer なのに lngWin32apiResultCode が Long である必要はありませんから。
第四引数で使用している lngParmErr についても同様です。


> でもunicodeに変換するときに
> s = AscW(strServerName)
> という関数を使ったのですが、空文字は変換されなくて、空白文字をいれてしてみたところを空文字に戻すのを忘れていました。
> すいません。
> ここを空文字で実行すると、「引数 'String' の長さは 0 より大きくなければなりません。」と出てきました。ほかにunicodeに変換する関数とかはあるのでしょうか?色々調べてみたのですが、見つからなくてこれにしました。

 誤解があるようですが、 AcsW 関数は文字コードの変換を行うわけではありません。
 ヘルプにもあるように引数で指定された文字の文字コードを返します。
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vblr7/html/vafctasc.asp

 実際に文字コードの変換が必要になることは少ないのではないかと思います(今回は必要ありません)。
必要になったときには、はなさんも試されてたように Encoding クラスを用いることになるでしょうか。
2004/11/17(Wed) 09:48:39 編集(投稿者)

こんにちは。
返信ありがとうございます!
>
>  閑話休題。
>  NetShareAdd の第一引数が(何故か) Object で宣言されてますけど、これを String に変更してくださいませ。
> こちらではこれで共有に成功しました。
>
Stringに直したところ、私も共有に成功しました!ありがとうございます。
あと、第一引数を「vbNullString」に変えてみました。
「strServerName」では失敗したので…


>  いけない、ということはないでしょうけど、その方が望ましいでしょう。
>  NetShareAdd の戻り値は Integer なのに lngWin32apiResultCode が Long である必要はありませんから。
> 第四引数で使用している lngParmErr についても同様です。

どちらもIntegerに直しました。ありがとうございます。

>  誤解があるようですが、 AcsW 関数は文字コードの変換を行うわけではありません。
>  ヘルプにもあるように引数で指定された文字の文字コードを返します。
> http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vblr7/html/vafctasc.asp
>
>  実際に文字コードの変換が必要になることは少ないのではないかと思います(今回は必要ありません)。
> 必要になったときには、はなさんも試されてたように Encoding クラスを用いることになるでしょうか。

AcsW関数の使い方間違っていたんですね…
しかも、今回必要ないんですね。VB.NETはあらかじめ、unicodeなんですね。

共有に成功することができてうれしいです。毎回分かりやすく教えていただいて本当にありがとうございました><
解決済み!

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