2010-02-23 9 views
8

Ho implementato la possibilità di caricare, scaricare, eliminare, ecc. Utilizzando la classe FtpWebRequest in C#. Questo è abbastanza semplice.Come inviare comandi FTP arbitrari in C#

Che cosa devo fare ora è il supporto invio di comandi arbitrari FTP quali

quote SITE LRECL=132 RECFM=FB 
or 
quote SYST 

Ecco un esempio di configurazione direttamente dal nostro app.config:

<!-- The following commands will be executed before any uploads occur --> 
<extraCommands> 
    <command>quote SITE LRECL=132 RECFM=FB</command> 
</extraCommands> 

io sono ancora alla ricerca come fare utilizzando FtpWebRequest. Probabilmente proverò la classe WebClient successiva. Chiunque può indicarmi la giusta direzione più velocemente? Grazie!

AGGIORNAMENTO: Sono giunto alla stessa conclusione, a partire da .NET Framework 3.5 FtpWebRequest non supporta nulla tranne ciò che è in WebRequestMethods.Ftp.*. Proverò un'app di terze parti raccomandata da alcuni degli altri post. Grazie per l'aiuto!

+0

avete fatto provare Rebex FTP con questi comandi? ha funzionato bene? – Askolein

risposta

9

non credo che possa essere fatto con FtpWebRequest ... L'unico modo per specificare un comando FTP è attraverso la proprietà Method, e gli stati di documentazione:

Nota che le stringhe definiti nel Le classi WebRequestMethods.Ftp sono le uniche opzioni supportate per la proprietà Method. L'impostazione della proprietà Method su qualsiasi altro valore comporterà un'eccezione ArgumentException.

SITO e SIST non sono tra le opzioni predefinite, quindi credo che sei bloccato ...

Non perdere tempo a provare la classe WebClient, che vi darà anche meno flessibilità rispetto FtpWebRequest .

Tuttavia, ci sono un sacco di applicazione di terze parti FTP, open source o commerciale, e sono abbastanza sicuro che alcuni di essi in grado di gestire i comandi personalizzati ...

3

È possibile provare il nostro Rebex FTP component:

// create client and connect 
Ftp client = new Ftp(); 
client.Connect("ftp.example.org"); 
client.Login("username", "password"); 

// send SITE command 
// note that QUOTE and SITE are ommited. QUOTE is command line ftp syntax only. 
client.Site("LRECL=132 RECFM=FB"); 

// send SYST command 
client.SendCommand("SYST"); 
FtpResponse response = client.ReadResponse(); 
if (response.Group != 2) 
    ; // handle error 

// disconnect 
client.Disconnect(); 
-5

Usa sendCommand("SITE LRECL=242 BLKSIZE=0 RECFM=FB");

+3

Questo è molto inutile perché non viene fornita alcuna informazione. Che cos'è "sendCommand" è una libreria di terze parti, ha qualcosa a che fare con FtpWebRequest ??? –

6

Il FtpWebRequest non vi aiuterà come Thomas Levesque ha detto nel suo answer. È possibile utilizzare alcune soluzioni di terze parti o il seguente, semplificate TcpClient codice in base che ho riscritta da un answer written in Visual Basic:

public static void SendFtpCommand() 
{ 
    var serverName = "[FTP_SERVER_NAME]"; 
    var port = 21; 
    var userName = "[FTP_USER_NAME]"; 
    var password = "[FTP_PASSWORD]" 
    var command = "SITE CHMOD 755 [FTP_FILE_PATH]"; 

    var tcpClient = new TcpClient(); 
    try 
    { 
     tcpClient.Connect(serverName, port); 
     Flush(tcpClient); 

     var response = TransmitCommand(tcpClient, "user " + userName); 
     if (response.IndexOf("331", StringComparison.OrdinalIgnoreCase) < 0) 
      throw new Exception(string.Format("Error \"{0}\" while sending user name \"{1}\".", response, userName)); 

     response = TransmitCommand(tcpClient, "pass " + password); 
     if (response.IndexOf("230", StringComparison.OrdinalIgnoreCase) < 0) 
      throw new Exception(string.Format("Error \"{0}\" while sending password.", response)); 

     response = TransmitCommand(tcpClient, command); 
     if (response.IndexOf("200", StringComparison.OrdinalIgnoreCase) < 0) 
      throw new Exception(string.Format("Error \"{0}\" while sending command \"{1}\".", response, command)); 
    } 
    finally 
    { 
     if (tcpClient.Connected) 
      tcpClient.Close(); 
    } 
} 

private static string TransmitCommand(TcpClient tcpClient, string cmd) 
{ 
    var networkStream = tcpClient.GetStream(); 
    if (!networkStream.CanWrite || !networkStream.CanRead) 
     return string.Empty; 

    var sendBytes = Encoding.ASCII.GetBytes(cmd + "\r\n"); 
    networkStream.Write(sendBytes, 0, sendBytes.Length); 

    var streamReader = new StreamReader(networkStream); 
    return streamReader.ReadLine(); 
} 

private static string Flush(TcpClient tcpClient) 
{ 
    try 
    { 
     var networkStream = tcpClient.GetStream(); 
     if (!networkStream.CanWrite || !networkStream.CanRead) 
      return string.Empty; 

     var receiveBytes = new byte[tcpClient.ReceiveBufferSize]; 
     networkStream.ReadTimeout = 10000; 
     networkStream.Read(receiveBytes, 0, tcpClient.ReceiveBufferSize); 

     return Encoding.ASCII.GetString(receiveBytes); 
    } 
    catch 
    { 
     // Ignore all irrelevant exceptions 
    } 

    return string.Empty; 
} 

Ci si può aspettare il seguente flusso durante il recupero attraverso l'FTP:

220 (vsFTPd 2.2.2) 
user [FTP_USER_NAME] 
331 Please specify the password. 
pass [FTP_PASSWORD] 
230 Login successful. 
SITE CHMOD 755 [FTP_FILE_PATH] 
200 SITE CHMOD command ok.