如何检查UNC路径是否可用? 我有检查过程约半分钟,如果份额不可用的问题:如何(快速)检查UNC路径是否可用
var fi = new DirectoryInfo(@"\\hostname\samba-sharename\directory");
if (fi.Exists)
//...
是否有检查,如果一个文件夹可用更快的方法? 我正在使用Windows XP和C#。
如何检查UNC路径是否可用? 我有检查过程约半分钟,如果份额不可用的问题:如何(快速)检查UNC路径是否可用
var fi = new DirectoryInfo(@"\\hostname\samba-sharename\directory");
if (fi.Exists)
//...
是否有检查,如果一个文件夹可用更快的方法? 我正在使用Windows XP和C#。
这是如何快速和肮脏的方式来检查 - 运行Windows net 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.
这不是一个非常.net解决方案,但它非常快,有时更重要:-)。
而这里的代码来做到这一点(和LINQPad告诉我,只需要150毫秒,所以这是很好的)
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;
}
或者你可能会去使用WMI的路线,如提到的this answer到How to ensure network drives are connected for an application?
很酷的东西,谢谢! – thumbmunkeys 2012-08-08 07:27:21
如果路径中包含'OK',可能应将'line.contains(“OK”)''改为'line.StartsWith(“OK”)' – sparkplug 2015-11-02 10:01:37
那可能是最快的方式,延迟将是一般的网络速度/磁盘访问等
如果这是造成的延迟对于用户来说,你可以尝试检查这个异步?
我可以使它异步,但用户仍然需要等待半分钟的文件。 – thumbmunkeys 2011-03-01 10:08:47
如果您在资源管理器中导航到相同的UNC路径,您是否仍然看到相同的延迟? – 2011-03-01 10:39:40
@Mark:是的,它的延迟时间相同,这说明在访问不存在的samba共享时,win xp似乎有一个巨大的超时。当浏览器GUI尝试访问共享时(这真的很糟糕),它也挂起半分钟。 – thumbmunkeys 2011-03-01 16:22:37
也许你应该尝试创建文件夹,如果它确实存在,它会返回一个你可以捕获的错误。应该没有默认超时。
我试过了,如果共享不可用,创建一个文件夹具有相同的超长超时(如果不是这样的话,它会令人惊讶) – thumbmunkeys 2011-03-01 10:21:34
在我的项目中,我不得不检查服务器连接是否建立。我使用了TCP套接字来异步检查是否可以访问服务器。我想知道你是否可以用它来检查网络共享。异步TCP套接字连接变得如此之快,我测试了连接10次60毫秒以下。也许你可以玩一下这一点?
编辑:这里是异步套接字,我用我的项目。使用此类来检查某个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
}
}
编辑:请不要只是复制/粘贴。尝试理解代码,以便您可以使用它,并根据需要对其进行微调。
感谢您的建议,我将检查主机是否可访问,如果是,那么尝试访问该共享。 – thumbmunkeys 2011-03-01 10:24:25
我用平以上方法建议,因为我现在用的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);
}
在项目中,我使用System.IO:
if (Directory.Exists(@"\\hostname\samba-sharename\directory")) { ...
,它是相当快到目前为止...
当共享不可用时,您是否尝试过? – thumbmunkeys 2016-09-28 10:06:23
是的,这是为了测试是否存在...也许有一种时间从网络管理员设置时,不可用,这就是为什么你必须等待30秒..? – fasa 2016-09-28 10:13:47
知道给定文件夹是否可用的唯一方法是尝试使用它 - 任何其他检查可能会给出误报 – 2011-03-01 09:34:30
我同意,这是最快的方法。它需要很长的时间并不是由无效代码引起的,而是服务器的磁盘访问时间。 – 2011-03-01 09:37:29
@Johnny:当共享不可访问时(因此服务器无法访问),我有延迟,并且它很长,就像半分钟。 – thumbmunkeys 2011-03-01 09:40:09