System.Net.FtpClient is now available via nuget
Be sure to read the Documentation page for important information about using this library. It's a quick read and will be worth its weight in gold with regards to effectively using this project in your own!
For developers already using this project, check the commit comments for an update on what's changed and fixed.
Added exception handling in key places to improve reliability by avoiding uncatchable exceptions while cleaning up from a previous exception.
Added new IsDisposed property. Connect() method checks and throws ObjectDisposedException if true.
Added locking to FtpClient.Dispose() to allow a transaction to finish before cleanup.
Merged Daniel Arnold's fix in FtpSocketStream.
Added new UngracefullDisconnect property that allows you to close the control connection without sending QUIT to the server. Use this if the control connection socket is closed/reset by the server pre-maturely when calling Disconnect().
Added new ErrorMessage property to FtpReply that concatenates informational messages along with the final response message together in an effort to provide more meaningful error messages in cases such as this IIS reply which previously would trigger an FtpCommandException with the Message "End"; not helpful.
550-Access is denied.
Win32 Error: Access is denied.
Error details: File system denied the access.
The above error would now be formatted as so:
Access is denied; Win32 Error: Access is denied.; Error details: File system denied the access.; End
Which is immensly more helpful than just "End".
Fixed issues where FtpListItem parsers collection was not initialized until first directory listing. This prevented people from adding their own parsers ahead of time.
Addressed issue with sequencing or PBSZ/PROT commands for data channels, they are now executed after the user has been authenticated instead of before.
Readjusted path cleanup code to remove wild card/glob patterns from the path name when passed to GetListing()
Improved globbing/wildcard cleanup. If the last segment of the path in a file listing contains a glob/wildcard pattern that segment is excluded from the full path in the FtpListItem objects returned. Globs anywhere else in the path are ignored, as there is no straight forward way to expand the full path correctly.
Added comments to async examples to point out potential problem with using statement in typical use cases for the Begin* methods. Added disposed check internally when calling End* methods to see if the connection object has been disposed yet. If it has and you call an End* method, an ObjectDisposed() exception is thrown. This scenario signifies a programming error.
Merged Yuriy Gromchenko changes to address null reference exception in GetListing() method.