Click here to Skip to main content
15,893,622 members
Articles / Programming Languages / C#

C# Script: The Missing Puzzle Piece

Rate me:
Please Sign up or sign in to vote.
4.88/5 (184 votes)
6 Aug 2014MIT24 min read 1.3M   9.4K   531  
An article on a "scripting engine" for the C# language
using System;
using System.Windows.Forms;
using System.IO;
using Microsoft.Win32;
using System.Collections;
using System.Runtime.InteropServices;
using System.Diagnostics;


class Script
{
	static public void Main(string[] args)
	{
		bool install = true;
		if (args.Length != 0 && args[0] == "/u")
		{
			install = false;
		}

		string fileTypeName = null;
		RegistryKey csFile = Registry.ClassesRoot.OpenSubKey(".cs");	

		if (csFile != null)
		{
			fileTypeName = (string)csFile.GetValue("");
		}

		if (install)
		{
			//environment variables
			Console.WriteLine("Update Environment variables...");
			RegistryKey envVars = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", true);
			string path = Environment.GetEnvironmentVariable("PATH");
			path = AddToPath(Environment.CurrentDirectory, path);
			path = AddToPath(Path.Combine(Environment.CurrentDirectory, "lib"), path);

			envVars.SetValue("PATH", path);
			envVars.SetValue("CSSCRIPT_DIR", Environment.CurrentDirectory);
			envVars.Close();

			if (fileTypeName != null)
			{
				if (fileTypeName.ToLower() == "visualstudio.csfile.7.1")
					RunScript("\""+Path.Combine(Environment.CurrentDirectory, @"lib\DebugVS7.1.cs")+"\" /i");
				else if (fileTypeName.ToLower() == "visualstudio.cs.8.0")
					RunScript("\""+Path.Combine(Environment.CurrentDirectory, @"lib\DebugVS8.0.cs")+"\" /i");
				else if (Registry.ClassesRoot.OpenSubKey(".cmbx") != null)
					RunScript("\""+Path.Combine(Environment.CurrentDirectory, @"lib\Debug#D.cs")+"\" /i");
				else
					RunScript("\""+Path.Combine(Environment.CurrentDirectory, @"lib\DebugCLR.cs")+"\" /i");
			}

			Console.WriteLine("Create 'Run as script' shell extension...");
			RegistryKey shell = Registry.ClassesRoot.CreateSubKey(fileTypeName+"\\shell\\Run as script\\command");
			string regValue = "\"" + Path.Combine(Environment.CurrentDirectory, "cscscript.exe") + "\" \"%1\"";
			shell.SetValue("", regValue);
			shell.Close();

			int dwResult = 0;
			bool bReult = SendMessageTimeout( (System.IntPtr)HWND_BROADCAST, WM_SETTINGCHANGE, 0, "Environment", SMTO_ABORTIFHUNG, 5000, dwResult);
			Console.WriteLine("\nC# Script has been installed.");
		}
		else
		{
			//environment variables
			Console.WriteLine("Update Environment variables...");
			RegistryKey envVars = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", true);
			string path = Environment.GetEnvironmentVariable("PATH");
			path = RemoveFromPath(Environment.CurrentDirectory, path);
			path = RemoveFromPath(Path.Combine(Environment.CurrentDirectory, "lib"), path);
			
			envVars.SetValue("PATH", path);
			envVars.DeleteValue("CSSCRIPT_DIR", false);
			envVars.Close();

			//Shell extensions
			RunScript("\""+Path.Combine(Environment.CurrentDirectory, @"lib\Debug#D.cs")+"\" /u");
			RunScript("\""+Path.Combine(Environment.CurrentDirectory, @"lib\DebugVS7.1.cs")+"\" /u");
			RunScript("\""+Path.Combine(Environment.CurrentDirectory, @"lib\DebugVS8.0.cs")+"\" /u");
			RunScript("\""+Path.Combine(Environment.CurrentDirectory, @"lib\DebugCLR.cs")+"\" /u");

			Console.WriteLine("Remove 'Run as script' shell extension...");
			try
			{
				Registry.ClassesRoot.DeleteSubKeyTree(fileTypeName+"\\shell\\Run as script");
			}
			catch{}

			Console.WriteLine("\nC# Script has been uninstalled.");
		}

		
	}

	static private string AddToPath(string dir, string path)
	{
		string[] pathDirs = path.Split(';');
		if (!new ArrayList(pathDirs).Contains(dir))
			return dir + ";" + path;
		else
			return path;
	}
		
	static private string RemoveFromPath(string dir, string path)
	{
		string[] pathDirs = path.Split(';');
		if (new ArrayList(pathDirs).Contains(dir))
		{
			string pathVal = "";
			foreach(string pathDir in pathDirs)
			{
				if (pathDir != "" && pathDir.ToUpper() !=  dir.ToUpper())
				{
					pathVal += pathDir + ";";
				}
			}
			return pathVal;
		}
		else
		{
			return path;
		}
	}

	static void RunScript(string scriptFileCmd)
	{
		Process myProcess = new Process();
		myProcess.StartInfo.FileName = Path.Combine(Environment.CurrentDirectory, "cscscript.exe");
		myProcess.StartInfo.Arguments = "/nl " + scriptFileCmd;
		myProcess.StartInfo.UseShellExecute = false;
		myProcess.StartInfo.RedirectStandardOutput = true;
		myProcess.StartInfo.CreateNoWindow = true;
		myProcess.Start();
		
		string line = null;
		while (null != (line = myProcess.StandardOutput.ReadLine()))
		{
			Console.WriteLine(line);
		}
		myProcess.WaitForExit();
	}

	[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
	[return:MarshalAs(UnmanagedType.Bool)]
	public static extern bool SendMessageTimeout(IntPtr hWnd, int Msg, int wParam, string lParam, int fuFlags, int uTimeout, int lpdwResult);

	public const int HWND_BROADCAST = 0xffff;
	public const int WM_SETTINGCHANGE = 0x001A;
	public const int SMTO_ABORTIFHUNG = 0x0002;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Program Manager
Australia Australia
I was born in Ukraine. After completing the university degree worked there as a Research Chemist. Last 23 years I live in Australia where I've got my second qualification as a Software Engineer.

"I am the lucky one: I do enjoy what I am doing!"

Comments and Discussions