web-dev-qa-db-ja.com

ネットワークドライブにディレクトリが存在するかどうかを確認します

ディレクトリが存在するかどうかを検出しようとしていますが、この特定の状況では、ディレクトリはネットワーク上の場所です。 VB.NETのMy.Computer.FileSystem.DirectoryExists(PATH)およびより一般的なSystem.IO.Directory.Exists(PATH)を使用しましたが、どちらの場合もシステム応答はfalseです。確認してPATHが存在する場合、MyComputer Folderで表示できます。プログラムをデバッグし、My.Computer.FileSystem.Drives変数、ネットワークの場所はそのリストに表示されません。

PDATE:チェックして、WindowsでXP ResponseはTrueですが、Windows 7ではそうではありません。

PDATE2:提案された両方のソリューションをテストしましたが、同じ問題がまだあります。下の画像では、Explorerを使用してアクセスできますが、私のプログラムはできません。 GetUNCPath関数は有効なパス(エラーなし)を返しますが、Directory.Exists stilはfalseを返します。

また、UNCパス「\\ Server\Images」で試しました。同じ結果。

enter image description here

PDATE3:ネットワークドライブとリンクできない場合、UNCパスに直接リンクするにはどうすればよいですか? VSを通常モードで実行すると機能することを発見しましたが、ソフトウェアは管理者モードで実行する必要があります。だから、管理者としてネットワークディレクトリの存在を確認する方法はありますか?

20
Natalia

UACがオンになっている場合、マップされたネットワークドライブは、マップされたセッションに「デフォルト」でのみ存在します:通常または昇格。 Explorerからネットワークドライブをマップし、VSを管理者として実行すると、ドライブはそこにありません。

MSが「リンク接続」と呼ぶものを有効にする必要があります:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System:EnableLinkedConnections(REG_DWORD)= 0x1

UACとの「2つのログオンセッション」に関する背景情報: http://support.Microsoft.com/kb/937624/en-us

14
Martin Binder

System.IO.Directory.Existsを使用すると、ディレクトリが見つからなかったことがわかりますが、これは、ディレクトリが実際に存在しないか、ユーザーがディレクトリへの十分なアクセス権を持っていないためです。

これを解決するために、Directory.Existsがディレクトリの不在の本当の理由を取得できなかった後、標準のDirectory.Existsメソッドの代わりに使用されるグローバルメソッドにこれをラップした後、2次テストを追加します:

''' <summary>
''' This method tests to ensure that a directory actually does exist. If it does not, the reason for its 
''' absence will attempt to be determined and returned. The standard Directory.Exists does not raise 
''' any exceptions, which makes it impossible to determine why the request fails.
''' </summary>
''' <param name="sDirectory"></param>
''' <param name="sError"></param>
''' <param name="fActuallyDoesntExist">This is set to true when an error is not encountered while trying to verify the directory's existence. This means that 
''' we have access to the location the directory is supposed to be, but it simply doesn't exist. If this is false and the directory doesn't exist, then 
''' this means that an error, such as a security error, was encountered while trying to verify the directory's existence.</param>
Public Function DirectoryExists(ByVal sDirectory As String, ByRef sError As String, Optional ByRef fActuallyDoesntExist As Boolean = False) As Boolean
    ' Exceptions are partially handled by the caller

    If Not IO.Directory.Exists(sDirectory) Then
        Try
            Dim dtCreated As Date

            ' Attempt to retrieve the creation time for the directory. 
            ' This will usually throw an exception with the complaint (such as user logon failure)
            dtCreated = Directory.GetCreationTime(sDirectory)

            ' Indicate that the directory really doesn't exist
            fActuallyDoesntExist = True

            ' If an exception does not get thrown, the time that is returned is actually for the parent directory, 
            ' so there is no issue accessing the folder, it just doesn't exist.
            sError = "The directory does not exist"
        Catch theException As Exception
            ' Let the caller know the error that was encountered
            sError = theException.Message
        End Try

        Return False
    Else
        Return True
    End If
End Function
8
competent_tech
public static class MappedDriveResolver
    {
        [DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern int WNetGetConnection([MarshalAs(UnmanagedType.LPTStr)] string localName, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder remoteName, ref int length);
        public static string GetUNCPath(string originalPath)
        {
            StringBuilder sb = new StringBuilder(512);
            int size = sb.Capacity;

            // look for the {LETTER}: combination ...
            if (originalPath.Length > 2 && originalPath[1] == ':')
            {
                // don't use char.IsLetter here - as that can be misleading
                // the only valid drive letters are a-z && A-Z.
                char c = originalPath[0];
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
                {
                    int error = WNetGetConnection(originalPath.Substring(0, 2), sb, ref size);
                    if (error == 0)
                    {
                        DirectoryInfo dir = new DirectoryInfo(originalPath);
                        string path = Path.GetFullPath(originalPath).Substring(Path.GetPathRoot(originalPath).Length);
                        return Path.Combine(sb.ToString().TrimEnd(), path);
                    }
                }
            }    
            return originalPath;
        }
    }

使用するには、ネットワークフォルダーパスを渡し、UNCフォルダーパスに変換して、フォルダーが存在するかどうかを確認します。

File.Exists(MappedDriveResolver.GetUNCPath(filePath));

編集:

ネットワークドライブを表示するときに、2番目の編集と(Windows7での)唯一の違いを見ましたコンピューター>イメージ(\\​​ xyzServer)。 PCの名前はEquipoですか?スペイン語ではteamですか?それはあなたのPCですか?私はあなたの問題を再現しようとしましたが、それは私のために働いています:

enter image description here

5
Jeremy Thompson

これに加えて、リストできるネットワーク共有で「存在」チェックを行う必要がありましたが、アカウントにはアクセス許可がないため、Directory.ExistsはFalseを返しました。

投稿されたさまざまなソリューションが私にとってうまくいかなかったので、ここに私自身のものがあります:

public static bool DirectoryVisible(string path)
{
    try
    {
        Directory.GetAccessControl(path);
        return true;
    }
    catch (UnauthorizedAccessException)
    {
        return true;
    }
    catch
    {
        return false;
    }
}
1
WhoIsRich