最近工作需要针对p4.exe这个控制台程序做一些提高工作效率的工具,所以也就需要通过调用p4.exe提供一些接口,自己总结了一下其实大部分情况下是进行对p4.exe执行的命令行的输出进行字符串解析,然后获取需要的信息(如revision,changlist等),进行处理。
下面接口包括登录,获取一个文件最近版本,获取一个文件的上一个版本以及获取一个changelist中某个文件,C#自己刚刚开始玩,代码都是自己纯手写,仅供参考(接口中除了GetFile中的filename不是全路径,其他的FileName都是以//depot开头的完整路径):
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.IO; namespace TestCsConsole { class VCSLoader_P4_Impl : IVCSLoader_P4 { public enum eLoginStatus{eLoginSuccess = 0,eLoginError}; private void p4Set(string strP4Args) { ProcessStartInfo p4Proc = InitProcessStartInfo("p4.exe", "set " + strP4Args); Process p = Process.Start(p4Proc); p.WaitForExit(); p.Close(); } private bool p4Login(string Username, string strP4Args) { bool bLoginSucess = false; ProcessStartInfo p4Proc = InitProcessStartInfo("p4.exe", "login"); Process p = Process.Start(p4Proc); StreamReader reader = p.StandardOutput; StreamWriter wrt = p.StandardInput; wrt.WriteLine(strP4Args); string strLine; while (!reader.EndOfStream) { strLine = reader.ReadLine(); if (strLine.Equals("User "+ Username + " logged in.")) { bLoginSucess = true; } } p.WaitForExit(); p.Close(); reader.Close(); wrt.Close(); return bLoginSucess; } public int Initialize(string Host, string UserName, string Password, string WorkSpace) { p4Set("P4PORT=" + Host); p4Set("P4USER=" + UserName); p4Set("P4CLIENT=" + WorkSpace); if (p4Login(UserName, Password)) { return (int)eLoginStatus.eLoginSuccess; } else { return (int)eLoginStatus.eLoginError; } } public int GetFile(int ChangeList, string fileName, string SaveAsFileName) { string strMatchFileName = ""; ProcessStartInfo p4Proc = InitProcessStartInfo("p4.exe", "describe -s " + ChangeList); Process p = Process.Start(p4Proc); StreamReader reader = p.StandardOutput; string strLine; while (!reader.EndOfStream) { strLine = reader.ReadLine(); if (!strLine.Contains('#')) { continue; } strLine.Contains(fileName); int lastSlashIndx = strLine.LastIndexOf('/'); int lastPoundIndx = strLine.LastIndexOf('#'); string strFileNameInChangelist = strLine.Substring(lastSlashIndx + 1, lastPoundIndx - lastSlashIndx - 1); if (strFileNameInChangelist.Equals(fileName)) { strMatchFileName = strLine.Substring(strLine.IndexOf('/'), strLine.LastIndexOf(' ') - strLine.IndexOf('/')); //break; } } p.WaitForExit(); p.Close(); reader.Close(); if (strMatchFileName.Length > 0) { GetLatestVersion(strMatchFileName, SaveAsFileName); } return 0; } //获取最新版本的文件,若FileName后面加上比如#50这样的版本号,则会获取该版本的文件,返回相应的changelist public int GetLatestVersion(string FileName, string SaveAsFileName) { int nChanglist = 0; ProcessStartInfo p4Proc = InitProcessStartInfo("p4.exe", "print -o " + SaveAsFileName + " " + FileName); Process p = Process.Start(p4Proc); StreamReader reader = p.StandardOutput; string strLine; while (!reader.EndOfStream) { strLine = reader.ReadLine(); string strForMatch = "edit change "; if (strLine.Contains( strForMatch)) { int nLastSpacePos = strLine.LastIndexOf(' '); int nStartIndex = strLine.IndexOf(strForMatch) + strForMatch.Length; string strChangelist = strLine.Substring(nStartIndex, nLastSpacePos - nStartIndex); nChanglist = Int32.Parse(strChangelist); } } p.WaitForExit(); p.Close(); return nChanglist; } public int GetPreviousVersion(string FileName, string SaveAsFileName) { string strVersionNum = ""; ProcessStartInfo p4Proc = InitProcessStartInfo("p4.exe", "filelog " + FileName); Process p = Process.Start(p4Proc); StreamReader reader = p.StandardOutput; string strLine; int nVersionLineCounter = 0; while (!reader.EndOfStream) { strLine = reader.ReadLine(); if (!strLine.Contains("... #")) { continue; } ++nVersionLineCounter; if (2 == nVersionLineCounter) { const int nPosSharp = 4; int nSecondSpacePos = strLine.IndexOf(' ', 5); strVersionNum = strLine.Substring(nPosSharp, nSecondSpacePos - nPosSharp); } else { continue; } } p.WaitForExit(); p.Close(); if (0 < strVersionNum.Length) { return GetLatestVersion(FileName + strVersionNum, SaveAsFileName); } return 0; } private ProcessStartInfo InitProcessStartInfo(string processName, string arguments) { ProcessStartInfo procInfo = new ProcessStartInfo(processName); procInfo.Arguments = arguments; procInfo.CreateNoWindow = true; procInfo.RedirectStandardOutput = true; procInfo.RedirectStandardInput = true; procInfo.UseShellExecute = false; return procInfo; } } }