先贴下代码,后续写一些分析,和遇到的问题。
private static string ProcessErrorReadToEnd(Process p) { string errorString = string.Empty; try { if (p!=null && p.HasExited && p.ExitCode == 2) { errorString = p.StandardError.ReadToEnd(); } } // catch exception and return empty string, no need to throw exception outside this function. catch (Exception ex) { ConsoleLog.Debug(msg => msg("[ProcessErrorReadToEnd] Error: "+ ex.StackTrace)); } return errorString; }
public static RemoteShareConnectionAttempt TestShare(string path, string username, string password) { //TODO: what happens if the remote computer rebooted since we set this up? * // we'll need a way to "ping" the share and reconnect if( path == null ) { ConsoleLog.Debug(msg => msg("path is null")); throw new System.ArgumentNullException("path"); } if( username == null ) { ConsoleLog.Debug(msg => msg("username is null")); throw new System.ArgumentNullException("username"); } if( password == null ) { ConsoleLog.Debug(msg => msg("password is null")); throw new System.ArgumentNullException("password"); } #if Windows try { string args = "use "; if (path.Length != 0) { args += """ + path + "" "; if (username.Length == 0) { //[D-01392] //Windows does not let user to connect a share without a username.. //But if you connect once, it caches the username so you can connect without name.; args += ""/USER:anonymous""; } else { if (password.Length != 0) args += """ + password + "" "; args += ""/USER:" + username + """; } } else { return RemoteShareConnectionAttempt.FAILED; } //use the Windows/DOS "net" command to connect ProcessStartInfo procInfo = new ProcessStartInfo("net ", args); procInfo.UseShellExecute = false; procInfo.RedirectStandardError = true; procInfo.RedirectStandardOutput = true; procInfo.ErrorDialog = false; procInfo.WindowStyle = ProcessWindowStyle.Hidden; Process p = Process.Start(procInfo); //Give it 90s to connect p.WaitForExit(90000); ExtendedDirectoryInfo extendedDirectoryInfo = new ExtendedDirectoryInfo(path); if (extendedDirectoryInfo.Exists) { Core.CoreLog.Info("STR_SHARE_CONNECTED", 0, path, username); return RemoteShareConnectionAttempt.CONNECTED; } if (p.HasExited) { string errorString = ProcessErrorReadToEnd(p); Core.CoreLog.Error("STR_SHARE_CONNECT_FAILED", 0, path, username, p.ExitCode); //if p.HasExited is true and p.ExitCode is 0, it means that the user can logon the server but the folder path is inaccessible or not existing. //if exitcode is 2 and System error 1920 has occurred.It means the file cannot be accessed by the system. //if exitcode is 2 and "System error 53 has occurred.It means the network path was not found. if (p.ExitCode == 0 || (p.ExitCode == 2 && (errorString.Contains("System error 67") || errorString.Contains("System error 1920") || errorString.Contains("System error 53")))) { return RemoteShareConnectionAttempt.FAILED_INACCESSIBLE_SHARE; } if (p.ExitCode == 2 && (errorString.Contains("System error 1219") || string.IsNullOrEmpty(errorString))) { RemoveShareFromWindows(path); return RepeatTestShare(path, username, password); } return RemoteShareConnectionAttempt.FAILED; } p.Kill(); p = null; Core.CoreLog.Error("STR_SHARE_CONNECT_FAILED", 0, path, username, -2); return RemoteShareConnectionAttempt.FAILED; } catch (Exception ex) { if (!Core.Closing) { Core.CoreLog.Exception(ex, 0); Core.CoreLog.Error("STR_SHARE_CONNECT_FAILED", 0, path, username, -2); } return RemoteShareConnectionAttempt.FAILED; } #else throw new NotImplementedException("_shareName"); #endif }