【问题标题】:Using pscp in C# for file transfer between Windows and Linux through a post request在 C# 中使用 pscp 通过 post 请求在 windows 和 linux 之间传输文件
【发布时间】:2017-05-05 18:18:45
【问题描述】:

我一直在尝试通过 C# 代码传输文件,但它似乎不起作用。尽管命令提示符中的以下行可以正常工作。

"C:\Program Files (x86)\PuTTY\pscp.exe" -l user -pw password C:\Users\user1\Desktop\\transfer1.txt 000.000.00.000:/home/doc

通讯类是

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace Server.Controllers
{     
    public class ComLinux
    {
        public static string TransferFilesToSever(string args)
        {
        Process p = new Process();

        p.StartInfo.FileName = @"C:\Program Files (x86)\PuTTY\pscp.exe";
        p.StartInfo.Arguments = args;
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardInput = true;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.CreateNoWindow = false;
        p.Start();
        string output = p.StandardOutput.ReadToEnd();
        p.WaitForExit(); 
        return "Done";
   }}}

SendFilesController 看起来像

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Server.Controllers
{
    [Route("api/[controller]")]
    public class SendFilesController : Controller
    {
        [HttpPost]
        public IActionResult Post([FromBody] string cmdTostart)
        {
        var WindowsPath = ConfigurationManager.AppSettings["WindowsPath"].ToString();
        var LinuxPath = ConfigurationManager.AppSettings["LinuxPath"].ToString();
        var LinuxUserPass = ConfigurationManager.AppSettings["LinuxUserPass"].ToString();
        var WindowcommandtoL = LinuxUserPass + " " + WindowsPath + "transfer1.txt" + " " + LinuxPath;
        var resultw = ComLinux.TransferFilesToSever(WindowcommandtoL); 
        return Content("OK");
    }}}

在 app.config 中,我有

<add key="LinuxUserPass" value="-l user -pw password"/>
<add key="WindowsPath" value="C:\Users\user1\Desktop\"/>
<add key="LinuxPath" value="000.00.000://home/doc"/>

当发布请求时,我的 Http 代码是 200,但文件没有移动到 linux 服务器。我不确定这里出了什么问题。

【问题讨论】:

  • 你为什么用 putty 而不是SSH.NET
  • p.ExitCode 的值是多少? output 的值是多少?
  • @JacobKrall 当我通过 IIS Express 在 localhost:49595 以调试模式运行代码时,该代码似乎可以工作。但是一旦我将它发布到网站上,它就不起作用了。
  • 这没有回答问题!
  • @JacobKrall p.Exitcode 为 1,p.ouput 为空白。

标签: c# .net ssh putty scp


【解决方案1】:

首先,使用外部应用程序进行 SCP 上传是错误的。

改用一些本机 .NET SCP 实现。见SCP for C#


无论如何,一个明显的问题是您的命令不包含-hostkey 开关。您需要验证 SSH 主机密钥指纹。如果您曾经连接过 PuTTY/PSCP,系统会提示您验证主机密钥。如果您这样做了,经过验证的主机密钥将缓存在 Windows 注册表中。这就是您的代码在使用本地帐户在本地计算机上执行时有效的原因。

但是,如果您在另一台机器上运行代码或使用另一个帐户,它将无法工作,因为主机密钥没有在那里验证。

您应该在主机密钥指纹中包含-hostkey switch

【讨论】:

  • 感谢您的回答。我正在使用 pscp,因为我还需要 plink 在 linux 服务器上运行一些命令。我有另一个问题。对于主机密钥,pscp 已将其缓存在注册表中,我不知道如何转换注册表项,它是一个巨大的字符串,如 0x10001、0xae..你能举个例子说明如何指定缓存的主机密钥吗?
  • “我正在使用 pscp,因为我还需要 plink 在 linux 服务器上运行一些命令。” - 您需要运行命令与 PSCP/SCP 有何关系?而且所有/大多数 SCP 库都是通用 SSH 库,因此它们当然也支持执行命令!
  • 你是对的。我只是使用 plink 附带的 pscp。我可能会转向 SharpSSH
  • 不是 SharpSSH!那是一个死项目。还要别的吗。我建议SSH.NET
【解决方案2】:

我无法发送文件的原因是应用程序池标识是默认的,我不得不将其更改为我的用户名。

虽然我决定不使用 pscp 而是使用 ssh.net 库。非常感谢 Martin Prikryl

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-09
    • 2018-12-13
    • 1970-01-01
    相关资源
    最近更新 更多