Comment vérifier (rapidement) si un chemin UNC est disponible
Comment puis-je vérifier si un chemin UNC est disponible? J'ai le problème que la vérification prend environ une demi-minute, si l'action est pas :
var fi = new DirectoryInfo(@"hostnamesamba-sharenamedirectory");
if (fi.Exists)
//...
Est-il un moyen plus rapide pour vérifier si un dossier est disponible? Je suis sous Windows XP et C#.
6 réponses
Comment est - ce pour un moyen rapide et sale de vérifier-exécuter la commande de windows net use
et analyser la sortie pour la ligne avec le chemin du réseau d'intérêt (par exemple \vault2
) et OK
. Voici un exemple de la sortie:
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.
ce n'est pas un très .netish solution, mais il est très rapide, et parfois que les questions les plus :-).
et voici le code pour le faire (et LINQPad me dit qu'il ne faut que 150ms , donc c'est sympa)
void Main()
{
bool available = QuickBestGuessAboutAccessibilityOfPath(@"\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;
}
Ou vous pourriez probablement suivre la voie de l'utilisation de WMI , comme mentionné dans cette réponse à Comment assurer les lecteurs réseau sont connectés à une application?
dans mon projet, j'utilise le système.IO:
if (Directory.Exists(@"\hostname\samba-sharename\directory")) { ...
et c'est assez rapide pour l'instant...
dans un de mes projets, je devais vérifier si une connexion serveur était établie ou non. J'ai utilisé un TCP Socket pour vérifier asynchrone si le serveur pouvait être atteint ou non. Je me demande si vous pourriez utiliser ceci pour vérifier un partage de réseau. La connexion async TCP Socket connect va si vite que j'ai testé la connexion 10 fois en moins de 60 millisecondes. Tu pourrais peut-être t'amuser un peu avec ça ?
modifier: voici le Socket asynchrone que j'ai utilisé pour mon projet. Utilisez cette classe pour vérifier certaines IP ou l'adresse. J'espère qu'il vous sera utile
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
}
}
Edit: s'il vous Plaît ne pas simplement copier/coller. Essayez de comprendre le code afin que vous puissiez l'utiliser à votre avantage, et le finetune pour vos besoins.
Thats probablement la voie la plus rapide, le retard sera la vitesse générale du réseau/accès au disque, etc.
si cela provoque un retard pour l'utilisateur, vous pouvez essayer de vérifier cette asynchrone?
j'ai utilisé la méthode ping suggérée ci-dessus et cela n'a pas fonctionné pour moi puisque J'utilise OpenDNS Voici une fonction qui a bien fonctionné pour moi:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// <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);
}
peut-être que vous devriez essayer de créer le dossier, s'il existe, il retournera une erreur que vous pourriez attraper. Il ne devrait pas y avoir de délai par défaut.