最近工作需要针对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;
}
}
}