2013-07-04 96 views
20

我试图检测目录是否存在,但在这种特殊情况下,我的目录是网络位置。我使用VB.NET的My.Computer.FileSystem.DirectoryExists(PATH)和更一般的System.IO.Directory.Exists(PATH),在这两种情况下,系统响应都是错误的。 我检查并存在PATH,我可以在MyComputer文件夹中查看它。 如果我调试程序,并观察My.Computer.FileSystem.Drives变量,则网络位置不会出现在该列表中。检查网络驱动器上是否存在目录

更新:我检查,并在Windows XP中的反应是真实的,但不是在Windows 7

UPDATE2:我测试都提出了解决方案,但我仍然有同样的问题,下面的图片你会看到我可以使用资源管理器访问,但我的程序不能。 GetUNCPath函数返回有效路径(无错误),但Directory.Exists stil返回false。

我也尝试过使用UNC路径“\\ Server \ Images”;相同的结果。

enter image description here

UPDATE3:如果我不能与网络驱动器链接,我怎么可以链接到直接UNC路径?我发现,如果我在正常模式下运行VS,它可以工作,但我的软件必须以管理员模式运行。那么,有什么办法以管理员身份检查网络目录的存在吗?

+0

听起来像它可能是一个UAC的问题。你是否以管理员身份运行程序? – keyboardP

+0

是的,我使用管理员权限运行Visual Studio。 – Natalia

+0

据我所知,你做预期的格式,即:\\ server_name \ folder \ file.this – varocarbas

回答

12

如果UAC开启,映射网络驱动器只能在会话中“默认”,他们被映射:正常或升高。如果您从资源管理器映射网络驱动器,然后以管理员身份运行VS,驱动器将不在那里。

您需要启用什么MS称之为 “链接连接”: HKEY_LOCAL_MACHINE \ SOFTWARE \微软\的Windows \ CurrentVersion \政策\系统:EnableLinkedConnections(REG_DWORD)=为0x1

背景有关 “两个登录会话” 用信息UAC:http://support.microsoft.com/kb/937624/en-us

+0

我在普通帐户中运行VS,它工作的很好,我在HKEY_LOCAL_MACHINE上创建了EnableLinkedConnections键,但是当我以管理员模式运行VS时,仍然收到错误。 – Natalia

+0

请参阅更新3请 – Natalia

+0

等待,我看在互联网上,他们说我必须重新启动计算机,所以我会先检查一下。 – Natalia

8

当您使用System.IO.Directory.Exists时,它只会让您知道它无法找到该目录,但这可能是因为该目录实际上不存在或者因为该用户没有足够的目录权限。

为了解决这个问题,我们增加一个次要测试Directory.Exists未能获得该目录的缺席的真正原因,我们已经包装成在适当位置使用的标准Directory.Exists方法的一个全球性的方法,在此之后:

''' <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 
+0

请参阅更新2请 – Natalia

+0

@Natalia:我唯一能想到的是该应用程序未按照您认为的那样运行,因此无法获取映射的驱动器。您可以通过添加以下代码来查看exe的运行方式:Debug.WriteLine(System.Security.Principal.WindowsIdentity.GetCurrent()。Name) –

+0

我编写了该代码行,并且运行该应用程序的用户是我的用户。此用户是管理员。我认为这不是问题。 – Natalia

5
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)); 

编辑:

我看到你的第二个编辑和唯一的区别(在我的Windows7)时,我认为一个网络驱动器,我看到电脑>图片(\\ xyzServer)。你的电脑的名字是Equipo西班牙队是吗?是你的电脑吗?我试图重现你的问题,但它为我的作品:

enter image description here

+0

请参阅更新2请 – Natalia

+0

是的,我的电脑名称是“Equipo”,我来自阿根廷。我不知道为什么我的Visual Studio无法识别我的Windows 7上的网络驱动器。这个问题让我疯狂。 – Natalia

1

此外,我需要对可能列出的网络共享执行'Exists'检查,但该帐户没有访问权限,因此Directory.Exists将返回False。

张贴我没有工作,所以这里的各种解决方案是我自己:

public static bool DirectoryVisible(string path) 
{ 
    try 
    { 
     Directory.GetAccessControl(path); 
     return true; 
    } 
    catch (UnauthorizedAccessException) 
    { 
     return true; 
    } 
    catch 
    { 
     return false; 
    } 
} 
相关问题