SFTP в службе Windows

1

Мне нужно выполнить процесс SFTP через код С#. Я использую службу Windows. Ниже приведен код, который я использую.

WebCash.writeToFile(WebCash.outerbatchpath, command);
WebCash.writeToFile(WebCash.outerbatchpath, "exit");

ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", "/c "+WebCash.outerbatchpath);
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
Process p = new Process();
p.StartInfo = psi;
p.Start();
p.WaitForExit();

psi = null;
WebCash.writeToFile(WebCash.GetErrorLog(), DateTime.Now.ToString() + "- Running SFTP end - " + p.ExitCode);
return p.ExitCode;

При попытке отладки вышеуказанного кода отладчик не может передать p.WaitforExit() (т. p.WaitforExit()) Служба не выполняется после p.WaitforExit().

Я запускаю следующую команду (SFTP) в моей внешней стороне.

 psftp -b D:\Source_Data\SFTP\innerbatch.bat -l username -i D:\privatekey.ppk @servername

Внутренняя партия содержит команду ниже

put D:\Source_Data\SFTP\FileToTransfer.xml

Мне нужен код выхода, чтобы получить ошибку. Помощь Pls.

Теги:
windows-services
sftp

2 ответа

0
Лучший ответ

Я предполагаю, что запущенная вами программа ("внешняя партия") никогда не заканчивается.

Когда вы перенаправляете выход процесса, вы должны его прочитать. Там ограниченный буфер для перенаправленного вывода. Когда он заполняется, дочерний процесс останавливается при следующей попытке произвести вывод и ждет, пока родительский процесс не прочитает некоторые данные из буфера. Как вы никогда этого не делаете, и вы ждете завершения процесса, возникает взаимоблокировка.

См. MSDN для свойства ProcessStartInfo.RedirectStandardOutput:

Операции синхронного чтения вводят зависимость между показанием вызывающего абонента из потока StandardOutput и записью дочернего процесса в этот поток. Эти зависимости могут привести к условиям взаимоблокировки. Когда вызывающий абонент читает из перенаправленного потока дочернего процесса, он зависит от дочернего элемента. Вызывающий абонент ждет операции чтения до тех пор, пока ребенок не будет записываться в поток или не закрывает поток. Когда дочерний процесс записывает достаточно данных для заполнения перенаправленного потока, он зависит от родителя. Детский процесс ждет следующей операции записи, пока родитель не прочитает полный поток или не закрывает поток. Условие взаимоблокировки возникает, когда вызывающий и дочерний процессы ждут друг друга для завершения операции, и они не могут продолжаться. Вы можете избежать взаимоблокировок, оценивая зависимости между вызывающим и дочерним процессами.

В этом случае всегда рекомендуется использовать p.StandardOutput.ReadToEnd() вместо p.WaitForExit(). Обе команды ждут выхода процесса, но первый гарантирует, что тупик не произойдет.

С другой стороны, поскольку вы передаете только один файл, я не уверен, что вывод psftp самом деле достаточно велик, чтобы заполнить буфер. Если приведенное выше предложение не поможет, я бы рекомендовал вам упростить код, непосредственно запуская psftp.exe, удалив ненужные слои cmd.exe и внешнего командного файла.

EDIT: Если вы никогда не запускаете psftp под учетной записью службы, возможно, это psftp к подтверждению подтверждения ключа хоста.

Ключ хоста сервера не кэшируется в реестре. Вы
не имеют гарантии, что сервер - это компьютер, на котором вы
думаю.
Отпечаток ключа сервера dss:
ssh-dss 1024 0b: 77: 8b: 68: f4: 45: b1: 3c: 87: ad: 5c: be: 3b: c5: 72: 78
Если вы доверяете этому хосту, введите "y", чтобы добавить ключ к
PuTTY и продолжайте соединение.
Если вы хотите продолжать соединение только один раз, без
добавив ключ в кэш, введите "n".
Если вы не доверяете этому хосту, нажмите Return, чтобы отказаться от
подключение.
Сохранить ключ в кеше? (Г/л)

Вы должны использовать переключатель -hostkey чтобы явно указать отпечаток доверенного ключа хоста.

В качестве альтернативы можно использовать некоторую собственную библиотеку SFTP.NET.

Замечание: Именование сценария psftp .bat запутанно. Это не файл (Windows).

  • 0
    Я обновил свой ответ.
  • 0
    Изменение p.WaitForExit () на p.StandardOutput.ReadToEnd () не работает. Тот же результат :(
Показать ещё 5 комментариев
0

Использование WinSCP.

Для SshHostKeyFingerprint см. Диалог информации о сервере и протоколе

// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Sftp,
    HostName = "000.00.00.000",
    UserName = "xxxxxx",
    Password = "xxxxxx",
    PortNumber= 22,
    SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxxxxxx"
};

using (Session session = new Session())
{
    // Connect
    session.Open(sessionOptions);

    // Upload files
    //TransferOptions transferOptions = new TransferOptions();
    //transferOptions.TransferMode = TransferMode.Binary;

    //TransferOperationResult transferResult;
    var results = session.ListDirectory("/path");
    foreach (RemoteFileInfo item in results.Files)
    {
        Console.WriteLine(item.Name);
    }

    // Throw on any error
    //transferResult.Check();

    // Print results
    //foreach (TransferEventArgs transfer in transferResult.Transfers)
    //{
    //    Console.WriteLine("Upload of {0} succeeded", transfer.FileName);
    //}
}
  • 0
    У sessionOptions есть параметры Password, SshHostKeyFingerprint. Как это получить. У меня есть только закрытый ключ для доступа к серверу (то есть) У меня есть имя сервера, имя пользователя и закрытый ключ для доступа к серверу Пожалуйста помогите ..
  • 0
    чтобы получить ваш сервер SshHostKeyFingerprint: просто запустите winScp-клиент «приложение для Windows», добавьте имя пользователя / пароль, приложение отобразит этот ключ, или вы можете открыть приложение WinScp из меню «Команды» -> «Информация о сервере / протоколе» -> всплывающее окно. Окно содержит этот ключ.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню