Windows shell scripts in C#

Stephane Rolland picture Stephane Rolland · Jun 27, 2011 · Viewed 8.3k times · Source

I was pretty sure that some months ago I read about the possibility to launch Windows scripts not only the usual .bat, but also .js, .vbs and .cs !

I was willing to try windows scripts in C# .cs files this morning, but I can't happen to find any references on the web. All CS/C# scripts stuffs seem to be 3rd parties.

Do you have any knowledge reference/link for command-line scripts in C# for Windows, pure microsoft style ?

Yes, that would mean dynamic C# compilation... so maybe I am all wrong thinking it is possible. Just tell me.

Answer

Brian Chavez picture Brian Chavez · May 1, 2013

Option A

If you're looking for a true C# development experience, try CS-Script.

You can use comment directives to use third-party libraries and include other C# scripts.

//css_nuget dotnetzip
using Ionic.Zip;
using System;

class Script
{
    static public void Main()
    {
        using(ZipFile zip = new ZipFile())
        {
            zip.AddFile("app.exe");
            zip.AddFile("readme.exe");
            zip.Save("app.zip");
        }
    }
}

Personally, I prefer CS-Script because I've noticed 1) faster script start-up times compared to scriptcs below and 2) no issues using namespaces. C# you write here is real C#. The VS IDE just works.

Option B

Alternatively, take a look at scriptcs

http://scriptcs.net/

You can also use VS to write some simple scripts:

 //MyScript.Main()

 public class MyScript{
     public static void Main(){
          Console.WriteLine("hello world.");
     }
 }

When you're ready to run scripts with scriptcs, remove the // comment.

C:\> scriptcs myscript.cs

Also, you can use nuget to install 3rd party packages like NLog

C:\> scriptcs -install NLog

One problem I found with scriptcs is the inability to use namespaces. scriptcs under the hood uses the Roslyn compiler for compiling C# scripts. Unfortunately, Roslyn has a leaky design implementation when compiling scripts. In particular, in order for Roslyn to handle REPL type of use cases, each script compilation uses nested classes to store variables and state. Since you can't have a namespace in a nested class using namespaces with scriptcs will fail. So if you try to import loose *.cs files that contain namespaces (like domain objects from a VS project), you'll need to strip out the namespaces.

This awful design decision left a bad impression on me, so I've mostly used cs-script Option A until the Roslyn team supports namespaces.