人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

現在、WindowsMoible5にてWindows2000の共有フォルダに自動マウントする
機能を開発しようとしているのですが、WNetAddConnection3を呼び出すとNotSupportedExceptionエラーが発生し困っています。
※C++で実装するとNotSupportedExceptionエラーは発生しません。

【環境】
OS :WindowsMobile5(WindowsCE5)
機体:hx2790b
開発環境:VisualStudio2005
言語:VB.net

【やりたい事】
LAN上のWindows2000の共有フォルダからファイルをコピーしたい。
その際に、ログイン画面(ユーザー、パスワード、ドメインを入力する
画面)を表示させずに共有フォルダを利用可能にしたい。

【ソース】
Private Declare Function WNetAddConnection3 Lib "CoreDll.dll" Alias "WNetAddConnection3W" (ByRef hwndOwner As Object, ByRef lpNetResource As NETRESOURCE, ByRef lpPassword As String, ByRef lpUserName As String, ByVal dwFlags As Integer) As Integer





Dim netrs As NETRESOURCE
netrs.dwType = RESURCETYPE_ANY
netrs.lpLocalName = vbNullString
netrs.lpRemoteName = "\\hogeWin2k\share"
netrs.lpProvider = vbNullString
'API呼び出し!
lngRet = WNetAddConnection3(vbNullString, netrs, "USERNAME", "PASSWORD", CONNECT_INTERACTIVE)


よろしくお願い致します。

●質問者: hh1108
●カテゴリ:コンピュータ
✍キーワード:API as C++ DLL LAN
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● ardarim
●50ポイント ベストアンサー

.NET Compact Frameworkのマーシャル機能はかなり限定されていますので、文字列を含んだ構造体などは自動的に適切な処理を行ってくれません。この場合、自分でマーシャリング処理を実装して適切なアンマネージド形式の構造体を作ってAPIにポインタを渡す必要があります。

こちらにやり方が書かれています。

Microsoft .NET Compact Framework での高度な P/Invoke

VBでやる場合は、3つめの方法「マネージ文字列ポインタの使用」を使って実装することになります。

時間が作れたらサンプルを作って回答追加しますが、C++の経験もおありのようなので、後学のために自分で挑戦してみるのもよろしいかと思います。

またはサックリ済ませるのであれば、1つめの方法(C++でサンクDLLを作って経由する)の方が手っ取り早いです。

◎質問者からの返答

ardarim様

ありがとうございます。

教えていただいたURLを参考にこちらでもやろうと思うのですが、

なかなか作業時間を確保するのが難しく、、、

もしよろしければ「マネージ文字列ポインタの使用」でサンプルまでご提示いただけるとうれしいです。


2 ● ardarim
●35ポイント

いちおう動くみたいですが、バグ等は保証の限りでありませんので自己責任でお願いします。

MemoryとStringPtrはMicrosoftのページからそのままコピペしています。

いろいろ調べたらこのMicrosoftのページで紹介されているMemoryというクラスもメモリリークのバグがあるようですので見直したほうが良いと思います。

Imports System.ComponentModel
Imports System.Runtime.InteropServices

Public Class Form1

 Private Structure NETRESOURCE
 Public dwScope As Integer
 Public dwType As Integer
 Public dwDisplayType As Integer
 Public dwUsage As Integer
 Public lpLocalName As StringPtr
 Public lpRemoteName As StringPtr
 Public lpComment As StringPtr
 Public lpProvider As StringPtr

 Public Sub Free()
 lpLocalName.Free()
 lpRemoteName.Free()
 lpComment.Free()
 lpProvider.Free()
 End Sub
 End Structure

 Private Declare Function WNetAddConnection3 Lib "coredll" Alias "WNetAddConnection3W" ( _
 ByVal hwndOwner As Integer, _
 ByRef lpNetResource As NETRESOURCE, _
 ByVal lpPassword As String, _
 ByVal lpUserName As String, _
 ByVal dwFlags As Integer _
 ) As Integer

 Private Const RESOURCETYPE_ANY As Integer = &H0
 Private Const CONNECT_INTERACTIVE As Integer = &H8

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

 Dim lngRet As Integer
 Dim netrs As NETRESOURCE

 netrs.dwType = RESOURCETYPE_ANY
 netrs.lpLocalName = New StringPtr()
 netrs.lpRemoteName = New StringPtr("\\hogeWin2k\share")
 netrs.lpComment = New StringPtr()
 netrs.lpProvider = New StringPtr()

 lngRet = WNetAddConnection3(System.IntPtr.Zero, netrs, "password", "username", CONNECT_INTERACTIVE)

 MsgBox(lngRet)

 netrs.Free()

 End Sub
End Class

Public Class Memory
 <DllImport("coredll.dll", SetLastError:=True)> _
 Private Shared Function LocalAlloc(ByVal uFlags As Integer, _
 ByVal uBytes As Integer) As IntPtr
 End Function

 <DllImport("coredll.dll", SetLastError:=True)> _
 Private Shared Function LocalFree(ByVal hMem As IntPtr) As IntPtr
 End Function

 <DllImport("coredll.dll", SetLastError:=True)> _
 Private Shared Function LocalReAlloc(ByVal hMem As IntPtr, _
 ByVal uBytes As Integer, ByVal fuFlags As Integer) As IntPtr
 End Function

 Private Const LMEM_FIXED As Integer = 0
 Private Const LMEM_MOVEABLE As Integer = 2
 Private Const LMEM_ZEROINIT As Integer = &H40

 Private Const LPTR = (LMEM_FIXED Or LMEM_ZEROINIT)

 ' LocalAlloc を使用して、メモリ ブロックを割り当てます。
 Public Shared Function AllocHLocal(ByVal cb As Integer) As IntPtr
 Return LocalAlloc(LPTR, cb)
 End Function

 ' AllocHLocal で割り当てられたメモリを解放します。
 Public Shared Sub FreeHLocal(ByVal hlocal As IntPtr)
 If Not hlocal.Equals(IntPtr.Zero) Then
 If Not IntPtr.Zero.Equals(LocalFree(hlocal)) Then
 Throw New Win32Exception(Marshal.GetLastWin32Error())
 End If
 hlocal = IntPtr.Zero
 End If
 End Sub

 ' 以前に AllocHLocal で割り当てられたメモリ ブロックのサイズを変更します。
 Public Shared Function ReAllocHLocal(ByVal pv As IntPtr, _
 ByVal cb As Integer) As IntPtr
 Dim newMem As IntPtr = LocalReAlloc(pv, cb, LMEM_MOVEABLE)
 If newMem.Equals(IntPtr.Zero) Then
 Throw New OutOfMemoryException
 End If
 Return newMem
 End Function

 ' マネージ文字列の内容をアンマネージ メモリにコピーします。
 Public Shared Function StringToHLocalUni( _
 ByVal s As String) As IntPtr
 If s Is Nothing Then
 Return IntPtr.Zero
 Else
 Dim nc As Integer = s.Length
 Dim len As Integer = 2 * (1 + nc)
 Dim hLocal As IntPtr = AllocHLocal(len)
 If hLocal.Equals(IntPtr.Zero) Then
 Throw New OutOfMemoryException
 Else
 Marshal.Copy(s.ToCharArray(), 0, hLocal, s.Length)
 Return hLocal
 End If
 End If
 End Function
End Class

Public Structure StringPtr
 Private szString As IntPtr

 Public Sub New(ByVal s As String)
 Me.szString = Memory.StringToHLocalUni(s)
 End Sub

 Public Overrides Function ToString() As String
 Return Marshal.PtrToStringUni(Me.szString)
 End Function

 Public Sub Free()
 Memory.FreeHLocal(Me.szString)
 End Sub
End Structure

◎質問者からの返答

ardarim様

サンプルの提示までいただきありがとうございました。

今回はC#でDLLを作成しそれをVB.net側から利用することにします。

(メモリリークの可能性があるのであればVB.netで実装するのは怖いです)

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ