The contents of 'AppLoader.cs' is probably what you'll want to use. It essentially grabs a byte array and uses 'System.Reflection' to load it as an executable assembly. This should work, but I see problems with a lack of memory while using the Netduino.
Contents of AppLoader.cs so you don't have to download the Pyxis source:
/* Copyright 2010 Thomas W. Holtquist Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ using System; using System.Collections; using System.IO; using System.Reflection; using System.Runtime; using Microsoft.SPOT; namespace Skewworks.Pyxis.Kernel { internal static class AppLoader { /// <summary> /// The interface for a standlone application /// </summary> interface IApplication { void RunFromBytes(ref ApplicationKey AppKey, ref PyxisAPI APIRef, ref string path, ref string[] parameters); AppIcon GetAppIcon(byte[] bytes); } /// <summary> /// A class that can be loaded across applicaiton domains which /// implements the IApplicaiton interface /// </summary> public class Application : MarshalByRefObject, IApplication { /// <summary> /// we need a defautl consturctor to create an instance of this object /// across an application domain /// </summary> public Application() { } public AppIcon GetAppIcon(byte[] bytes) { // Attempt to execute DLL try { Assembly asm; MethodInfo[] m; asm = Assembly.Load(bytes); if (asm == null) { return new AppIcon(); } Type[] t = asm.GetTypes(); for (var j = 0; j < t.Length; j++) { m = t[j].GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); for (int i = 0; i < m.Length; i++) { if (m[i].Name == "PyxisIcon") { return (AppIcon)m[i].Invoke(asm, null); } } } } catch (Exception e) { // Do nothing } return new AppIcon(); } public void RunFromBytes(ref ApplicationKey AppKey, ref PyxisAPI APIRef, ref string path, ref string[] parameters) { string[] supporting = Directory.GetFiles(Path.GetDirectoryName(path)); for (int i = 0; i < supporting.Length; i++) { if (supporting[i] != path) { try { Assembly.Load(File.ReadAllBytes(supporting[i])); } catch (Exception) { // move along } } } RunAppFromBytes(AppKey, APIRef, File.ReadAllBytes(path), parameters); } private void RunAppFromBytes(ApplicationKey AppKey, PyxisAPI APIRef, byte[] bytes, string[] parameters) { // Attempt to execute DLL try { Assembly asm; MethodInfo[] m; asm = Assembly.Load(bytes); if (asm == null) { return; } Type[] t = asm.GetTypes(); for (var j = 0; j < t.Length; j++) { m = t[j].GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); for (int i = 0; i < m.Length; i++) { if (m[i].Name == "PyxisApp") { AppStartup myStartup = (AppStartup)m[i].Invoke(asm, new object[] { AppKey, APIRef, parameters }); APIRef.ActivateApplication(myStartup, AppKey); } } } } catch (Exception e) { // Do nothing APIRef.Prompt("Failed to launch program.\n" + e.Message, "System Alert", PromptType.OKOnly); } } } #region Variables private static IApplication iApp = null; #endregion /// <summary> /// The executable entry point. /// </summary> public static void LaunchApplication(PyxisAPI APIRef, string path, string[] parameters) { int AppID = GetAppID(APIRef); // Create the Application PyxisApplication PA = new PyxisApplication(); PA.Forms = new ArrayList(); PA.Domain = AppDomain.CreateDomain("PyxisApp" + AppID); PA.Key = new ApplicationKey(AppID, PA.Domain); APIRef._runningApps.Add(PA); // create an instance of the IApplication type // please note that the following call will also load the assembly that contains that type // which we pass as first parameter try { iApp = (IApplication)PA.Domain.CreateInstanceAndUnwrap(typeof(IApplication).Assembly.FullName, typeof(Application).FullName); // Allow system time to catch up System.Threading.Thread.Sleep(100); // Launch the Program iApp.RunFromBytes(ref PA.Key, ref APIRef, ref path, ref parameters); } catch (Exception e) { APIRef.Prompt("Failed to launch application!\n" + e.Message + "\n" + e.InnerException.ToString(), "System Alert", PromptType.OKOnly); APIRef._runningApps.Remove(PA); return; } } public static AppIcon GetApplicationIcon(byte[] bytes) { AppIcon AI; // Create the Domain AppDomain ad = AppDomain.CreateDomain("PyxisAppDesktopIcon"); // create an instance of the IApplication type // please note that the following call will also load the assembly that contains that type // which we pass as first parameter if (iApp == null) { try { iApp = (IApplication)ad.CreateInstanceAndUnwrap(typeof(IApplication).Assembly.FullName, typeof(Application).FullName); } catch (Exception e) { AppDomain.Unload(ad); return new AppIcon(); } } // Get the Icon AI = iApp.GetAppIcon(bytes); // Destroy Domain iApp = null; AppDomain.Unload(ad); return AI; } private static int GetAppID(PyxisAPI APIRef) { bool bConflict = false; int AppID = 0; int i; PyxisApplication PA; while (true) { bConflict = false; for (i = 0; i < APIRef._runningApps.Count; i++) { PA = (PyxisApplication)APIRef._runningApps[i]; if (PA.Domain.FriendlyName == "PyxisApp" + AppID) { bConflict = true; break; } } if (!bConflict) return AppID; AppID++; } } } }
Unrelated side note: Would it be possible to get a 'spoiler' tag added so you can embed long pieces of code in collapsible block?