WinSCP没有使用System.Diagnostics.Process从C#完全执行?

时间:2016-01-26 14:12:11

标签: c# process ssis winscp

我正在尝试从FTP服务器下载一些文件并自动执行此任务。我在大部分时间都遵循了本教程来完成我的过程:
http://www.timmitchell.net/post/2015/08/03/downloading-sftp-files-with-ssis/

现在,我想使用命令:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />

如果我从命令行运行此命令,它可以正常运行并同步所需的300~文件。

我的问题是,当我从C#运行它时,它只会同步30个文件并挂起synchronize local \\somesharefolder /someremotedir 函数调用。如果我显示过程窗口并手动关闭它,我的输出显示没有错。连接成功,文件开始下载,然后停止。

以下是编辑后的代码:

WaitForExit()

示例编辑输出:

// Create a new Process object to execute WinSCP
Process winscp = new Process();

// Set the executable path and download directory
winscp.StartInfo.FileName = @"C:\Program Files (x86)\WinSCP\WinSCP.com";

// Set static execution options
winscp.StartInfo.UseShellExecute = false;
winscp.StartInfo.RedirectStandardInput = true;
winscp.StartInfo.RedirectStandardOutput = true;
winscp.StartInfo.CreateNoWindow = true;

// Set session options
string sessionOptionString = "option batch abort" +
    System.Environment.NewLine + "option confirm off";

// Build the connection string (<user>:<password>@<hostname>)
string connectString = @"open ftp://" +
    "username" + ":" +
    "password" + "@" +
    "hostURL" + " -implicit";

// Supplying the host key adds an extra level of security, and avoids getting the prompt to trust the server
string hostKeyString = null;

// If hostkey was specified, include it
if (hostKeyString != null && hostKeyString.Length > 0)
{
    connectString += " -hostkey=\"" + hostKeyString + "\"";
}
else
{
    connectString += " -hostkey";
}

// Build the get command strings, stored in list to maintain order.
List<string> cmdStrings = new List<string>();

cmdStrings.Add(@"synchronize local \\some\file\share /some/remote/directory");
// Create output variables to capture execution info
string outStr = "", errStr = "";
int returnVal = 1;

// This try/catch block will capture catastrophic failures (such as specifying the wrong path to winscp)
try
{
    winscp.Start();

    winscp.StandardInput.WriteLine(sessionOptionString);
    winscp.StandardInput.WriteLine(connectString);
    foreach (var cmd in cmdStrings)
    {
        winscp.StandardInput.WriteLine(cmd);
    }
    winscp.StandardInput.Close();

    winscp.WaitForExit();

    // Set the outStr to the output value, obfuscating the password

    outStr = winscp.StandardOutput.ReadToEnd().Replace(":" +
        "password" +
        "@", ":*******@");
    returnVal = winscp.ExitCode;
}
catch (Exception ex)
{
    errStr = "An error occurred when attempting to execute winscp.com: " +
        ex.Message.Replace("'", "\"").Replace("--", " - ");
}

outStr.Dump();

输出停在那里,它没有被切断。

1 个答案:

答案 0 :(得分:1)

您正在等待该过程完成,然后才能阅读StandardOutput。这是有问题的,因为重定向的Process具有fixed-size buffer

当缓冲区已满时,对它的写入将被阻止,因此stdout管理的子进程在写入ReadToEnd时会阻塞。

如果您WaitForExit之前class,则不再出现此问题。