NETCF RPMBootstrap

NETCFRPM is a great tool, but it’s kind of obvious that it was a late addition to the SP1 SDK.  One big problem is the process of deploying.  There are a couple files that must be pushed to the device in order to run, and these are documented only in Steven Pratchner’s blog (maybe elsewhere too, but they aren’t in the RPM readme deployed with the SDK). Don’t get me wrong, I’d rather have it as an afterthought than not at all.


At any rate, without these files you’ll launch RPM, but a device connected via ActiveSync won’t show up in the Device ComboBox. Once deployed, RPM pushes uses RAPI to do it’s work.  What surprises me is that RPM uses RAPI for data transfer, so why doesn’t it use RAPI at the start to find the device and push these files to begin with?  The likely answer is that the team just didn’t have time to get it done.  Well, since my general philosophy is any time that I do the same operation more than three times, it needs to be automated.  This is especially true when I have to go hunting for files, (or even the list of files that I can’t always recall).


So I created a simple bootstrap that does all this for you.  It requires the OpenNETCF.Desktop.Communication library, but that’s about it.  It could be extended to correctly detect target processor architecture (currently just uses ARM), and even do the RAPI provisioning (see Steven Blog entry) for WM 5.0 devices that need it, but at the current moment it works with my devices, so it’s unlikely that I’ll make changes unless I start testing another device.


At any rate, here’s the first cut (download the binary here):


namespace OpenNETCF.RPMBootstrap
{
  class Program
  {
    static void Main(string[] args)
    {
      RapiBootstrap();
    }

    private static OpenNETCF.Desktop.Communication.RAPI m_rapi;

    private static string[] m_filnames = new string[] 
   
      @”netcfrtl.dll”,
      @”netcflaunch.exe”
    };

    private const string SDK_REG_KEY = @”SOFTWAREMicrosoft.NETCompactFrameworkv2.0.0.0InstallRoot”;
    private const string SOURCE_PATH = @”WindowsCEwce400armv4″;
    private const string TARGET_PATH = @”Windows”;
    private const string CE4_ARM_PATH = @”WindowsCEwce400armv4″;
    private const string RPM_PATH = @”binNetCFRPM.exe”;

    public static void RapiBootstrap()
    {
      System.Console.WriteLine(“OpenNETCF RPMBootstrap Bootstrap”);
      System.Console.WriteLine(“================================”);

      m_rapi = new OpenNETCF.Desktop.Communication.RAPI();

      System.Console.WriteLine(“Connecting via ActiveSync…”);
      m_rapi.Connect(true, 10000);

      if (!m_rapi.Connected)
      {
        System.Console.WriteLine(“Connection FAILED”);
        return;
      }
      System.Console.WriteLine(“Connected”);

      // determine SDK install folder
      Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(SDK_REG_KEY);
      string sdkPath = (string)key.GetValue(null);
      key.Close();
      System.Console.WriteLine(“CF 2.0 SDK is installed at:nt” + sdkPath);
      string localFilePath = System.IO.Path.Combine(sdkPath, CE4_ARM_PATH);

      foreach (string fileName in m_filnames)
      {
        string targetFile = System.IO.Path.Combine(TARGET_PATH, fileName);

        if (!m_rapi.DeviceFileExists(targetFile))
        {
            System.Console.WriteLine(string.Format(“{0} not on device”, fileName));
            System.Console.Write(“Copying…”);
            string localFile = System.IO.Path.Combine(localFilePath, fileName);
            m_rapi.CopyFileToDevice(localFile, targetFile);
            System.Console.WriteLine(“ok”);
        }
        else
        {
            System.Console.WriteLine(string.Format(“{0} already on device”, fileName));
        }
      }
      System.Console.Write(“Disconnecting…”);
      m_rapi.Disconnect();
      System.Console.WriteLine(“ok”);

      // find RPM
      string rpmPath = System.IO.Path.Combine(sdkPath, RPM_PATH);

      if (!System.IO.File.Exists(rpmPath))
      {
        System.Console.WriteLine(“Local RPM Binary not found at:rt” + rpmPath);
        return;
      }

      // launch
      System.Console.WriteLine(“Launching RPM…”);
      System.Diagnostics.Process p = System.Diagnostics.Process.Start(rpmPath);
    }
  }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s