使用System.Diagnostics.Process在命令行中传输文件

9

我想运行一个命令行程序,并将文件作为输入流。该命令在命令行上可以正常工作,但是在C#的Process对象中似乎无法正常工作。这是我正在使用的命令:

"C:\Servers\CollabNet Subversion Server\svnadmin" load C:\Repositories\TestLoad < C:\Temp\test.dump

除了上面那个命令之外,这个函数可以正常处理其他所有传递给它的命令。

public static bool ExecuteSvnCommand( string command, string arguments, out string result, out string errors )
{
    bool retval = false;
    string output = string.Empty;
    string errorLines = string.Empty;
    Process svnCommand = null;
    var psi = new ProcessStartInfo( command );

    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.WindowStyle = ProcessWindowStyle.Hidden;
    psi.UseShellExecute = false;
    psi.CreateNoWindow = true;

    try
    {
        Process.Start( psi );
        psi.Arguments = arguments;
        svnCommand = Process.Start( psi );

        StreamReader myOutput = svnCommand.StandardOutput;
        StreamReader myErrors = svnCommand.StandardError;
        svnCommand.WaitForExit();

        if ( svnCommand.HasExited )
        {
            output = myOutput.ReadToEnd();
            errorLines = myErrors.ReadToEnd();
        }

        // Check for errors
        if ( errorLines.Trim().Length == 0 )
        {
            retval = true;
        }
    }
    catch ( Exception ex )
    {
        string msg = ex.Message;
        errorLines += Environment.NewLine + msg;
    }
    finally
    {
        if (svnCommand != null)
        {
            svnCommand.Close();
        }
    }

    result = output;
        errors = errorLines;

    return retval;
}

我尝试了几种不同的函数组合,但我无法让它工作。我一直收到“系统找不到指定的文件”消息。我已经做了一个星期了,我认为我需要几双眼睛来看看我做错了什么。
3个回答

9

Mark和Luke都给了我正确的方向。我不能使用任何一个答案,因为我必须这样做才能在Linux上使用Mono运行。所以我最终按照建议将内容写入StandardInput中。以下是可行的代码:

public static bool ExecuteSvnCommandWithFileInput( string command, string arguments, string filePath, out string result, out string errors )
{
    bool retval = false;
    string output = string.Empty;
    string errorLines = string.Empty;
    Process svnCommand = null;
    var psi = new ProcessStartInfo( command );

    psi.RedirectStandardInput = true;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.WindowStyle = ProcessWindowStyle.Hidden;
    psi.UseShellExecute = false;
    psi.CreateNoWindow = true;

    try
    {
        Process.Start( psi );
        psi.Arguments = arguments;
        svnCommand = Process.Start( psi );

        var file = new FileInfo(filePath);
        StreamReader reader = file.OpenText();
        string fileContents = reader.ReadToEnd();
        reader.Close();

        StreamWriter myWriter = svnCommand.StandardInput;
        StreamReader myOutput = svnCommand.StandardOutput;
        StreamReader myErrors = svnCommand.StandardError;

        myWriter.AutoFlush = true;
        myWriter.Write(fileContents);
        myWriter.Close();

        output = myOutput.ReadToEnd();
        errorLines = myErrors.ReadToEnd();

        // Check for errors
        if ( errorLines.Trim().Length == 0 )
        {
            retval = true;
        }
    }
    catch ( Exception ex )
    {
        string msg = ex.Message;
        errorLines += Environment.NewLine + msg;
    }
    finally
    {
        if (svnCommand != null)
        {
            svnCommand.Close();
        }
    }

    result = output;
    errors = errorLines;

    return retval;
}

5

我不能百分之百确定,但我的猜测是您需要手动使用进程的 StandardInput 属性将数据从 test.dump 推送到进程中。

否则,您可以尝试使用 cmd.exe 执行命令:

var psi = new ProcessStartInfo( "cmd.exe /c \"" + command "\"" );

这是因为">"、"<"和"|"操作符由shell本身(cmd.exe)实现。

1

我的猜测是你应该挂钩StandardInput并自己写入文件。你可以尝试使用ShellExecute = true,但我不确定它是否有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接