如何檢查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