When I needed to add automated file transfer to and from a remote FTP server, I found any number of excellent, clear, well structured and beautifully documented examples; both commercial and private - and all useless to me! Our Internet access is over a rather 'well throttled' firewall that seems to only have port 21 left open. The classic sockets approach to implementing an FTP client will open a 'command channel' over port 21 (default FTP port), allowing the client to sign-on etc., but as soon as any data is required to flow a second, 'data channel' must be opened (default port 20). Active or passive, I could not establish a second channel through our firewall.
I would have given up at this stage and started to look for a new employer, when it occurred to me that the Windows Explorer was perfectly able to exchange data with all and any FTP server I pointed it at... this runs over exactly the same firewall, so something strange and not just a bit magical is happening here. It turns out this bit of magic is to be found in the WinInet.dll. I am still not quite sure how the WinInet.dll works, it seems to sweet talk the firewall into opening just a small chink in its armor - but the important thing is that it works!
In order to use the FTP features of WinInet.dll, I needed to encapsulate the API in C#. This was mostly pain free, except for the marshaling of string parameters - it is documented, but you have to know what to look for. Having finished this, I figured I could offer it to the C# community; maybe I will save somebody many frustrating hours trying to bore through his corporate firewall, but also because I am quite sure I am going to get a bunch of really helpful feedback... for example, why does a successful file deletion return error code 2 = file not found? Ah, the mysteries of API programming.
I have included a very minimal console application to test the basic functionality - the default URL is ftp://ftp.microsoft.com/, users are invited to replace this with their own target.