Re: FTP CD command
- From: Tom Shelton <tom_shelton@xxxxxxxxxxxxxxxxxx>
- Date: Mon, 23 Feb 2009 13:15:36 -0800
On 2009-02-23, Tom Shelton <tom_shelton@xxxxxxxxxxxxxxxxxx> wrote:
On 2009-02-23, Lou <lou.garvin@xxxxxxxxxxx> wrote:
At this point NO suggestion is stupid.
-I'll look into it since no other solution works.
Thanks for the not-so-stupid suggestion.
-Lou
It's C# and it was written a long time ago :) But, it did work.
http://groups.google.com/group/microsoft.public.dotnet.languages.vb/browse_frm/thread/5f5e891f45ffcf62?hl=en&ie=UTF-8&q=simpleftp+author:tom+author:shelton#b36f43bd9b436da2
If you need async operations, then call this on a background thread or you
could with a bit of work implement the WinInet async methods...
Just realized that was a really old version! Here is one that you can
actually do a simple directory listing:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace FireAnt.Net.Ftp
{
internal static class WinInet
{
public const int INTERNET_OPEN_TYPE_PRECONFIG = 0;
public const int INTERNET_OPEN_TYPE_DIRECT = 1;
public const int INTERNET_OPEN_TYPE_PROXY = 3;
public const short INTERNET_DEFAULT_FTP_PORT = 21;
public const int INTERNET_SERVICE_FTP = 1;
public const int FTP_TRANSFER_TYPE_ASCII = 0x01;
public const int FTP_TRANSFER_TYPE_BINARY = 0x02;
public const int GENERIC_WRITE = 0x40000000;
public const int GENERIC_READ = unchecked ( (int)0x80000000 );
public const int MAX_PATH = 260;
public const int ERROR_INSUFFICIENT_BUFFER = 122;
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern IntPtr InternetOpen (
string lpszAgent,
int dwAcessType,
string lpszProxyName,
string lpszProxyBypass,
int dwFlags );
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern IntPtr InternetConnect (
IntPtr hInternet,
string lpszServerName,
short nServerPort,
string lpszUserName,
string lpszPassword,
int dwService,
int dwFlags,
ref int dwContext );
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern bool FtpGetCurrentDirectory (
IntPtr hConnect,
StringBuilder lpszCurrentDirectory,
ref int lpdwCurrentDirectory );
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern bool FtpSetCurrentDirectory (
IntPtr hConnect,
string lpszCurrentDirectory );
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern IntPtr FtpOpenFile (
IntPtr hConnect,
string lpszFileName,
int dwAccess,
int dwFlags,
out int dwContext );
[DllImport ( "wininet.dll", SetLastError = true )]
public static extern bool InternetWriteFile (
IntPtr hFile,
[MarshalAs ( UnmanagedType.LPArray )] byte[] lpBuffer,
int dwNumberOfBytesToWrite,
out int lpdwNumberOfBytesWritten );
[DllImport ( "wininet.dll", SetLastError = true )]
public static extern bool InternetReadFile (
IntPtr hFile,
[MarshalAs ( UnmanagedType.LPArray )] byte[] lpBuffer,
int dwNumberOfBytesToRead,
out int lpdwNumberOfBytesRead
);
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern bool InternetCloseHandle ( IntPtr hInternet );
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern bool FtpPutFile (
IntPtr hConnect,
string lpszLocalFile,
string lpszNewRemoteFile,
int dwFlags,
out int dwContext );
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern bool FtpGetFile (
IntPtr hConnect,
string lpszRemoteFile,
string lpszLocalFile,
bool failIfExists,
int dwFlagsAttributes,
int dwFlags,
out int dwContext );
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern bool FtpCreateDirectory (
IntPtr hConnect,
string lpszDirectory );
// BOOL FtpCommand(
// __in HINTERNET hConnect,
// __in BOOL fExpectResponse,
// __in DWORD dwFlags,
// __in LPCTSTR lpszCommand,
// __in DWORD_PTR dwContext,
// __out HINTERNET *phFtpCommand
//);
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern IntPtr FtpFindFirstFile (
IntPtr hConnect,
string lpszSearchFile,
out WIN32_FIND_DATA lpFindFileData,
uint dwFlags,
out int dwContext );
[DllImport("wininet.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool InternetFindNextFile (
IntPtr hFind,
out WIN32_FIND_DATA lpvFindData);
[DllImport ( "wininet.dll", CharSet = CharSet.Auto, SetLastError = true )]
public static extern bool InternetGetLastResponseInfo (
out int lpdwError,
StringBuilder lpszBuffer,
ref int lpdwBufferLength );
[StructLayout(LayoutKind.Sequential)]
public struct FILETIME
{
public uint dwLowDateTime;
public uint dwHighDateTime;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct WIN32_FIND_DATA
{
public uint dwFileAttributes;
public FILETIME ftCreationTime;
public FILETIME ftLastAccessTime;
public FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs ( UnmanagedType.ByValTStr, SizeConst = MAX_PATH )]
public string cFileName;
[MarshalAs ( UnmanagedType.ByValTStr, SizeConst = 14 )]
public string cAlternateFileName;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.IO;
namespace FireAnt.Net.Ftp
{
[Flags ()]
public enum AccessMode
{
Read = WinInet.GENERIC_READ,
Write = WinInet.GENERIC_WRITE,
}
public enum TransferMode
{
Ascii = WinInet.FTP_TRANSFER_TYPE_ASCII,
Binary = WinInet.FTP_TRANSFER_TYPE_BINARY,
}
public class FtpFileInfo
{
internal FtpFileInfo ( WinInet.WIN32_FIND_DATA info )
{
this.Name = info.cFileName;
this.IsDirectory = Convert.ToBoolean ( info.dwFileAttributes & 0x10 );
}
public string Name { get; internal set; }
public bool IsDirectory { get; internal set; }
}
/// <summary>
/// Summary description for SimpleFTP.
/// </summary>
public sealed class SimpleFtp : IDisposable
{
private IntPtr internet;
private IntPtr connection;
private IntPtr fileHandle;
private int context;
private const int BUFFER_SIZE = 2048;
public SimpleFtp ( string host, string userName, string password )
{
internet = WinInet.InternetOpen (
null,
WinInet.INTERNET_OPEN_TYPE_DIRECT,
null,
null,
0 );
if ( internet == IntPtr.Zero )
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
connection = WinInet.InternetConnect (
this.internet,
host,
WinInet.INTERNET_DEFAULT_FTP_PORT,
userName,
password,
WinInet.INTERNET_SERVICE_FTP,
0,
ref this.context );
if ( connection == IntPtr.Zero )
{
WinInet.InternetCloseHandle ( this.internet );
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
}
~SimpleFtp ()
{
this.CleanUp ();
}
void IDisposable.Dispose ()
{
this.CleanUp ();
GC.SuppressFinalize ( this );
}
public string CurrentDirectory
{
get
{
StringBuilder path = new StringBuilder ( 260 );
int bufferSize = path.Capacity;
if ( !WinInet.FtpGetCurrentDirectory ( this.connection, path, ref bufferSize ) )
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
return path.ToString ();
}
set
{
if ( !WinInet.FtpSetCurrentDirectory ( this.connection, value ) )
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
}
}
public void Close ()
{
( (IDisposable)this ).Dispose ();
}
public void OpenFile ( string fileName, AccessMode access, TransferMode mode )
{
this.fileHandle = WinInet.FtpOpenFile ( this.connection, fileName, (int)access, (int)mode, out this.context );
if ( this.fileHandle == IntPtr.Zero )
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
}
public void CloseFile ()
{
if ( this.fileHandle != IntPtr.Zero )
{
if ( WinInet.InternetCloseHandle ( this.fileHandle ) )
{
this.fileHandle = IntPtr.Zero;
}
else
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
}
}
public int WriteFile ( string buffer )
{
byte[] bytes = new ASCIIEncoding ().GetBytes ( buffer );
return this.WriteFile ( bytes );
}
public int WriteFile ( byte[] buffer )
{
int byteCount;
if ( !WinInet.InternetWriteFile ( this.fileHandle, buffer, buffer.Length, out byteCount ) )
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
return byteCount;
}
public bool ReadFile ( out string buffer )
{
// clear the buffer...
buffer = string.Empty;
// read from the file
int bytesRead;
byte[] readBuffer = new byte[SimpleFtp.BUFFER_SIZE];
bool success = WinInet.InternetReadFile ( this.fileHandle, readBuffer, readBuffer.Length, out bytesRead );
// the call failed!
if ( !success )
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
// we got some data, so convert it for the return...
if ( bytesRead != 0 )
{
buffer = Encoding.ASCII.GetString ( readBuffer, 0, bytesRead );
}
return ( bytesRead != 0 ) ? true : false;
}
public bool ReadFile ( byte[] buffer )
{
int bytesRead;
bool success = WinInet.InternetReadFile ( this.fileHandle, buffer, buffer.Length, out bytesRead );
if ( !success )
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
return ( bytesRead != 0 ) ? true : false;
}
public void GetFile ( string localFile, string remoteFile, bool fail )
{
GetFile ( localFile, remoteFile, TransferMode.Ascii, fail );
}
public void GetFile ( string localFile, string remoteFile, TransferMode mode, bool fail )
{
if ( !WinInet.FtpGetFile ( connection, remoteFile, localFile, fail, 0, (int)mode, out context ) )
{
int errorCode = Marshal.GetLastWin32Error ();
if ( errorCode == 12003 )
{
int realError;
int capacity = 1024;
StringBuilder buffer = new StringBuilder ( capacity );
while ( !WinInet.InternetGetLastResponseInfo ( out realError, buffer, ref capacity ) )
{
if ( Marshal.GetLastWin32Error () == WinInet.ERROR_INSUFFICIENT_BUFFER )
{
buffer = new StringBuilder ( ++capacity );
}
else
{
throw new Exception ( "Unable to retrieve extended error information." );
}
}
throw new Win32Exception ( realError, buffer.ToString () );
}
else
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
}
}
public void CreateDirectory ( string remoteDir )
{
if ( !WinInet.FtpCreateDirectory ( connection, remoteDir ) )
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
}
public void PutFile ( string localFile, string remoteFile )
{
this.PutFile ( localFile, remoteFile, TransferMode.Ascii );
}
public void PutFile ( string localFile, string remoteFile, TransferMode mode )
{
if ( !WinInet.FtpPutFile ( this.connection, localFile, remoteFile, (int)mode, out this.context ) )
{
throw new Win32Exception ( Marshal.GetLastWin32Error () );
}
}
public FtpFileInfo[] Dir (string mask)
{
List<FtpFileInfo> files = new List<FtpFileInfo> ();
WinInet.WIN32_FIND_DATA data;
IntPtr hFind = WinInet.FtpFindFirstFile ( this.connection, null, out data, 0, out this.context );
if ( hFind != IntPtr.Zero )
{
files.Add( new FtpFileInfo(data) );
while ( WinInet.InternetFindNextFile ( hFind, out data ) )
{
files.Add( new FtpFileInfo(data) );
}
}
WinInet.InternetCloseHandle ( hFind );
return files.ToArray ();
}
private void CleanUp ()
{
if ( this.fileHandle != IntPtr.Zero )
{
WinInet.InternetCloseHandle ( this.fileHandle );
}
if ( this.connection != IntPtr.Zero )
{
WinInet.InternetCloseHandle ( this.connection );
}
if ( this.internet != IntPtr.Zero )
{
WinInet.InternetCloseHandle ( this.internet );
}
}
}
}
Simple example of use after compiling to a class library:
Using ftp As New SimpleFtp(myhost, myuser, mypassword)
Console.WriteLine (ftp.CurrentDirectory)
For Each info In ftp.Dir(String.Empty)
Console.WriteLine("{0}, IsDirectory={1}", info.Name, info.IsDirectory)
Next
End Using
--
Tom Shelton
.
- References:
- FTP CD command
- From: Lou
- Re: FTP CD command
- From: Michel Posseth [MCP]
- Re: FTP CD command
- From: Lou
- Re: FTP CD command
- From: Michel Posseth [MCP]
- Re: FTP CD command
- From: Lou
- Re: FTP CD command
- From: Michel Posseth [MCP]
- Re: FTP CD command
- From: Clive Lumb
- Re: FTP CD command
- From: Lou
- Re: FTP CD command
- From: Tom Shelton
- FTP CD command
- Prev by Date: Re: FTP CD command
- Next by Date: Re: How to know all forms Opened in current AppDomain?
- Previous by thread: Re: FTP CD command
- Next by thread: Re: FTP CD command
- Index(es):
Relevant Pages
|
Loading