45

UNCパスが使用可能かどうかを確認するにはどうすればよいですか?共有が利用できない場合、チェックに約30分かかるという問題があります。

var fi = new DirectoryInfo(@"\\hostname\samba-sharename\directory");

if (fi.Exists)
//...

フォルダが利用可能かどうかを確認するためのより速い方法はありますか?私はWindowsXPとC#を使用しています。

4

7 に答える 7

26

これをすばやく汚い方法で確認するにはどうすればよいですか?windowsnet useコマンドを実行し、対象のネットワークパス(例\\vault2)とを含む行の出力を解析しますOK。出力の例を次に示します。

C:\>net use
New connections will be remembered.

Status       Local     Remote                    Network

-------------------------------------------------------------------------------
OK           O:        \\smarty\Data       Microsoft Windows Network
Disconnected P:        \\dummy\Data       Microsoft Windows Network
OK                     \\vault2\vault2           Microsoft Windows Network
The command completed successfully.

これはあまり.netishの解決策ではありませんが、非常に高速であり、時にはそれがより重要になります:-)。

そして、これを行うためのコードがあります(そして、LINQPadは、150ミリ秒しかかからないと言っているので、それは素晴らしいことです)

void Main()
{
    bool available = QuickBestGuessAboutAccessibilityOfNetworkPath(@"\\vault2\vault2\dir1\dir2");
    Console.WriteLine(available);
}

public static bool QuickBestGuessAboutAccessibilityOfNetworkPath(string path)
{
    if (string.IsNullOrEmpty(path)) return false;
    string pathRoot = Path.GetPathRoot(path);
    if (string.IsNullOrEmpty(pathRoot)) return false;
    ProcessStartInfo pinfo = new ProcessStartInfo("net", "use");
    pinfo.CreateNoWindow = true;
    pinfo.RedirectStandardOutput = true;
    pinfo.UseShellExecute = false;
    string output;
    using (Process p = Process.Start(pinfo)) {
        output = p.StandardOutput.ReadToEnd();
    }
    foreach (string line in output.Split('\n'))
    {
        if (line.Contains(pathRoot) && line.Contains("OK"))
        {
            return true; // shareIsProbablyConnected
        }
    }
    return false;
}

または、ネットワークドライブがアプリケーションに接続されていることを確認する方法のこの回答で示唆されているように、おそらくWMIを使用するルートに進むことができますか?

于 2012-08-02T23:50:14.447 に答える
13

私のプロジェクトでは、System.IOを使用しています。

if (Directory.Exists(@"\\hostname\samba-sharename\directory")) { ...

これまでのところかなり速いです...

于 2016-09-28T08:28:00.510 に答える
5

私のプロジェクトでは、サーバー接続が確立されているかどうかを確認する必要がありました。TCPソケットを使用して、サーバーに到達できるかどうかを非同期的にチェックしました。これを使ってネットワーク共有をチェックしていただけませんか。非同期TCPソケット接続は非常に高速で、60ミリ秒未満で10回接続をテストしました。多分あなたはそれで少し遊ぶことができますか?


編集:これが私のプロジェクトに使用した非同期ソケットです。このクラスを使用して、特定のIPまたはアドレスを確認します。それがあなたに役立つことを願っています

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace Base.BaseObjects
{
    public class AsynchronousClient
    {
        #region Properties

        private int _port = 0000, currentTry = 0, _buffersize, _fastpingdelay = 80;
        private string _server = "localhost";
        private Socket client;
        private static IPEndPoint remoteEP;

        // Delegates & Events
        public delegate void SendMessageDelegate(string message);
        public event SendMessageDelegate SendMessageEvent;
        public delegate void ConnectionStatusDelegate(bool connected, bool reconnect);
        public event ConnectionStatusDelegate ConnectionStatusChanged;

        // ManualResetEvent instances signal completion.
        private static ManualResetEvent connectDone = new ManualResetEvent(false);
        private static ManualResetEvent sendDone = new ManualResetEvent(false);
        private static ManualResetEvent receiveDone = new ManualResetEvent(false);

        /// <summary>
        /// Port to monitor
        /// </summary>
        public int Port { get { return _port; } }

        /// <summary>
        /// Number of packages to buffer until system reports connection loss
        /// </summary>
        public int BufferSize { get { return _buffersize; }  }

        /// <summary>
        /// Time in milliseconds between two pings
        /// </summary>
        public int FastPingDelay { get { return _fastpingdelay; } }

        /// <summary>
        /// Servername to connect to
        /// </summary>
        public string Server
        {
            get { return _server; }
            set
            {
                _server = value;
                // Resolve the remote endpoint for the socket.
                try
                {
                    IPAddress ipAddress = (IPAddress)Dns.GetHostAddresses(value)[0];
                    remoteEP = new IPEndPoint(ipAddress, Port);
                }
                catch (SocketException ex)
                {
                    SendMessage(ex.Message);
                }
            }
        }

        #endregion

        #region Events & Delegates

        protected void SendMessage(string message)
        {
            if (SendMessageEvent != null)
                SendMessageEvent(message);
        }

        protected void UpdateConnectionStatus(bool connected, bool reconnect)
        {
            if (ConnectionStatusChanged != null)
                ConnectionStatusChanged(connected, reconnect);
        }

        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket client = (Socket)ar.AsyncState;

                // Complete the connection.
                client.EndConnect(ar);

                SendMessage(String.Format("Socket connected to {0}", client.RemoteEndPoint.ToString()));
                //UpdateConnectionStatus(true, false);

                // Signal that the connection has been made.
                connectDone.Set();
            }
            catch (Exception e)
            {
                SendMessage(e.ToString());
                UpdateConnectionStatus(false, true);
            }
        }

        #endregion

        #region methods

        public AsynchronousClient(int port, string server)
        {
            _port = port;
            Server = server;
            _buffersize = 10;
            _fastpingdelay = 20;
        }

        public void CreateSocket()
        {
            try
            {
                StopClient();
            }
            catch (Exception ex)
            {
                SendMessage(ex.Message);
            }
            finally
            {
                client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            }
        }

        public bool FastPingSocket()
        {
            for (currentTry = 0; currentTry <= BufferSize; currentTry++)
            {
                try
                {
                    CreateSocket();
                    client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
                    connectDone.WaitOne();
                    System.Threading.Thread.Sleep(FastPingDelay);
                    client.Shutdown(SocketShutdown.Receive);
                    connectDone.WaitOne();
                    client.Close();
                    return true;
                }
                catch (SocketException ex)
                {
                    SendMessage(ex.Message);
                }
                catch (ObjectDisposedException ex)
                {
                    currentTry--;
                    SendMessage(ex.Message);
                    CreateSocket();
                }
                catch (NullReferenceException ex)
                {
                    currentTry--;
                    SendMessage(ex.Message);
                    CreateSocket();
                }
                catch (ArgumentNullException ex)
                {
                    SendMessage(ex.Message);
                    CreateSocket();
                }
                catch (InvalidOperationException ex)
                {
                    SendMessage(ex.Message);
                    CreateSocket();
                    currentTry--;
                }
                finally
                {
                    StopClient();
                }
            }
            UpdateConnectionStatus(false, true);
            return false;
        }

        public void StopClient()
        {
            // Release the socket.
            try
            {
                client.Shutdown(SocketShutdown.Both);
                client.Close();
            }
            catch (Exception) { }
            finally
            {
                UpdateConnectionStatus(false, false);
            }
        }

        #endregion

    }
}

編集:単にコピー/貼り付けしないでください。コードを理解して、利益のために使用できるようにし、ニーズに合わせて微調整してください。

于 2011-03-01T10:17:33.727 に答える
4

私は結局「浮気」し、ホストにpingを送信するだけでした。これは、実際には私がチェックしているケースであるため、合理的です。

private bool HostExists(string PCName)
{
    Ping pinger = new Ping();

    try
    {
        PingReply reply = pinger.Send(PCName);
        return reply.Status == IPStatus.Success;
    }
    catch
    {
        return false;
    }
    finally
    {
        pinger.Dispose();
    }

}

この方法は、その速度、単純さ、および信頼性のために私に最も適しています。

于 2018-12-13T22:32:23.270 に答える
3

上記で提案したping方法を使用しましたが、OpenDNSを使用しているため、機能しませんでした。これが私にとってうまく機能した関数です。

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// <summary>
/// A quick method to test is the path exists 
/// </summary>
/// <param name="s"></param>
/// <param name="timeOutMs"></param>
/// <returns></returns>
public static bool CheckPathExists(string s, int timeOutMs = 120) {
    if (s.StartsWith(@"\\")) {
        Uri uri = new Uri(s);
        if (uri.Segments.Length == 0 || string.IsNullOrWhiteSpace(uri.Host))
            return false;
        if (uri.Host != Dns.GetHostName()) {
            WebRequest request;
            WebResponse response;
            request = WebRequest.Create(uri);
            request.Method = "HEAD";
            request.Timeout = timeOutMs;
            try {
                response = request.GetResponse();
            } catch (Exception ex) {
                return false;
            }
            return response.ContentLength > 0;

            // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
            // Do a Ping to see if the server is there
            // This method doesn't work well using OPenDNS since it always succeeds
            // regardless if the IP is a valid or not
            // OpenDns always maps every host to an IP. If the host is not valid the 
            // OpenDNS will map it to 67.215.65.132
            /* Example:
                C:\>ping xxx

                Pinging xxx.RT-AC66R [67.215.65.132] with 32 bytes of data:
                Reply from 67.215.65.132: bytes=32 time=24ms TTL=55
                */

            //Ping pingSender = new Ping();
            //PingOptions options = new PingOptions();
            // Use the default Ttl value which is 128,
            // but change the fragmentation behavior.
            //options.DontFragment = true;

            // Create a buffer of 32 bytes of data to be transmitted.
            //string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            //byte[] buffer = Encoding.ASCII.GetBytes(data);
            //int timeout = 120;
            //PingReply reply = pingSender.Send(uri.Host, timeout, buffer, options);
            //if (reply == null || reply.Status != IPStatus.Success)
            //    return false;
        }
    }
    return File.Exists(s);
}
于 2013-12-12T21:18:42.077 に答える
2

それがおそらく最も速い方法です。遅延は一般的なネットワーク速度/ディスクアクセスなどになります。

これがユーザーに遅延を引き起こしている場合は、これを非同期でチェックしてみてください。

于 2011-03-01T09:49:33.977 に答える
0

たぶんあなたはフォルダを作成しようとするべきです、もしそれが存在するなら、それはあなたが捕まえることができるエラーを返します。デフォルトのタイムアウトはありません。

于 2011-03-01T10:15:36.580 に答える