csharpiconAre you a C# programmer and are you a fan of SnippetCompiler ? If no see why in “Ten Must-Have .NET Tools” (Snippet Compiler is Number One), if yes then you will love the idea of being able to test a C# snippet code by just copying it to the clipboard and then type csc.exe command in Rebol Console (no need to even create a Zero Impact Project).

Just copy and paste the rebol script below in Rebol Console (you can also put it in user.r so as to always have this command available in all rebol sessions):


csc.exe: func[][
  source: read clipboard://
  write %temp.cs source
  csc-path: "C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe"
  command: rejoin [csc-path " /t:exe /checked /debug /out:" "output.exe" " " "temp.cs"]
  call/wait/console command
  call/console "output.exe"
]

Then copy and paste the C# snippet code below:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string firstName = "John";
            string lastName = "Doe";

            Console.WriteLine("Name: " + firstName + " " + lastName);

            Console.WriteLine("Please enter a new first name:");
            firstName = Console.ReadLine();

            Console.WriteLine("New name: " + firstName + " " + lastName);

            Console.ReadLine();
        }
    }
}

You can execute it by typing csc.exe and see the C# compiler output directly within Rebol Console thanks to the /console refinement of the rebol Call command:

csharpcompiler

Console input doesn’t work with Console.ReadKey() and you must replace it with Console.Read();

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace ReflectionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string test = "test";
            Console.WriteLine(test.GetType().FullName);
            Console.WriteLine(typeof(Int32).FullName);
            // Console.ReadKey();
            Console.Read();
        }
    }
}

You can of course test Winforms for example:

using System;
using System.Windows.Forms;

class Class1
{
    public static void Main()
    {
        Form frm1 = new Form();
        Form frm2 = new Form();

        frm1.Text = "frm1";
        frm2.Text = "frm2";

        frm2.Show();
        Application.Run(frm1);
    }
}

This is particularly nice when you encounter an MSDN sample source code like that you want to test immediately like this one:

using System;

public class clsPerson
{
  public  string FirstName;
  public  string MI;
  public  string LastName;
}

class class1
{
   static void Main(string[] args)
   {
      clsPerson p=new clsPerson();
      p.FirstName = "Jeff";
      p.MI = "A";
      p.LastName = "Price";
      System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());
      x.Serialize(Console.Out, p);
      Console.WriteLine();
      Console.ReadLine();
   }
}

For a real-world example found here (Recursive Hierarchical DataSet Techniques):

using System;
using System.Data;
using System.DirectoryServices;
using System.IO;
 class FolderTraverserWithHierarchicalDataSet
 {
  public static DataSet ds=null;
  [STAThread]
  static void Main(string[] args)
  {    

   ds=new DataSet();
   DataTable dt = new DataTable("directories");
   dt.Columns.Add(new DataColumn("DirName"));
    dt.Columns.Add(new DataColumn("Parent"));
      dt.AcceptChanges();
   ds.Tables.Add(dt);
   string InitialPath=@"C:\test\";
   DirectoryInfo dir = new DirectoryInfo(InitialPath);
   TraverseFolder(dir,InitialPath);
   DataTable tbl=ds.Tables[0];
   ds.Relations.Add("SelfReferencing", tbl.Columns["DirName"],
    tbl.Columns["Parent"], false);
   Console.WriteLine("Folder -- Parent");
   foreach (DataRow row in tbl.Rows)
      DisplayRow(row, " ");
   Console.ReadLine();
   }
  private static void TraverseFolder(DirectoryInfo dir,string parentName)
  {
   FileInfo[] filesInDir = dir.GetFiles();
   DirectoryInfo[] directories = dir.GetDirectories();
   foreach(DirectoryInfo newDir in directories)
   {
    object[] rowData ={ newDir.FullName,parentName };
    ds.Tables[0].Rows.Add( rowData);
    TraverseFolder(newDir,newDir.FullName); // recursive call
   }

  }
    static void DisplayRow(DataRow row, string strIndent)
    {
     Console.WriteLine(strIndent + row["DirName"]);
     foreach (DataRow rowChild in row.GetChildRows("SelfReferencing"))
      DisplayRow(rowChild, strIndent + "\t");
    }
 }

Last example which shows that it works even with complex code (code generation) found here (first save source.txt in c:\temp directory):

/*01*/  // Sample of emitting debugging information for dynamic modules
/*02*/  // Reflection emit example adopted from http://blogs.msdn.com/joelpob/archive/2004/01/21/61411.aspx
/*03*/  using System;
/*04*/  using System.Reflection;
/*05*/  using System.Reflection.Emit;
/*06*/  using System.Threading;
/*07*/  using System.Diagnostics.SymbolStore;
/*08*/
/*09*/  public class EmitHelloWorld
/*10*/  {
/*11*/      static void Main(string[] args)
/*12*/      {
/*13*/          // create a dynamic assembly and module
/*14*/          AssemblyName assemblyName = new AssemblyName("HelloWorld");
/*15*/
/*16*/          AppDomain appDomain = Thread.GetDomain();
/*17*/          AssemblyBuilder assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
/*18*/
/*19*/          ModuleBuilder module = assemblyBuilder.DefineDynamicModule("HelloWorld.exe", true); // <-- pass 'true' to track debug info.
/*20*/
/*21*/          // Tell Emit about the source file that we want to associate this with.
/*22*/          Guid emptyGuid;
/*23*/          emptyGuid = Guid.Empty;
/*24*/          ISymbolDocumentWriter doc = module.DefineDocument("Source.txt", emptyGuid, emptyGuid, emptyGuid);
/*25*/
/*26*/          // create a new type to hold our Main method
/*27*/          TypeAttributes typeAttributes;
/*28*/          typeAttributes = TypeAttributes.Public | TypeAttributes.Class;
/*29*/          TypeBuilder typeBuilder = module.DefineType("HelloWorldType", typeAttributes);
/*30*/
/*31*/          // create the Main(string[] args) method
/*32*/          MethodAttributes methodAttributes;
/*33*/          methodAttributes = MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.Public;
/*34*/          Type voidType = Type.GetType("System.Void");
/*35*/          Type[] parameterTypes;
/*36*/          parameterTypes = new Type[] { typeof(string[]) };
/*37*/          MethodBuilder methodbuilder = typeBuilder.DefineMethod("Main", methodAttributes, voidType, parameterTypes);
/*38*/
/*39*/          // generate the IL for the Main method
/*40*/          ILGenerator ilGenerator = methodbuilder.GetILGenerator();
/*41*/          OpCode genericOpCode;
/*42*/
/*43*/          // Create a local variable of type string, and call it xyz
/*44*/          Type stringType = Type.GetType("System.String");
/*45*/          LocalBuilder localXYZ = ilGenerator.DeclareLocal(stringType);
/*46*/          localXYZ.SetLocalSymInfo("xyz"); // Provide name for the debugger.
/*47*/
/*48*/          // Emit sequence point before the IL instructions. This is start line, start col, end line, end column,
/*49*/
/*50*/          // Line 2: xyz = "hello";
/*51*/          ilGenerator.MarkSequencePoint(doc, 2, 1, 2, 100);
/*52*/          genericOpCode = OpCodes.Ldstr;
/*53*/          ilGenerator.Emit(genericOpCode, "Hello world at " + DateTime.Now.ToString());
/*54*/          genericOpCode = OpCodes.Stloc;
/*55*/          ilGenerator.Emit(genericOpCode, localXYZ);
/*56*/
/*57*/          // Line 3: Write(xyz);
/*58*/          Type sysConsoleType = Type.GetType("System.Console");
/*59*/          parameterTypes[0] = typeof(string);
/*60*/          MethodInfo infoWriteLine = sysConsoleType.GetMethod("WriteLine", parameterTypes);
/*61*/          ilGenerator.MarkSequencePoint(doc, 3, 1, 3, 100);
/*62*/          genericOpCode = OpCodes.Ldloc;
/*63*/          ilGenerator.Emit(genericOpCode, localXYZ);
/*64*/          genericOpCode = OpCodes.Call;
/*65*/          ilGenerator.EmitCall(genericOpCode, infoWriteLine, null);
/*66*/
/*67*/          // Line 4: return;
/*68*/          ilGenerator.MarkSequencePoint(doc, 4, 1, 4, 100);
/*69*/          genericOpCode = OpCodes.Ret;
/*70*/          ilGenerator.Emit(genericOpCode);
/*71*/
/*72*/          // bake it
/*73*/          Type helloWorldType = typeBuilder.CreateType();
/*74*/
/*75*/          // run it
/*76*/          MethodInfo mainMethod = helloWorldType.GetMethod("Main");
/*77*/          object[] parameters;
/*78*/          parameters = new string[] { null };
/*79*/          mainMethod.Invoke(null, parameters);
/*80*/
/*81*/          // set the entry point for the application and save it
/*82*/          assemblyBuilder.SetEntryPoint(methodbuilder, PEFileKinds.ConsoleApplication);
/*83*/          assemblyBuilder.Save("HelloWorld.exe");
/*84*/      }
/*85*/  }

Of course you can try with other applications than the C# compiler. This is for example for subversion create repository command:


    repo-directory: to-local-file ask "repo: "
    Subversion.Directory: "C:\Program Files\Subversion\"
    command: rejoin [Subversion.Directory "bin/svnadmin.exe create" " " repo-directory]
    call/wait/console command

The End.

Note: if you want to redirect Rebol’s output to your program see this article.

Bookmark and Share

Recent Articles