首页 > 解决方案 > 如何使用 c# Process 获取 SVN 提交日志

问题描述

我需要使用 C# 应用程序按日期获取 svn 项目的提交日志,即如果我们提供了 URl、开始和结束日期,我们应该在进程中使用 svn.exe 来获取日志详细信息

我已经使用命令 svn log -r {"2007-07-07"}:{2019-11-08} 来获取登录命令提示符。

            SourcePath = args[0];  // URL link
            var startDate = args[1];
            var endDate = args[2];
            var svnSource = args[3];  // svn.exe location in my machine

            var cmd1 = "cd /";
            var cmd2 = "c:";
            var cmd3 = string.Concat("cd ", svnSource);                              
            var cmd4 = string.Concat("svn log ", SourcePath, " -r {",  startDate, "}:{", endDate, "}");

            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = "svn.exe";              
            startInfo.RedirectStandardInput = true;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError = true;
            startInfo.UseShellExecute = false;
            Process process = new Process();
            process.StartInfo = startInfo;


            process.Start();
            process.StandardInput.WriteLine(cmd1);
            process.StandardInput.WriteLine(cmd2);
            process.StandardInput.WriteLine(cmd3);
            process.StandardInput.WriteLine(cmd4);

而(!process.StandardOutput.EndOfStream){

            string line = process.StandardOutput.ReadLine();
            if (!string.IsNullOrEmpty(line))
            {
                if (!process.HasExited)
                {

                }
            }

}

我希望字符串“line”中的结果包含所有日志值,但我得到的实际输出值为空。调试时断点本身不会命中“while (!process.StandardOutput.EndOfStream)”部分。

如何解决这个问题?我在这里做错了什么?

标签: c#svnprocesssystem.diagnostics

解决方案


首先,svn.exe 不会解释这样的命令,所以你应该启动一个像 cmd.exe 这样的 shell。

如果您为 SourcePath 提供 URL,那么 svn 可以从 cmd 的任何位置运行,因此您根本不需要前 3 个命令:cmd1、cmd2、cmd3。话虽如此,您也不需要 svnSource 变量。

当然,您可以 cd 到根目录以使您的输出看起来更干净。

所以这些是我对你的代码所做的修改:

var SourcePath = args[0];  // URL link
var startDate = args[1];
var endDate = args[2];    

var cmd1 = "cd c:\\";
var cmd2 = string.Concat("svn log ", SourcePath, " -r {", startDate, "}:{", endDate, "}");

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
Process process = new Process();
process.StartInfo = startInfo;

process.Start();
process.StandardInput.WriteLine(cmd1);
process.StandardInput.WriteLine(cmd2);

// It's always a good idea to close your standard input when you're not gonna need it anymore,
// otherwise the process will wait indefinitely for any input and your while condition will never
// be true or in other words it will become an infinite loop...
process.StandardInput.Close();

string result = string.Empty; // for storing the svn commit log

while (!process.StandardOutput.EndOfStream)
{
    string line = process.StandardOutput.ReadLine();
    if (!string.IsNullOrEmpty(line))
    {
        if (!process.HasExited)
        {
            result += line + Environment.NewLine;
        }
    }                
}

推荐阅读