Domanda

I want to quickly check if a file share is available in C#, but without knowing anything about the directories that might be on the network share. I have found these posts 1 2 3 that show how to check if a network directory is available, but they all assume I know the directory share that I want to check if exists. That is, they want to check if \\SomeServer\SomeDirectory is available, but I just want to check if \\SomeServer is available.

For a little more detail about what I'm trying to do, I prompt the user for a SQL server to connect to, and they give me an address such as "SQL001"; obviously this address is only valid when on our internal network. With this address I'm able to connect to the server and its databases. Now, I give them the option to backup a database, and want the OpenFileDialog to have the InitialDirectory set to "\\SQL001" so they can quickly access a shared folder on that server and back the database up on the remote server.

If I set "\\SQL001" as the OpenFileDialog's InitialDirectory, everything works fine, however if they mistyped and put "\\SQL002" (which doesn't exist), or maybe try and use the tool when off the internal network, then the OpenFileDialog's ShowDialog function throws an error. So I want to check and make sure that the file share is available first, and if not I won't set the InitialDirectory.

Using Directory.Exists("\\SQL001") always returns false unfortunately. If I do Directory.Exists("\\SQL001\Backups") it works, but we have many different SQL servers and they don't all have a share called "Backups", so that is not reliable. I can also use Directory.Exists("\\SQL001\c$\") which works for me, but many employees will not have permissions to the root C:\, but will have permissions for the network shares, so that is not a good alternative either.

So my question is, assuming the user has permissions to a file share, how can I check that the file share is available? Also, I don't want to force the user to map "\\SQL001" as a network drive either.

The only solution I can see right now is to just call the OpenFileDialog's ShowDialog function and catch the specific exception, wipe out the InitialDirectory and then call ShowDialog again. It'll work, but feels a bit hacky, so I'm hoping for a better solution.

È stato utile?

Soluzione 2

Based on Allan Elder's response I came up with the following solution that seems to work. I used System.Net.Dns.GetHostEntry() instead of GetHostByName though, as GetHostByName is now deprecated.

/// <summary>
/// Gets the rooted path to use to access the host.
/// Returns an empty string if the server is unavailable.
/// </summary>
/// <param name="serverName">The server to connect to.</param>
public static string GetNetworkPathFromServerName(string serverName)
{
    // Assume we can't connect to the server to start with.
    var networkPath = String.Empty;

    // If this is a rooted path, just make sure it is available.
    if (Path.IsPathRooted(serverName))
    {
        // If the path exists, use it.
        if (Directory.Exists(serverName))
            networkPath = serverName;
    }
        // Else this is a network path.
    else
    {
        // If the server name has a backslash in it, remove the backslash and everything after it.
        serverName = serverName.Trim(@"\".ToCharArray());
        if (serverName.Contains(@"\"))
            serverName = serverName.Remove(serverName.IndexOf(@"\", StringComparison.Ordinal));

        try
        {
            // If the server is available, format the network path properly to use it.
            if (Dns.GetHostEntry(serverName) != null)
            {
                // Root the path as a network path (i.e. add \\ to the front of it).
                networkPath = String.Format("\\\\{0}", serverName);
            }
        }
        // Eat any Host Not Found exceptions for if we can't connect to the server.
        catch (System.Net.Sockets.SocketException)
        { }
    }

    return networkPath;
}

Altri suggerimenti

A valid UNC path must contain a minimum of two components; the \SERVERNAME\SHARE; Directory.Exists will return false if that condition isn't met.

To determine if the machine that is identified by SERVERNAME exists, you could use GetHostByName

http://msdn.microsoft.com/en-us/library/system.net.dns.gethostbyname.aspx

That still won't tell you if the machine is down, though.

If you intend to use Windows file sharing after you check server availability, the effective method is to open a socket to NetBIOS port (139) which is used for file sharing service. This will tell you not only whether server is online, but whether it is available for file operations. Complete .net source code is here.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top