ネットワークドライブへの接続

タグの編集
投稿者 N88-BASIC  (社会人) 投稿日時 2016/9/22 14:34:44
Windows 10 Pro (64bit) + Visual Basic 2015 Community にてネットワークドライブへの接続を行う処理を行おうとしております。

サーバー(ネットワークドライブの提供元)はルーターのUSBメモリの共有機能です。
マニュアル処理では問題なく接続でき、また、「ユーザー認証なし」の設定では下記コードで問題なく接続できています。
「ユーザー認証あり」に設定すると、下記コードでは”指定されたネットワークパスワードが間違っています。”と表示されてしまいます(パスワードが間違っているとおっしゃられるとそれまでですが、、)

デバッグをお願いしているようで心苦しいのですが、下記コードに問題があればご指摘いただければ幸いです。

余談ですが、WNetCancelConnection2A ではマニュアル接続のドライブの切断には問題ありません。

以上 よろしくお願いします。

以下、使用コード

'----- ネットワークドライブの接続の環境整備 -----
    Public Declare Function WNetAddConnection2 Lib "mpr.dll" Alias _
        "WNetAddConnection2A" (ByRef lpNetResource As NETRESOURCE,
                               ByVal lpPassword As String,
                               ByVal lpUserName As String,
                               ByVal dwFlags As Integer) As Integer

    Public Structure NETRESOURCE
        Public dwScope As Integer
        Public dwType As Integer
        Public dwDispalyType As Integer
        Public dwUsage As Integer
        Public lpLocalName As String
        Public lpRemoteName As String
        Public lpComment As String
        Public lpProvider As String
    End Structure

    Private Function iAddNetDrive() As Integer
        Dim NetRsrc As NETRESOURCE
        Dim strUser As String = "user"
        Dim strPass As String = "A"
        NetRsrc.dwScope = 2
        NetRsrc.dwType = &H1
        NetRsrc.dwDispalyType = &H3
        NetRsrc.lpLocalName = "N:"
        NetRsrc.lpRemoteName = "\\NetDrive\Common"
        NetRsrc.dwUsage = Nothing
        NetRsrc.lpComment = Nothing
        NetRsrc.lpProvider = Nothing
        iAddNetDrive = WNetAddConnection2(NetRsrc, strPass, strUser, 0)
 End Function

'----------- 以下が接続処理と接続処理の結果の確認 -------------
   Private Sub btConnect_Click(sender As Object, e As EventArgs) Handles btConnect.Click
        Dim iRes As Integer = iAddNetDrive()
        lbStatus.Text = New System.ComponentModel.Win32Exception(iRes).Message 
    End Sub

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2016/9/23 12:29:30
> "WNetAddConnection2A"
個人的には Wide 版を使った方が良いと思っているのですが、
Web のサンプルの多くは、ANSI 版ばかりなんですよね…。



> Dim strUser As String = "user"
> Dim strPass As String = "A"
間違いなく、『半角「A」一文字』なのですね?


> パスワードが間違っているとおっしゃられるとそれまでですが、、
「パスワードが正しく送られていない(文字化けなど)」のか、
「本当にパスワードが間違っている」か、まずは事前確認を行いましょう。

たとえば PowerShell で
$user = "user"
$pass = ConvertTo-SecureString "A" -AsPlainText -Force
$drive = "N"
$unc = "\\NetDrive\Common"

$$ = New-Object PSCredential($user, $pass)
ndr $drive FileSystem $unc -Credential $$ -Persist
を実行するか、またはコマンドプロンプトで NET USE コマンドを使って、N: ドライブにマッピングすることはできていますか?

この時点でパスワードエラーになるのだとしたら「それまで」の問題なわけで。
投稿者 N88-BASIC  (社会人) 投稿日時 2016/9/25 10:03:19
魔界の仮面弁士 さん、チェック用のコマンドまでご紹介いただきありがとうございました。

実行結果は奇妙な結果でした。

1)ご提示いただいたコマンドの実行結果は、問題なく接続できました。 
 その後、切断を行い、本プログラムを実行すると、接続が完了いたしました。
 ただ、再起動後は接続できません。

2)NET USE コマンドの実行
  パスワードの指定(記述)なし、パスワードの指定あり、パスワード&ユーザー名の指定あり
  いずれの場合も接続できました。
  ただ、本プログラムでの接続は「不可」でした。

3)プログラム上のユーザー名のみを未確認のものに変更すると、
 同じ、”指定されたネットワーク パスワードが間違っています。”とのエラーです。

4)ネットワークドライブのユーザー名の変更後
  ご提示いただいたコマンドの実行(ユーザー名等は正しいもの)は「接続不可」でした。

 NET USE コマンドは「接続可能」でした。

5)ネットワークドライブのユーザー名を元に戻すと
 コマンドの接続は可能でした。

その他、前回の質問での情報漏れは
※サーバーは立てていません。ドメインは WORKGROUP です。

想像ですが、NET USE コマンド以外は、記憶されている資格情報と一致していないとエラーが出るようです。
プログラムというよりシステムの構成上の問題があるかもしれません。

今後は、Shell("net use n: ...")にて対応しようかと考えております(コマンドの実行結果は GetForegroundWindow での確認後、WNetGetUser による確認がいいのでは?と思っています)。

※ 最初は、WNetAddConnection2W で試していたのですが「指定されたデバイス名は無効です。」となり、Unicode による記載方法がわからずあきらめました。

余談、WNetAddConnection2* に受け渡す構造体への形式ですが ByRef としており(Web検索のサンプルの参照により)、ByVal では実行時エラーとなります。API の説明では DWORD WNetAddConnection2(  _In_ LPNETRESOURCE lpNetResource, ..)とあり ByVal が正しいと思っていました 。WNetGetUser では、_Out_ や _Inout_ がByRef としていました(ただ、LPTSTR などがはっきりわからず、名前の取得はせず接続確認だけで済ませました)。本サイトの情報では WNetCancel -> WNetAdd という順序での提案がありましたが、接続しているのを切断するのがもったいので、正しいかどうかはわかりませんが、 WNetGetUser にしました)

以上 長文並びにご連絡が遅くなりましたが、今後ともよろしくお願いいたします。

また、変化がありましたらご報告いたします。

※本来の質問に対しての解決ではありませんが、実質的に目的を達せそうですので、「解決済」とさせていただきました。