指定パスがネットワーク上かどうかを調べる

タグの編集
投稿者 pingpong  (社会人) 投稿日時 2020/12/17 11:43:32
また質問させてください。
アプリ上でユーザが選んだファイルのパスを調べると、ネットワーク上のファイルパスは\\で始まるし、リムーバブル機器を含む、PC上のファイルパスはC:\のように英字のドライブ名で始まります。
ただ、ネットワーク上の別PCのフォルダを仮想ドライブに設定すると、このファイルのパスは英字のドライブ名で始まるようになります。
任意のファイルパスの実体がネットワーク上(自分のPC以外の場所)であるかどうかを確認するにはどうすればよいでしょうか?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/12/17 15:52:59
ドライブレターを持つパスの場合、.NET であれば DriveInfo クラスの DriveType プロパティ
VBScript や VBA なら Drive オブジェクトの DriveType プロパティで判定できます。

API 等を呼び出すことなく直接的に使える手は、これぐらいですね…。

※エクスプローラーのコンテキストメニューから「ネットワークドライブの割り当て」を
 選択することで、Z: などのドライブレターを付与することができます。

Public Function IsNetworkPath(p As StringAs Boolean?
    'パスの実在性チェックは省略しています。 
    Try
        If Path.IsPathRooted(p) Then
            If p Like "[a-zA-Z]*" Then
                Dim root As String = Path.GetPathRoot(p)
                Dim di As New DriveInfo(root)
                Return di.DriveType = DriveType.Network
            ElseIf p Like "\\*" Then
                'UNC パスの判断方法は…? 
                Return True
            End If
        End If
    Catch
    End Try
    Return Nothing  '判定不能なパス 
End Function



ドライブレター対策はこれで良いとして、問題は UNC パス表記。
こちらの判定は難しそうです。

殆どのケースでは、ネットワークを指すことが多いでしょうけれども、
ローカルのファイルに対して \\ で始まる UNC パスでアクセスすることもできますので、
\\ で始まればネットワークであるという単純な決めつけはできないはず。

たとえば、「ファイル名を指定して実行」の画面から
"\\localhost\C$\Windows\System32\calc.exe"
という記述で、ローカルの電卓を起動したり、
"\\?\C:\Program Files\dotnet\LICENSE.txt" や
"\\?\C:\Program Files\dotnet\LICENSE.txt" や
"file:///C|/Program Files/dotnet/LICENSE.txt"
という記述で、ローカルのテキストファイルを開いたりできますからね。

OneDrive などのクラウドストレージにマップされているパスや
シンボリックリンク等の扱いも悩ましい所。

仮に、"\\192.168.0.1\SHARE\TEST\新しいファイル.txt" というファイルが
あったとして、これを管理者モードのコマンドプロンプトから
    MD C:¥SAMPLE_FOLDER
    CD /D C:¥SAMPLE_FOLDER
    MKLINK /D EXAMPLE \\192.168.0.1\SHARE\TEST

などしてディレクトリのシンボリックリンクを作成しておいた場合、
"C:¥SAMPLE_FOLDER\EXAMPLE\" というパスでフォルダーにアクセスしたり、
"C:¥SAMPLE_FOLDER\EXAMPLE\新しいファイル.txt" というファイル名で
操作することができます。この場合、これらのパスを
ローカルと見做すべきかネットワークパスと見做すべきかは悩ましい所。
投稿者 pingpong  (社会人) 投稿日時 2020/12/18 10:34:36
魔界の仮面弁士さん、ご回答ありがとうございました。
なるほど、特殊なことをしている場合、あまり簡単に判別できないのですね。
色々と勉強してみます。