C# 检查网络驱动器上是否存在目录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17472168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check if directory exists on Network Drive
提问by Natalia
I'm trying to detect if the directory exists, but in this particular situation my directory is a network location.
I used VB.NET's My.Computer.FileSystem.DirectoryExists(PATH)and the more general System.IO.Directory.Exists(PATH), and in both cases, the system response is false.
I checked and the PATH exists, I can view it in MyComputer Folder.
If I debug the program, and watch the My.Computer.FileSystem.Drivesvariable, the network location does not appear in that list.
我试图检测目录是否存在,但在这种特殊情况下,我的目录是一个网络位置。我使用了 VB.NETMy.Computer.FileSystem.DirectoryExists(PATH)和更一般的System.IO.Directory.Exists(PATH),在这两种情况下,系统响应都是错误的。我检查过路径存在,我可以在 MyComputer 文件夹中查看它。如果我调试程序并观察My.Computer.FileSystem.Drives变量,则网络位置不会出现在该列表中。
UPDATE:I checked and in Windows XP the Response is True, but not in Windows 7.
更新:我检查过,在 Windows XP 中,响应为 True,但在 Windows 7 中不是。
UPDATE2:I tested both proposed solutions but I still have the same problem, on the image below you will see that I can access using Explorer but my program cannot.
The GetUNCPathfunction returns a valid path (no errors), but Directory.Existsstil returns false.
UPDATE2:我测试了两个提议的解决方案,但我仍然遇到同样的问题,在下图中您会看到我可以使用资源管理器访问,但我的程序不能。该GetUNCPath函数返回有效路径(无错误),但Directory.Existsstil 返回 false。
I also tried with the UNC path "\\Server\Images"; same result.
我也尝试过使用 UNC 路径“\\Server\Images”;同样的结果。


UPDATE3:If I cannot link with a network drive, how can I link to UNC path directly?. I discovered that if i run VS in normal mode, it works, but my software must run in administrator mode. So, there is any way to check the existence of a network directory as administrator?
UPDATE3:如果我无法与网络驱动器链接,我如何直接链接到 UNC 路径?。我发现如果我在正常模式下运行 VS,它可以工作,但我的软件必须在管理员模式下运行。那么,有什么方法可以以管理员身份检查网络目录的存在吗?
采纳答案by Martin Binder
If UAC is turned on, mapped network drives only exist "by default" in the session they are mapped: Normal or elevated. If you map a network drive from explorer, then run VS as admin, the drive will not be there.
如果 UAC 已打开,则映射的网络驱动器仅“默认”存在于它们所映射的会话中:正常或提升。如果您从资源管理器映射网络驱动器,然后以管理员身份运行 VS,该驱动器将不存在。
You need to enable what MS calls "linked connections": HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System: EnableLinkedConnections (REG_DWORD) = 0x1
您需要启用 MS 所谓的“链接连接”:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System: EnableLinkedConnections (REG_DWORD) = 0x1
Background Information about "two logon sessions" with UAC: http://support.microsoft.com/kb/937624/en-us
关于 UAC 的“两次登录会话”的背景信息:http: //support.microsoft.com/kb/937624/en-us
回答by competent_tech
When you use System.IO.Directory.Exists, it only lets you know that it couldn't find the directory, but this could be because the directory doesn't actually exist or because the user doesn't have sufficient access rights to the directory.
当您使用 时System.IO.Directory.Exists,它只会让您知道它找不到该目录,但这可能是因为该目录实际上并不存在,或者因为用户对该目录没有足够的访问权限。
In order to resolve this, we add a secondary test after Directory.Existsfails to obtain the real reason for the directory's absence and we have wrapped this into a global method that is used in place of the standard Directory.Existsmethod:
为了解决这个问题,我们在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
回答by Jeremy Thompson
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;
}
}
To use it, pass in a Network folder path, convert to UNC folder path and see if the folder exists:
要使用它,请传入网络文件夹路径,转换为 UNC 文件夹路径并查看文件夹是否存在:
File.Exists(MappedDriveResolver.GetUNCPath(filePath));
Edit:
编辑:
I saw your second edit and the only difference (in my Windows7) when I view a network drive I see Computer > Images (\\xyzServer). Is your PC's name Equipo? is that teamin spanish? is that your PC? I tried to reproduce your problem but it works for me:
当我查看网络驱动器时,我看到了您的第二次编辑和唯一的区别(在我的 Windows7 中),我看到了Computer > Images (\\xyzServer)。是你电脑的名字Equipo吗?那个团队是西班牙语的吗?那是你的电脑吗?我试图重现您的问题,但它对我有用:


回答by WhoIsRich
Adding to this, I needed to do an 'Exists' check on network shares that could listed, but the account did not have permission to access, so Directory.Exists would return False.
除此之外,我需要对可以列出的网络共享进行“存在”检查,但该帐户没有访问权限,因此 Directory.Exists 将返回 False。
Various solutions posted did not work for me, so here is my own:
发布的各种解决方案对我不起作用,所以这是我自己的:
public static bool DirectoryVisible(string path)
{
try
{
Directory.GetAccessControl(path);
return true;
}
catch (UnauthorizedAccessException)
{
return true;
}
catch
{
return false;
}
}

