/// <summary> /// Gets the client settings. /// </summary> /// <returns></returns> public static SourceControlSettings GetSettings() { SourceControlSettings settings = new SourceControlSettings(); settings.Port = Environment.GetEnvironmentVariable("SVNURL"); string path = Environment.GetEnvironmentVariable("path").Replace("\"", ""); string[] pathArray = path.Split(';'); for (int i = 0; i < pathArray.Length; ++i) { string svn = Path.Combine(pathArray[i], "svn.exe"); if (File.Exists(svn)) { settings.ClientExe = svn; break; } } // get override settings from svn info output // Example: // D:\projects\Malevich\Malevich>svn info // Path: . // URL: https://malevich.svn.codeplex.com/svn/Malevich // Repository Root: https://malevich.svn.codeplex.com/svn // Repository UUID: 8ead0314-7f71-49e1-95c8-3147638646d4 // Revision: 40756 // Node Kind: directory // Schedule: normal // Last Changed Author: unknown // Last Changed Rev: 35869 // Last Changed Date: 2010-01-10 23:37:13 -0800 (Sun, 10 Jan 2010) if (settings.ClientExe != null) { Regex portRegex = new Regex(@"^(\s)*Repository Root(\s)*:(\s)*(?<url>(\S)*)(\s)*$", RegexOptions.ExplicitCapture); Regex urlRegEx = new Regex(@"^(\s)*URL(\s)*:(\s)*(?<url>(\S)*)(\s)*$", RegexOptions.ExplicitCapture); ProcessReader procReader = new ProcessReader(LogOptions.None); string svnInfo = procReader.RunExecutable(settings.ClientExe, false, "info"); string url = null; if (svnInfo != null) { StringReader sr = new StringReader(svnInfo); while (settings.Port == null || url == null) { string l = sr.ReadLine(); if (l == null) break; if (settings.Port == null) { Match portMatch = portRegex.Match(l); if (portMatch.Success) { settings.Port = portMatch.Groups[1].Value; } } Match urlMatch = urlRegEx.Match(l); if (urlMatch.Success) { url = urlMatch.Groups[1].Value; } } } // the client is unused in Subversion, so generate our from the computer name string localRoot = GetLocalRootDirectory(url); if (localRoot != null) { settings.Client = Environment.GetEnvironmentVariable("COMPUTERNAME") + "-" + localRoot; } } return settings; }
/// <summary> /// Gets the source depot settings. /// </summary> /// <returns></returns> public static SourceControlSettings GetSettings() { SourceControlSettings settings = new SourceControlSettings(); settings.Port = Environment.GetEnvironmentVariable("SDPORT"); if (settings.Port != null) settings.Port = settings.Port.Trim(); settings.Proxy = Environment.GetEnvironmentVariable("SDPROXY"); if (settings.Proxy != null) settings.Proxy = settings.Proxy.Trim(); settings.Client = Environment.GetEnvironmentVariable("SDCLIENT"); if (settings.Client != null) settings.Client = settings.Client.Trim(); string path = Environment.GetEnvironmentVariable("path").Replace("\"", ""); string[] pathArray = path.Split(';'); for (int i = 0; i < pathArray.Length; ++i) { string sd = Path.Combine(pathArray[i], "sd.exe"); if (File.Exists(sd)) { settings.ClientExe = sd; break; } } string dir = Directory.GetCurrentDirectory(); string root = Path.GetPathRoot(dir); while (!dir.Equals(root)) { string sd = Path.Combine(dir, "sd.ini"); if (File.Exists(sd)) { Regex portRegex = new Regex(@"^(\s)*SDPORT(\s)*=(\s)*(?<port>(\S)*)(\s)*$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); Regex proxyRegex = new Regex(@"^(\s)*SDPROXY(\s)*=(\s)*(?<port>(\S)*)(\s)*$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); Regex clientRegex = new Regex(@"^(\s)*SDCLIENT(\s)*=(\s)*(?<client>(\S)*)(\s)*$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); StreamReader sr = new StreamReader(sd); while (settings.Port == null || settings.Client == null || settings.Proxy == null) { string l = sr.ReadLine(); if (l == null) break; if (settings.Proxy == null) { Match proxyMatch = proxyRegex.Match(l); if (proxyMatch.Success) { settings.Proxy = proxyMatch.Groups[1].Value; continue; } } if (settings.Port == null) { Match portMatch = portRegex.Match(l); if (portMatch.Success) { settings.Port = portMatch.Groups[1].Value; continue; } } if (settings.Client == null) { Match clientMatch = clientRegex.Match(l); if (clientMatch.Success) { settings.Client = clientMatch.Groups[1].Value; continue; } } } sr.Close(); break; } dir = Path.GetDirectoryName(dir); } return settings; }
/// <summary> /// The main function. Parses arguments, and if there is enough information, calls ProcessCodeReview. /// </summary> /// <param name="args"> Arguments passed by the system. </param> static void Main(string[] args) { if (args.Length == 0) { DisplayHelp(); return; } // First, rummage through the environment, path, and the directories trying to detect the source // control system. string sourceControlInstance = Environment.GetEnvironmentVariable("REVIEW_INSTANCE"); SourceControlSettings sdSettings = SourceDepotInterface.GetSettings(); SourceControlSettings p4Settings = PerforceInterface.GetSettings(); SourceControlSettings tfsSettings = SourceControl.Tfs.Factory.GetSettings(); SourceControlSettings svnSettings = SubversionInterface.GetSettings(); string databaseServer = Environment.GetEnvironmentVariable("REVIEW_DATABASE"); string command = null; // Now go through the command line to get other options. string link = null; string linkDescr = null; string description = null; bool force = false; bool admin = false; string changeId = null; string newChangeId = null; bool includeBranchedFiles = false; List<string> reviewers = new List<string>(); List<string> invitees = new List<string>(); SourceControl.SourceControlType? sourceControlType = null; SourceControlSettings settings = new SourceControlSettings(); string impersonatedUserName = null; List<string> bugIds = new List<string>(); bool verbose = false; bool preview = false; for (int i = 0; i < args.Length; ++i) { if (i < args.Length - 1) { if (args[i].EqualsIgnoreCase("--sourcecontrol")) { if ("TFS".EqualsIgnoreCase(args[i + 1])) { sourceControlType = SourceControl.SourceControlType.TFS; } else if ("P4".EqualsIgnoreCase(args[i + 1])) { sourceControlType = SourceControl.SourceControlType.PERFORCE; } else if ("SD".EqualsIgnoreCase(args[i + 1])) { sourceControlType = SourceControl.SourceControlType.SD; } else if ("SVN".EqualsIgnoreCase(args[i + 1])) { sourceControlType = SourceControl.SourceControlType.SUBVERSION; } else { Console.WriteLine("error : source control '{0}' is not supported.", args[i + 1]); return; } ++i; continue; } if (args[i].EqualsIgnoreCase("--port")) { settings.Port = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--server")) { settings.Port = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--client")) { settings.Client = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--workspace")) { settings.Client = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--tfsdiffsource")) { string diff = args[i + 1]; if (diff.EqualsIgnoreCase("local")) { settings.Diff = SourceControlSettings.DiffSource.Local; } else if (diff.EqualsIgnoreCase("shelf")) { settings.Diff = SourceControlSettings.DiffSource.Server; } else { Console.WriteLine( "error : unrecognized value of TFS diff source. Should be either shelf or local."); return; } ++i; continue; } if (args[i].EqualsIgnoreCase("--user")) { settings.User = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--password")) { settings.Password = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--clientexe")) { settings.ClientExe = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--database")) { databaseServer = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--instance")) { sourceControlInstance = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--invite")) { if (!AddReviewers(invitees, args[i + 1])) return; ++i; continue; } if (args[i].EqualsIgnoreCase("--link")) { link = args[i + 1]; ++i; if (!(link.StartsWith(@"file://\\") || link.StartsWith("http://") || link.StartsWith("https://"))) { Console.WriteLine("error : incorrect link specification : should start with http://, https://, or " + "file://. If the latter is used, the supplied file name should be UNC."); return; } continue; } if (args[i].EqualsIgnoreCase("--linkdescr")) { linkDescr = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--description")) { description = args[i + 1]; ++i; continue; } if (args[i].EqualsIgnoreCase("--impersonate")) { impersonatedUserName = args[++i]; continue; } if (args[i].EqualsIgnoreCase("--bugid")) { bugIds.Add(args[++i]); continue; } } if (args[i].EqualsIgnoreCase("--force")) { force = true; continue; } if (args[i].EqualsIgnoreCase("--admin")) { admin = true; continue; } if (args[i].EqualsIgnoreCase("--includebranchedfiles")) { includeBranchedFiles = true; continue; } if (args[i].EqualsIgnoreCase("--verbose")) { verbose = true; continue; } if (args[i].EqualsIgnoreCase("--preview")) { preview = true; continue; } if (args[i].EqualsIgnoreCase("help") || args[i].EqualsIgnoreCase("/help") || args[i].EqualsIgnoreCase("--help") || args[i].EqualsIgnoreCase("-help") || args[i].EqualsIgnoreCase("/h") || args[i].EqualsIgnoreCase("-h") || args[i].EqualsIgnoreCase("-?") || args[i].EqualsIgnoreCase("/?")) { DisplayHelp(); return; } if (args[i].StartsWith("-")) { Console.WriteLine("error : unrecognized flag: {0}", args[i]); return; } if (command == null && args[i].EqualsIgnoreCase("review") || args[i].EqualsIgnoreCase("close") || args[i].EqualsIgnoreCase("delete") || args[i].EqualsIgnoreCase("reopen") || args[i].EqualsIgnoreCase("rename") || args[i].EqualsIgnoreCase("addlink")) { command = args[i]; continue; } if (changeId == null) { changeId = args[i]; continue; } if ("addlink".EqualsIgnoreCase(command)) { if (link == null) { link = args[i]; continue; } else if (linkDescr == null) { linkDescr = args[i]; continue; } } if ("rename".EqualsIgnoreCase(command)) { if (newChangeId == null) { newChangeId = args[i]; continue; } } if (command == null || "review".EqualsIgnoreCase(command)) { if (!AddReviewers(reviewers, args[i])) return; continue; } Console.WriteLine("error : {0} is not recognized. --help for help", args[i]); return; } string userName = impersonatedUserName ?? Environment.GetEnvironmentVariable("USERNAME"); if (changeId == null) { Console.WriteLine("error : change list is required. Type 'review help' for help."); return; } if (databaseServer == null) { Console.WriteLine("error : database server is required. Type 'review help' for help."); return; } if (link == null && linkDescr != null) { Console.WriteLine("error : if you supply link description, the link must also be present."); return; } if (impersonatedUserName != null && !admin) { Console.WriteLine("error : --impersonate may only be used in conjunction with --admin."); return; } int sourceControlInstanceId; if (!Int32.TryParse(sourceControlInstance, out sourceControlInstanceId)) sourceControlInstanceId = DefaultSourceControlInstanceId; // These commands do not require source control - get them out the way first. if (command != null) { CodeReviewDataContext context = new CodeReviewDataContext("Data Source=" + databaseServer + ";Initial Catalog=CodeReview;Integrated Security=True"); if (command.EqualsIgnoreCase("close")) { MarkChangeListAsClosed(context, userName, sourceControlInstanceId, changeId, force, admin); return; } else if (command.EqualsIgnoreCase("delete")) { DeleteChangeList(context, userName, sourceControlInstanceId, changeId, force, admin); return; } else if (command.EqualsIgnoreCase("rename")) { RenameChangeList(context, userName, sourceControlInstanceId, changeId, newChangeId, admin); return; } else if (command.EqualsIgnoreCase("reopen")) { ReopenChangeList(context, userName, sourceControlInstanceId, changeId, admin); return; } else if (command.EqualsIgnoreCase("addlink")) { if (link != null) AddAttachment(context, userName, changeId, link, linkDescr); else Console.WriteLine("You need to supply the link to add."); return; } } // If we have the client, maybe we can guess the source control... if (sourceControlType == null && settings.ClientExe != null) { string clientExeFile = Path.GetFileName(settings.ClientExe); if ("sd.exe".EqualsIgnoreCase(clientExeFile)) sourceControlType = SourceControl.SourceControlType.SD; else if ("p4.exe".EqualsIgnoreCase(clientExeFile)) sourceControlType = SourceControl.SourceControlType.PERFORCE; else if ("tf.exe".EndsWith(clientExeFile, StringComparison.InvariantCultureIgnoreCase)) sourceControlType = SourceControl.SourceControlType.TFS; else if ("svn.exe".EqualsIgnoreCase(clientExeFile)) sourceControlType = SourceControl.SourceControlType.SUBVERSION; } // Attempt to detect the source control system. if (sourceControlType == null) { if (sdSettings.Port != null && sdSettings.Client != null && sdSettings.ClientExe != null) sourceControlType = SourceControl.SourceControlType.SD; if (p4Settings.Port != null && p4Settings.Client != null && p4Settings.ClientExe != null) sourceControlType = SourceControl.SourceControlType.PERFORCE; if (tfsSettings.Port != null) sourceControlType = SourceControl.SourceControlType.TFS; if (svnSettings.Port != null && svnSettings.Client != null && svnSettings.ClientExe != null) sourceControlType = SourceControl.SourceControlType.SUBVERSION; if (sourceControlType == null) { Console.WriteLine("Could not determine the source control system."); Console.WriteLine("User 'review help' for help with specifying it."); return; } } // If source control is explicitly specified... if (sourceControlType == SourceControl.SourceControlType.TFS) { if (settings.Client != null) tfsSettings.Client = settings.Client; if (settings.Port != null) tfsSettings.Port = settings.Port; if (settings.User != null) tfsSettings.User = settings.User; if (settings.Password != null) tfsSettings.Password = settings.Password; if (settings.ClientExe != null) tfsSettings.ClientExe = settings.ClientExe; if (settings.Diff != SourceControlSettings.DiffSource.Unspecified) tfsSettings.Diff = settings.Diff; if (tfsSettings.Port == null) { Console.WriteLine("Could not determine tfs server. Consider specifying it on the command line or " + "in the environment."); return; } if (tfsSettings.Client == null && tfsSettings.Diff == SourceControlSettings.DiffSource.Local) { Console.WriteLine("Could not determine tfs workspace. Consider specifying it on the command line " + "or in the environment."); return; } } if (sourceControlType == SourceControl.SourceControlType.PERFORCE) { if (settings.Client != null) p4Settings.Client = settings.Client; if (settings.Port != null) p4Settings.Port = settings.Port; if (settings.User != null) p4Settings.User = settings.User; if (settings.Password != null) p4Settings.Password = settings.Password; if (settings.ClientExe != null) p4Settings.ClientExe = settings.ClientExe; if (p4Settings.ClientExe == null) { Console.WriteLine( "Could not find p4.exe. Consider putting it in the path, or on the command line."); return; } if (p4Settings.Port == null) { Console.WriteLine("Could not determine the server port. " + "Consider putting it on the command line, or in p4 config file."); return; } if (p4Settings.Client == null) { Console.WriteLine("Could not determine the perforce client. " + "Consider putting it on the command line, or in p4 config file."); return; } } if (sourceControlType == SourceControl.SourceControlType.SUBVERSION) { if (settings.Client != null) svnSettings.Client = settings.Client; if (settings.Port != null) svnSettings.Port = settings.Port; if (settings.User != null) svnSettings.User = settings.User; if (settings.Password != null) svnSettings.Password = settings.Password; if (settings.ClientExe != null) svnSettings.ClientExe = settings.ClientExe; if (svnSettings.ClientExe == null) { Console.WriteLine( "Could not find svn.exe. Consider putting it in the path, or on the command line."); return; } if (svnSettings.Port == null) { Console.WriteLine("Could not determine the server Url. " + "Consider putting it on the command line."); return; } } if (sourceControlType == SourceControl.SourceControlType.SD) { if (settings.Client != null) sdSettings.Client = settings.Client; if (settings.Port != null) sdSettings.Port = settings.Port; if (settings.ClientExe != null) sdSettings.ClientExe = settings.ClientExe; if (sdSettings.ClientExe == null) { Console.WriteLine( "Could not find sd.exe. Consider putting it in the path, or on the command line."); return; } if (sdSettings.Port == null) { Console.WriteLine("Could not determine the server port. " + "Consider putting it on the command line, or in sd.ini."); return; } if (sdSettings.Client == null) { Console.WriteLine("Could not determine the source depot client. " + "Consider putting it on the command line, or in sd.ini."); return; } } try { ISourceControl sourceControl; IBugServer bugTracker = null; if (sourceControlType == SourceControl.SourceControlType.SD) sourceControl = SourceDepotInterface.GetInstance(sdSettings.ClientExe, sdSettings.Port, sdSettings.Client, sdSettings.Proxy); else if (sourceControlType == SourceControl.SourceControlType.PERFORCE) sourceControl = PerforceInterface.GetInstance(p4Settings.ClientExe, p4Settings.Port, p4Settings.Client, p4Settings.User, p4Settings.Password); else if (sourceControlType == SourceControl.SourceControlType.SUBVERSION) sourceControl = SubversionInterface.GetInstance(svnSettings.ClientExe, svnSettings.Port, svnSettings.Client); else if (sourceControlType == SourceControl.SourceControlType.TFS) { sourceControl = SourceControl.Tfs.Factory.GetISourceControl( tfsSettings.Port, tfsSettings.Client, tfsSettings.ClientOwner, tfsSettings.User, tfsSettings.Password, tfsSettings.Diff == SourceControlSettings.DiffSource.Server); bugTracker = SourceControl.Tfs.Factory.GetIBugServer( tfsSettings.Port, tfsSettings.Client, tfsSettings.ClientOwner, tfsSettings.User, tfsSettings.Password); } else throw new ApplicationException("Unknown source control system."); if (verbose) { ILogControl logControl = sourceControl as ILogControl; if (logControl != null) logControl.SetLogLevel(LogOptions.ClientUtility); else Console.WriteLine("Note: client log requested, but not supported by the utility."); } if (!sourceControl.Connect()) { Console.WriteLine("Failed to connect to the source control system."); return; } ProcessCodeReview(databaseServer, sourceControl, sourceControlInstanceId, changeId, reviewers, invitees, link, linkDescr, description, bugTracker, bugIds, force, includeBranchedFiles, preview, impersonatedUserName); sourceControl.Disconnect(); } catch (SourceControlRuntimeError) { // The error condition has already been printed out at the site where this has been thrown. Console.WriteLine("Code review has not been submitted!"); } catch (SqlException ex) { Console.WriteLine("Could not connect to Malevich database. This could be a temporary"); Console.WriteLine("network problem or a misconfigured database name. Please ensure that"); Console.WriteLine("the database ({0}) is specified correctly.", databaseServer); Console.WriteLine("If this is a new Malevich server installation, please ensure that"); Console.WriteLine("SQL Server TCP/IP protocol is enabled, and its ports are open in"); Console.WriteLine("the firewall."); if (verbose) { Console.WriteLine("Exception information (please include in bug reports):"); Console.WriteLine("{0}", ex); } else { Console.WriteLine("Use --verbose flag to show detailed error information."); } } }
/// <summary> /// Autodiscovers TFS client based on the current directory. /// </summary> /// <param name="settings"></param> private static bool AutoDiscoverTfsSettings(SourceControlSettings settings) { try { string vcsConfig = Path.Combine(TeamFoundationServer.ClientCacheDirectory, "VersionControl.config"); if (!File.Exists(vcsConfig)) return false; XmlDocument config = new XmlDocument(); config.Load(vcsConfig); string dir = Directory.GetCurrentDirectory(); if (!dir.EndsWithIgnoreCase("\\")) dir += "\\"; XmlNodeList servers = config.GetElementsByTagName("ServerInfo"); foreach (XmlNode server in servers) { if (server.ChildNodes == null) continue; foreach (XmlNode workspace in server.ChildNodes) { if (workspace.ChildNodes == null) continue; XmlNode paths = workspace["MappedPaths"]; if (paths == null) continue; foreach (XmlNode path in paths.ChildNodes) { XmlAttribute pathAttribute = path.Attributes["path"]; if (pathAttribute == null) continue; string value = pathAttribute.Value; if (value == null) continue; if (!value.EndsWithIgnoreCase("\\")) value += "\\"; if (dir.StartsWithIgnoreCase(value)) { if (settings.Port == null) { XmlAttribute uriAttribute = server.Attributes["uri"]; if (uriAttribute != null) settings.Port = uriAttribute.Value; } if (settings.Client == null && settings.Diff == SourceControlSettings.DiffSource.Local) { XmlAttribute workspaceAttribute = workspace.Attributes["name"]; if (workspaceAttribute != null) settings.Client = workspaceAttribute.Value; XmlAttribute workspaceOwnerAttr = workspace.Attributes["ownerName"]; if (workspaceOwnerAttr != null) settings.ClientOwner = workspaceOwnerAttr.Value; } } } } } } catch (FileNotFoundException) { return false; } return true; }
/// <summary> /// Gets the Tfs client settings. /// </summary> /// <returns></returns> public static SourceControlSettings GetSettings() { SourceControlSettings settings = new SourceControlSettings(); settings.Port = Environment.GetEnvironmentVariable("TFSSERVER"); settings.Client = Environment.GetEnvironmentVariable("TFSWORKSPACE"); settings.ClientOwner = Environment.GetEnvironmentVariable("TFSWORKSPACEOWNER"); settings.User = Environment.GetEnvironmentVariable("TFSUSER"); settings.Password = Environment.GetEnvironmentVariable("TFSPASSWORD"); settings.Diff = SourceControlSettings.DiffSource.Unspecified; string tfsDiffSource = Environment.GetEnvironmentVariable("TFSDIFFSOURCE"); if ("shelf".Equals(tfsDiffSource, StringComparison.InvariantCultureIgnoreCase)) settings.Diff = SourceControlSettings.DiffSource.Server; if ("local".Equals(tfsDiffSource, StringComparison.InvariantCultureIgnoreCase)) settings.Diff = SourceControlSettings.DiffSource.Local; string path = Environment.GetEnvironmentVariable("path").Replace("\"", ""); string[] pathArray = path.Split(';'); for (int i = 0; i < pathArray.Length; ++i) { string tf = Path.Combine(pathArray[i], "tf.exe"); if (File.Exists(tf)) settings.ClientExe = tf; } if (!AutoDiscoverTfsSettings(settings)) Console.WriteLine("WARNING: Unable to detect ambient TFS settings."); return settings; }
/// <summary> /// Gets the perforce client settings. /// </summary> /// <returns></returns> public static SourceControlSettings GetSettings() { SourceControlSettings settings = new SourceControlSettings(); settings.Port = Environment.GetEnvironmentVariable("P4PORT"); if (settings.Port != null) settings.Port = settings.Port.Trim(); settings.Client = Environment.GetEnvironmentVariable("P4CLIENT"); if (settings.Client != null) settings.Client = settings.Client.Trim(); settings.User = Environment.GetEnvironmentVariable("P4USER"); if (settings.User != null) settings.User = settings.User.Trim(); settings.Password = Environment.GetEnvironmentVariable("P4PASSWD"); string path = Environment.GetEnvironmentVariable("path").Replace("\"", ""); string[] pathArray = path.Split(';'); for (int i = 0; i < pathArray.Length; ++i) { string p4 = Path.Combine(pathArray[i], "p4.exe"); if (File.Exists(p4)) { settings.ClientExe = p4; break; } } string p4Config = Environment.GetEnvironmentVariable("P4CONFIG"); if (p4Config != null) { string dir = Directory.GetCurrentDirectory(); string root = Path.GetPathRoot(dir); while (!dir.Equals(root)) { string p4 = Path.Combine(dir, p4Config); if (File.Exists(p4)) { Regex portRegex = new Regex(@"^(\s)*P4PORT(\s)*=(\s)*(?<port>(\S)*)(\s)*$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); Regex clientRegex = new Regex(@"^(\s)*P4CLIENT(\s)*=(\s)*(?<client>(\S)*)(\s)*$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); Regex userRegex = new Regex(@"^(\s)*P4USER(\s)*=(\s)*(?<user>(\S)*)(\s)*$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); Regex passwdRegex = new Regex(@"^(\s)*P4PASSWD(\s)*=(\s)*(?<passwd>(\S)*)(\s)*$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); StreamReader sr = new StreamReader(p4); while (settings.Port == null || settings.Client == null || settings.User == null || settings.Password == null) { string l = sr.ReadLine(); if (l == null) break; if (settings.Port == null) { Match portMatch = portRegex.Match(l); if (portMatch.Success) { settings.Port = portMatch.Groups[1].Value; continue; } } if (settings.Client == null) { Match clientMatch = clientRegex.Match(l); if (clientMatch.Success) { settings.Client = clientMatch.Groups[1].Value; continue; } } if (settings.User == null) { Match userMatch = userRegex.Match(l); if (userMatch.Success) { settings.User = userMatch.Groups[1].Value; continue; } } if (settings.Password == null) { Match passwdMatch = passwdRegex.Match(l); if (passwdMatch.Success) { settings.Password = passwdMatch.Groups[1].Value; continue; } } } sr.Close(); break; } dir = Path.GetDirectoryName(dir); } } return settings; }