2012-11-21 142 views
2

我有一个奇怪的要求,我被要求在VBScript中编写一个特定的验证脚本,因为它是纯文本的。但是我更喜欢c#。因此,无论如何要在Task Scheduler中安排它,以便编译器将编译程序(源代码以.cs文件形式)并在运行中运行它。编译并运行程序

+0

“in task manager”? –

+0

@AlexeiLevenkov更正 –

回答

1

假设您想要命令行中类似于VBScript/JavaScript的行为,它们的行为与普通EXE文件相似。要查看JS/VBS如何执行,请检查输出assoc .jsftype JSType命令。

基本上你想创建CMD/BAT文件,它将启动CSC来编译你的.cs文件,并且运行CMD文件的所有原始参数的可执行文件。将这个新的CMD文件与.CS文件类型相关联。配置关联检查ftype /?提供了大量信息。

请注意,使用自定义扩展而不是默认.cs(即.cssript)以避免与常规.cs文件混淆是个好主意。

4

你在找什么是CSharpCodeProvider

这允许您从源代码编译或评估C#代码并运行它。它可以在运行中和从另一个进程中完成。

+0

我不这么认为,我需要在飞行中编译uwing csc.exe的代码 –

+0

@AkshayJ:创建一个具有编译代码任务的应用程序。请求任务计划程序在需要时运行该应用程序? – LightStriker

+0

为什么你必须使用csc? CSharpCodeProvider将提供精确的汇编结果 – Martheen

1

有一个很好的例子here提供了源代码。基本上你创建一个运行程序,它是一个执行你的cs文件的exe文件。

跑步者是一个控制台应用程序。您只需将您的CS文件作为参数传入。一个警告是,你必须命名你的课程“CSScript”。但它看起来像下面的课程。该链接使用CSharpCodeProvider类来即时编译您的源代码。

using System; 
using System.Windows.Forms; 

class CScript { 
    public void Main() { 
     // your dynamic code here 
    } 
} 

该示例通过动态地编译传入的CS文件执行源,然后使用反射调用的主要方法。

void ExecuteSource(String sourceText){CSharpCodeProvider codeProvider = new CSharpCodeProvider();

 ICodeCompiler compiler = codeProvider.CreateCompiler(); 
     CompilerParameters parameters = new CompilerParameters(); 
     parameters.GenerateExecutable = false; 
     parameters.GenerateInMemory = true; 
     parameters.OutputAssembly = "CS-Script-Tmp-Junk"; 
     parameters.MainClass = "CScript.Main"; 
     parameters.IncludeDebugInformation = false; 

     foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { 
      parameters.ReferencedAssemblies.Add(asm.Location); 
     } 

     CompilerResults results = compiler.CompileAssemblyFromSource(parameters, sourceText); 

     if (results.Errors.Count > 0) { 
      string errors = "Compilation failed:\n"; 
      foreach (CompilerError err in results.Errors) { 
       errors += err.ToString() + "\n"; 
      } 
      MessageBox.Show(errors, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } else { 
      object o = results.CompiledAssembly.CreateInstance("CScript"); 
      Type type = o.GetType(); 
      MethodInfo m = type.GetMethod("Main"); 
      m.Invoke(o, null); 
      if (File.Exists("CS-Script-Tmp-Junk")) { File.Delete("CS-Script-Tmp-Junk"); } 
     } 
    } 

要调用运行命令如下

CS-SCript.exe yourcsfile.cs 
+0

我不想使用任何编译的代码。一切都应该用纯文本。你的代码在编译任何东西之前需要编译成一个exe文件。 –

+0

不幸的是,你需要一个可执行文件来运行任何脚本文件。对于PHP,您使用php.exe,您使用CScript.exe(或您的system32文件夹中的WScript.exe)。 Windows自动运行vbs文件而不引用它们的唯一原因是因为这些文件类型与CScript.exe可执行文件相关联,并且CScript.exe位于系统路径中。 – nerdybeardo

+0

我想我需要一个批处理文件来调用csc.exe,然后调用它的输出。 –

5

这是很容易做到的一个自编译CMD批处理文件。这是纯文本和可运行的(从我的博客条目 - Dynamically Create an Executable from user-data Text)。

你可以直接调用这个文本文件作为批处理文件,它将作为EXE运行。只需以.CMD扩展名(包括所有C#代码)保存该文件并正常运行即可。

/* This section is run in batch file mode 
%FrameworkDir%%FrameworkVersion%\csc.exe /nologo /out:bootstrap.exe /Reference:%FrameworkDir%%FrameworkVersion%\System.Net.dll "%0" 
goto end 
*/ 

using System; 

static class Program 
{ 
    static void Main(string[] argv) 
    { 
     if (argv.Length > 0) 
      Console.Write(argv[0]); 
     Console.WriteLine(); 
    } 
} 
/* 
:end 

REM ** Run the program 
BootStrap.exe "Hello world!" 
REM */ 

/* */意见让你把批处理文件命令编译本身,当然它们是由C#编译器忽略。批量(CMD)文件将跳过一个错误到下一行,所以这个文件像EXE exept一样运行,它是文本。作为改进,您可能需要将/out目标更改为%TEMP%中的某处。

[已更新]更简单的Hello World示例。

+0

这是否需要.net V4? –

+0

不是。该技术(黑客)适用于.net 1.0 – cirrus

+0

%FrameworkDir%和%FrameworkVersion%从何而来? – Martin