• If you are using threads in your application, you must put the MTAThread attribute on the Main() startup method or you will get an exception when accessing certain methods on RemoteDevice instances.
  • If handling the RemoveDeviceManager's DeviceConnected and DeviceDisconnected events and instantiate a RemoteDevice instance when connecting, be sure to dispose of that object when disconnected.
  • If in a forms application, use the RemoteDeviceManager.DeviceConnected and DeviceDisconnected events as they are thread aware.
  • If in a console application, that may be blocking the primary thread, use the UnsafeThreadDeviceConnectedNotice and UnsafeThreadDeviceDisconnectedNotice events as they will come in from a different thread. Do not access any primary thread created instances of RemoteDeviceManager or RemoteDevice or you will get errors. If you need those instances, recreate them in the handlers for those events. See the RAPI2TestM project in the Source Code for an example.

Sample code

Code showing a form that alerts when devices are connected or disconnected.

public partial class Form1 : Form
   private RemoteDeviceManager mgr;

   public Form1()
      mgr = new RemoteDeviceManager();
      mgr.DeviceConnected += mgr_DeviceConnected;
      mgr.DeviceDisconnected += mgr_DeviceDisconnected;

   private void mgr_DeviceConnected(object sender, RemoteDeviceConnectEventArgs e)
      this.OnConnection(e.Device, true);

   private void mgr_DeviceDisconnected(object sender, RemoteDeviceConnectEventArgs e)
      this.OnConnection(e.Device, false);

   private void OnConnection(RemoteDevice dev, bool connected)
      if (connected)
         statusLabel.Text = dev.Name + " is now connected";
         statusLabel.Text = "No devices are connected.";

   private void Form1_Load(object sender, EventArgs e)
      RemoteDevice dev = mgr.Devices.FirstConnectedDevice;
      OnConnection(dev, dev != null);

   private void Form1_FormClosing(object sender, EventArgs e)
      mgr.DeviceConnected -= mgr_DeviceConnected;
      mgr.DeviceDisconnected -= mgr_DeviceDisconnected;

Code exercising the library.

using (RemoteDeviceManager r = new RemoteDeviceManager())
   using (RemoteDevice dev = r.Devices.FirstConnectedDevice)
      if (dev == null)

      // Device information
      Console.WriteLine(dev.Name + ":" + dev.Platform);
      Console.WriteLine("Remaining power: {0}%", dev.PowerStatus.BatteryLifePercent);

      // Start and stop a synchronization

      // Manipulate local and device files & directories
      string myDocs = dev.GetFolderPath(SpecialFolder.MyDocuments);
      string deviceFile = myDocs + @"\Test.txt";
      string localFile = System.IO.Path.GetTempFileName();
      System.IO.File.WriteAllText(localFile, "Testing. 1. 2. 3.");

      RemoteFile.CopyFileToDevice(dev, localFile, deviceFile, true);
      RemoteFile.CopyFileFromDevice(dev, myDocs + @"\Test.txt", localFile, true);
      RemoteDirectory.CreateDirectory(dev, myDocs + @"\TestDir");
      RemoteFile.Copy(dev, myDocs + @"\Test.txt", myDocs + @"\TestDir\test2.txt", true);
      RemoteFile.Move(dev, myDocs + @"\TestDir\test2.txt", myDocs + @"\test2.txt");
      Console.WriteLine(@"{0}: Size={1}, FT={2:u},{3:u},{4:u}, Attr={5}", deviceFile,
         RemoteFile.GetCreationTime(dev, deviceFile),
         RemoteFile.GetLastAccessTime(dev, deviceFile),
         RemoteFile.GetLastWriteTime(dev, deviceFile),
         RemoteFile.GetAttribtues(dev, deviceFile));
      RemoteFile.Delete(dev, myDocs + @"\test2.txt");
      RemoteDirectory.Delete(dev, myDocs + @"\TestDir");

      Console.WriteLine("Directory listing:");
      foreach (string fn in RemoteDirectory.GetFiles(dev, myDocs, "*"))
         Console.WriteLine("   " + fn);

      dev.CreateShortcut("Test", @"\Temp\Test.txt");
      Console.WriteLine("Test shortcut = " + dev.GetShortcutTarget("Test"));
      RemoteFile.Delete(dev, "Test");

      // Manipulate the registry
      using (RemoteDevice.DeviceRegistryKey hKey = dev.DeviceRegistryLocalMachine.OpenSubKey("Ident"))
         Console.WriteLine("Device Name: " + hKey.GetValue("Name", string.Empty).ToString());
         using (RemoteDevice.DeviceRegistryKey hKey2 = hKey.CreateSubKey("Test"))
            hKey2.SetValue("StrVal", "test");
            hKey2.SetValue("DWVal", (int)55);
            hKey2.SetValue("ByVal", new byte[] { 0, 1, 2, 3, 4, 5, 6 });
            hKey2.SetValue("MStrVal", new string[] { "str1", "str2" });
            foreach (string item in hKey2.GetValueNames())
             object o = hKey2.GetValue(item, string.Empty);
             if (o is byte[])
               o = string.Join(", ", Array.ConvertAll<byte, string>(o as byte[], delegate(byte b) { return b.ToString(); }));
             if (o is string[])
               o = string.Join(", ", o as string[]);
             Console.WriteLine("Test\\{0} = {1}", item, o);

      // Start a remote process
      dev.CreateProcess(@"\Windows\calendar.exe", null, ProcessCreationFlags.None);

Last edited May 15, 2012 at 3:55 AM by dahall, version 8


dahall Mar 31 at 3:52 PM 
This library (which isn't being maintained by me any longer) is designed to be used on the PC to control a device.

EScatalpa Mar 30 at 1:55 PM 
I am experienced in programming, but new to C#. Does all of this coding go into a new program that should be run on the user's PC? Or is some or all of this logic supposed to be on the run on the remote device? Please advise.

superkew Aug 19, 2011 at 7:48 AM 
Thank you for making this wrapper and the source code. It is exactly what I have been looking for!