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