指定パスがネットワーク上かどうかを調べる への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/12/17 15:52:59
ドライブレターを持つパスの場合、.NET であれば DriveInfo クラスの DriveType プロパティ
VBScript や VBA なら Drive オブジェクトの DriveType プロパティで判定できます。
API 等を呼び出すことなく直接的に使える手は、これぐらいですね…。
※エクスプローラーのコンテキストメニューから「ネットワークドライブの割り当て」を
選択することで、Z: などのドライブレターを付与することができます。
ドライブレター対策はこれで良いとして、問題は 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" というファイルが
あったとして、これを管理者モードのコマンドプロンプトから
などしてディレクトリのシンボリックリンクを作成しておいた場合、
"C:¥SAMPLE_FOLDER\EXAMPLE\" というパスでフォルダーにアクセスしたり、
"C:¥SAMPLE_FOLDER\EXAMPLE\新しいファイル.txt" というファイル名で
操作することができます。この場合、これらのパスを
ローカルと見做すべきかネットワークパスと見做すべきかは悩ましい所。
VBScript や VBA なら Drive オブジェクトの DriveType プロパティで判定できます。
API 等を呼び出すことなく直接的に使える手は、これぐらいですね…。
※エクスプローラーのコンテキストメニューから「ネットワークドライブの割り当て」を
選択することで、Z: などのドライブレターを付与することができます。
Public Function IsNetworkPath(p As String) As 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
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/17 11:43:32
また質問させてください。
アプリ上でユーザが選んだファイルのパスを調べると、ネットワーク上のファイルパスは\\で始まるし、リムーバブル機器を含む、PC上のファイルパスはC:\のように英字のドライブ名で始まります。
ただ、ネットワーク上の別PCのフォルダを仮想ドライブに設定すると、このファイルのパスは英字のドライブ名で始まるようになります。
任意のファイルパスの実体がネットワーク上(自分のPC以外の場所)であるかどうかを確認するにはどうすればよいでしょうか?
アプリ上でユーザが選んだファイルのパスを調べると、ネットワーク上のファイルパスは\\で始まるし、リムーバブル機器を含む、PC上のファイルパスはC:\のように英字のドライブ名で始まります。
ただ、ネットワーク上の別PCのフォルダを仮想ドライブに設定すると、このファイルのパスは英字のドライブ名で始まるようになります。
任意のファイルパスの実体がネットワーク上(自分のPC以外の場所)であるかどうかを確認するにはどうすればよいでしょうか?
なるほど、特殊なことをしている場合、あまり簡単に判別できないのですね。
色々と勉強してみます。