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

フォルダの共有

  • 題名: フォルダの共有
  • 著者: がぶりぇる
  • 日時: 2008/06/27 11:02:40
  • ID: 22359
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[WindowsXP/BisualBasic2008]
分類:[.NET]

VB6.0で作成していたソフトを改造し、ソフトからメール送信等の処理を行いたいため、
.NETに変換しようと思い、最近になって.NETを使用し始めました。
そのソフト内でフォルダを共有化する処理があったのですが、
NetShareAddを使用していたので、過去ログ内のhttp://dobon.net/vb/bbs/log3-13/7329.html
を参考にコードを修正しました。
コード部分でブレークポイントを入れ、ステップインにて実行すると問題なく共有化されるのですが、
ブレークポイントを入れずに実行した場合はエラーとなり共有化が行われません。
ステップイン実行時は問題なく共有化されるため原因がわからずに困っている状況です。
どうか、ご教授ください。

Option Strict Off
Option Explicit On
Imports VB = Microsoft.VisualBasic
Imports System.Runtime.InteropServices

Friend Class frm_main
Inherits System.Windows.Forms.Form

'リソースの共有を設定する関数
Private Declare Function NetShareAdd Lib "netapi32.dll" (ByVal ServerName As String, ByVal level As Integer, ByRef buf As SHARE_INFO, ByRef parm_err As Integer) As Integer

'共有情報
Private Structure SHARE_INFO
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

'-----------------------------------------------------
'@(f)
'
'機能  :フォームロード処理
'
'-----------------------------------------------------
Private Sub frm_main_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load

''フォルダを共有
Call DriveShare()

End Sub

Private Sub DriveShare()
'共有フォルダ作成

Dim strServerName As String
Dim udtShareInfo As SHARE_INFO
Dim lngReturn As Integer
Dim lngParmErr As Integer
Dim CheckFlg As Boolean
Dim gchNetName As GCHandle
Dim gchRemark As GCHandle
Dim gchPath As GCHandle
Dim gchPassword As GCHandle

CheckFlg = OSCheck  ''NT系OS時はTrueを返す
If CheckFlg = True Then
'サーバ名を設定(空文字の場合はローカルコンピュータ)
strServerName = ""
'共有情報を設定
With udtShareInfo
gchNetName = GCHandle.Alloc("UCAMフォルダ", GCHandleType.Pinned)
.shi2_netname = gchNetName.AddrOfPinnedObject().ToInt32()
.shi2_type = STYPE_DISKTREE
gchRemark = GCHandle.Alloc("UCAMフォルダ", GCHandleType.Pinned)
.shi2_remark = gchRemark.AddrOfPinnedObject().ToInt32()
.shi2_permissions = 0
.shi2_max_uses = 4
.shi2_current_uses = 0
gchPath = GCHandle.Alloc(My.Application.Info.DirectoryPath, GCHandleType.Pinned)
.shi2_path = gchPath.AddrOfPinnedObject().ToInt32()
gchPassword = GCHandle.Alloc("", GCHandleType.Pinned)
.shi2_passwd = gchPassword.AddrOfPinnedObject().ToInt32()
End With
'指定したリソースを共有
lngReturn = NetShareAdd(strServerName, 2, udtShareInfo, lngParmErr)
''正常終了・すでに共有されてる場合以外
If (lngReturn <> 0) And (lngReturn <> 2118) Then
MsgBox("共有化失敗!" & vbCrLf & "エラーコード:" & lngReturn, MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, "エラー")
End
End If
gchNetName.Free()
gchRemark.Free()
gchPath.Free()
gchPassword.Free()
End If

End Sub
End Class

ステップイン実行時はlngReturnに「0」か「2118」が帰ってきます。
(すでに共有されている場合は2118が帰ってきています)
ブレークポイントを設定せずに実行すると「123」が返されます。
WIN32エラーコードを見ると
ERROR_INVALID_NAME 123 ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。
となっているのですが、どう回避していいのかわからないのです。
下記、コード参考・・・

Public Enum SHARE_TYPE As Integer
Disk = 0
Printer = 1
Device = 2
IPC = 3
Special = &H80000000
End Enum

Public Enum SHARE_PERMISSION As Integer
ACCESS_NONE = 0
ACCESS_READ = 1
ACCESS_WRITE = 2
ACCESS_CREATE = 4
ACCESS_EXEC = 8
ACCESS_DELETE = &H10
ACCESS_ATRIB = &H20
ACCESS_PERM = &H40
ACCESS_ALL = ACCESS_READ + ACCESS_WRITE + ACCESS_CREATE + ACCESS_EXEC + ACCESS_DELETE + ACCESS_ATRIB + ACCESS_PERM
ACCESS_GROUP = &H8000
End Enum

<StructLayout(LayoutKind.Sequential)> _
Public Structure SHARE_INFO_2
<MarshalAs(UnmanagedType.LPWStr)> Public shi2_netname As String
<MarshalAs(UnmanagedType.U4)> Public shi2_type As SHARE_TYPE
<MarshalAs(UnmanagedType.LPWStr)> Public shi2_remark As String
<MarshalAs(UnmanagedType.U4)> Public shi2_permissions As SHARE_PERMISSION
<MarshalAs(UnmanagedType.U4)> Public shi2_max_uses As Integer
<MarshalAs(UnmanagedType.U4)> Public shi2_current_uses As Integer
<MarshalAs(UnmanagedType.LPWStr)> Public shi2_path As String
<MarshalAs(UnmanagedType.LPWStr)> Public shi2_passwd As String
Public shi502_reserved As Integer
Public shi502_security_descriptor As IntPtr
Public Sub New(ByVal netName As String, ByVal type As SHARE_TYPE, ByVal remark As String, _
ByVal maxUses As Integer, ByVal path As String, ByVal permissions As SHARE_PERMISSION, ByVal passwd As String)
shi2_netname = netName
shi2_type = type
shi2_remark = remark
shi2_permissions = permissions
shi2_max_uses = maxUses
shi2_current_uses = 0
shi2_path = path
shi2_passwd = passwd
shi502_security_descriptor = IntPtr.Zero
End Sub
End Structure

'リソースの共有を設定する関数
<DllImport("netapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function NetShareAdd(<MarshalAs(UnmanagedType.LPWStr)> ByVal servername As String, _
ByVal level As Integer, ByRef buf As SHARE_INFO_2, ByRef parm_err As Integer) As Integer
End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim iRet As Integer

'フォルダを共有
iRet = DriveShare("共有名", "共有パス", "コメント")
If iRet <> 0 Then
MsgBox("共有化失敗!" & vbCrLf & "エラーコード:" & iRet.ToString.Trim, MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, "エラー")
End If

End Sub

Private Function DriveShare(ByVal ShareName As String, ByVal SharePath As String, ByVal ShareComment As String) As Integer

'共有フォルダ作成
Dim strServerName As String
Dim udtShareInfo As SHARE_INFO_2
Dim iRet As Integer
Dim lngParmErr As Integer

strServerName = ""

udtShareInfo = New SHARE_INFO_2(ShareName, SHARE_TYPE.Disk, ShareComment, -1, SharePath, SHARE_PERMISSION.ACCESS_NONE, "")

'指定したリソースを共有
iRet = NetShareAdd(strServerName, 502, udtShareInfo, lngParmErr)

Return iRet

End Function

こんなところでしょうか・・・

Vista の場合、このプログラムを管理者権限で動作させれば、OKです。

以上。
  • 題名: Re[2]: フォルダの共有
  • 著者: がぶりぇる
  • 日時: 2008/06/30 9:40:29
  • ID: 22371
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
無事、共有化の処理に成功しました!
今後は、教えていただいたコードの内容を理解し、
精進していきたいと思います。

ただ、 NetShareAddの返り値ですが、
すでに共有されている場合は2118が帰ってくるため、
その場合のケアも必要になるようですね。
解決済み!

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