Вы когда нибудь выполняли массовое переименовывание файлов, или какую-нибудь другую, кажущуюся банально лёгкой, но рутинную задачу? Ни разу не создавали bat'ники, но знаете C#?
Находясь в похожей ситуации, в течение 15 минут было создано довольно простое приложение которое похоже на консоль, но которое понимает C#.
Приложение работает по принципу запоминания кода, и выполнения полученного скрипта. Поддерживается выполнение скрипта из файла, который появляется в директории с приложением при первом выполнении.
Были добавлены базовые команды, которые требуются для создания скрипта через консоль и его выполнения:
!show — показывает запомненный скрипт целиком
!del — удаляет последнюю строку в скрипте
!clear — стирает скрипт
!run — выполнит скрипт и сохранит его содержимое в файл «script.cs»
!runsc — выполнит скрипт из файла «script.cs» (для случая если вы редактируете файл текстовым редактором)
Исходник Program.cs (собственно всего приложения):
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using Microsoft.CSharp;
namespace SharpConsole
{
class Program
{
const string header = @"
using System;
using System.IO;
using System.Net;
using System.Threading;
using System.Collections.Generic;
namespace CScript
{
public class Script
{
public static void ScriptMethod()
{
";
const string footer = @"
}
}
}";
static void Main(string[] args)
{
Console.Title = "SharpConsole";
Console.WriteLine("Welcome to SharpConsole v0.1. Type !help for help.");
List<string> code = new List<string>();
while (true)
{
Console.Write("csharp> ");
string line = Console.ReadLine();
switch (line)
{
case "!run":
{
string program = FormatSources(code);
File.WriteAllText("script.cs", program);
ExecuteScript(program);
}
break;
case "!show":
{
Console.WriteLine();
Console.WriteLine(FormatSources(code));
Console.WriteLine();
}
break;
case "!del":
code.RemoveAt(code.Count - 1);
break;
case "!clear":
{
code = new List<string>();
Console.WriteLine("Done.");
}
break;
case "!runsc":
{
string script = File.ReadAllText("script.cs");
ExecuteScript(script);
}
break;
case "!help":
{
string[] commands = new string[]
{
"1. Type your code and it will be added in script",
"2. !show will shows your code",
"3. !del remove last line from your code",
"4. !clear remove all lines from your code",
"5. !run will run script in memory and writes it in script.cs",
"6. !runsc will run script.cs",
"Have fun! :)",
};
foreach (var str in commands)
Console.WriteLine(str);
}
break;
default:
{
code.Add(" " + line);
}
break;
}
}
}
private static void ExecuteScript(string program)
{
var CSHarpProvider = CSharpCodeProvider.CreateProvider("CSharp");
CompilerParameters compilerParams = new CompilerParameters()
{
GenerateExecutable = false,
GenerateInMemory = true,
};
compilerParams.ReferencedAssemblies.AddRange(new string[]
{
"System.dll",
"System.Core.dll",
"System.Net.dll",
});
var compilerResult = CSHarpProvider.CompileAssemblyFromSource(compilerParams, program);
if (compilerResult.Errors.Count == 0)
{
Console.WriteLine("Executing...");
try
{
compilerResult.CompiledAssembly.GetType("CScript.Script").GetMethod("ScriptMethod").Invoke(null, null);
Console.WriteLine("Done.");
}
catch (Exception e)
{
Console.WriteLine(e.InnerException.Message + "rn" + e.InnerException.StackTrace);
}
}
else
{
foreach (var oline in compilerResult.Output)
Console.WriteLine(oline);
}
}
private static string FormatSources(List<string> code)
{
string program = header;
StringBuilder sb = new StringBuilder(program);
foreach (var sc in code)
{
sb.AppendLine(sc);
}
sb.AppendLine(footer);
return sb.ToString();
}
}
}
По умолчанию, при выполнении скрипта, к сборке подключаются 3 референса:
compilerParams.ReferencedAssemblies.AddRange(new string[]
{
"System.dll",
"System.Core.dll",
"System.Net.dll",
});
Но вы можете добавить другие для ваших нужд.
Проект VS: скачать
Надеюсь это будет кому-нибудь полезно! Буду рад ответить на вопросы.
Автор: Divere