Friedel Megen van

from the Microsoft Innovation Center in Aachen, Germany has contributed FTP support to the .NET Micro Framework.  The feature has been integrated with the CodePlex project and is available there.  The implementation follows the standard implementation.  The support for client and server are through the FtpWebRequest and FtpListener classes.  Here is a sample FTP app – take a peek at how easy this is. 

Contribution activity is picking up.  Is there something that you have thought the .NET Micro Framework  needs?  Grab your friends and get to it!! :-)

using System.Collections;
using System.IO;
using System.Net;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Net;
using Microsoft.SPOT.Net.Ftp;

namespace FtpServerSample
{
    public class MyFtpServer
    {
        // the standard emulator has two volumes: "ROOT" and "WINFS"
        static string virtualROOT = "/pub/config/root/";
        static string virtualWINFS = "/pub/config/winfs/";

        //--//

        public static void Main()
        {
            SetupFiles();

            ProcessClientRequest();
        }

        private static void ProcessClientRequest()
        {
            Debug.Print("Welcome to the FTP Service.");

            FtpListener.AuthenticationEvent += (object sender, UserAuthenticatorArgs e) =>
            {
                if (e.User == "anonymous")
                {
                    Debug.Print("hi anonymous");
                    e.Result = UserAuthenticationResult.Approved;
                }
            };

            // all other directories will be handled by the standard listener, on both volumes
            FtpListener listener_root = new FtpFilesystemListener(virtualROOT, @"\ROOT\");
            listener_root.Start();
            FtpListener listener_winfs = new FtpFilesystemListener(virtualWINFS, @"\WINFS\");
            listener_winfs.Start();

            System.Threading.Thread.Sleep(Timeout.Infinite);
        }

        // this method writes some files in the ROOT and WINFS volumes of the standard emulator
        // there will be a "special" directory that will be associated with the main program loop handler
        private static void SetupFiles()
        {
            // Format
            VolumeInfo[] vis = VolumeInfo.GetVolumes();

            if (vis.Length == 0)
            {
                throw new Exception("Cannot run this sample because this emulator does not support a file system");
            }

            for (int i = 0; i < vis.Length; i++)
            {
                if (vis[i].Name.ToLower() == "root")
                {
                    if (!vis[i].IsFormatted)
                    {
                        vis[i].Format(0);
                    }
                    break;
                }
                else if (vis[i].Name.ToLower() == "winfs")
                {
                    if (!vis[i].IsFormatted)
                    {
                        vis[i].Format(0);
                    }
                    break;
                }
            }

            // Create some files in each volume
            // we will prefix files with the volume name to make them recognizable
            Hashtable files = new Hashtable();
            files.Add("SampleReadme.txt", "In this directory you will find the very source of this program.");
            files.Add("SampleCode.cs", "Check http://netmf.codeplex.com for the actual (open) sources!");
            for (int volIdx = 0; volIdx < vis.Length; ++volIdx)
            {
                // all files go into the data directory, duplicated in each volume
                Directory.CreateDirectory(vis[volIdx].Name + @"\" + "data");
                // the same file will also be duplicated inside a special directory in each volume
                Directory.CreateDirectory(vis[volIdx].Name + @"\" + "special");

                foreach (string fileName in files.Keys)
                {
                    //
                    string path = @"\" + vis[volIdx].Name + @"\special\" + vis[volIdx].Name + "_special_" + fileName;
                    using (StreamWriter sw = new StreamWriter(new FileStream(path, FileMode.Create)))
                    {
                        sw.Write((string)files[fileName]);
                    }
                }
                foreach (string fileName in files.Keys)
                {
                    string path = @"\" + vis[volIdx].Name + @"\data\" + vis[volIdx].Name + "_" + fileName;
                    using (StreamWriter sw = new StreamWriter(new FileStream(path, FileMode.Create)))
                    {
                        sw.Write((string)files[fileName]);
                    }
                }
            }
        }
    }
}