/// <summary> /// Compiles some source code and returns the bytes that were contained in the compiled DLL file. /// /// Each time that this function is called, it will be compiled in a different directory. /// /// The default flags are "/shared /deterministic+ /nologo /t:library". /// </summary> /// <param name="source"> The source code for the program that will be compiled </param> /// <param name="additionalFlags"> A string containing any additional compiler flags </param> /// <returns> An array of bytes that were read from the compiled DLL</returns> private byte[] CompileAndGetBytes(string source, string additionalFlags, out string finalFlags) { // Setup var tempDir = Temp.CreateDirectory(); var srcFile = tempDir.CreateFile("test.cs").WriteAllText(source).Path; var outFile = srcFile.Replace("test.cs", "test.dll"); finalFlags = $"{ _flags } { additionalFlags } /pathmap:{tempDir.Path}=/"; try { var errorsFile = srcFile + ".errors"; // Compile var result = ProcessUtilities.Run("cmd", $@"/C ""{CompilerServerUnitTests.CSharpCompilerClientExecutable}"" { finalFlags } { srcFile } /out:{ outFile } > { errorsFile }"); if (result.ExitCode != 0) { var errors = File.ReadAllText(errorsFile); AssertEx.Fail($"Deterministic compile failed \n stderr: { result.Errors } \n stdout: { errors }"); } var bytes = File.ReadAllBytes(outFile); AssertEx.NotNull(bytes); return(bytes); } finally { File.Delete(srcFile); File.Delete(outFile); } }
internal static void DoMerge(string command) { if (ProcessUtilities.Run(CodeCoverageUtilities.coverageDataToolPath, command, ProcessWindowStyle.Hidden, false) != 0) { throw new ApplicationException("Code coverage Merge operation failed:" + coverageDataToolPath + " " + command); } }
public void DefaultUsings() { var source = @" dynamic d = new ExpandoObject(); Process p = new Process(); Expression<Func<int>> e = () => 1; var squares = from x in new[] { 1, 2, 3 } select x * x; var sb = new StringBuilder(); var list = new List<int>(); var stream = new MemoryStream(); await Task.Delay(10); Console.Write(""OK""); "; var cwd = Temp.CreateDirectory(); cwd.CreateFile("a.csx").WriteAllText(source); var result = ProcessUtilities.Run(CsiPath, "a.csx", workingDirectory: cwd.Path); AssertEx.AssertEqualToleratingWhitespaceDifferences("OK", result.Output); Assert.False(result.ContainsErrors); }
protected void VerifyValues(string props, string[] targets, string[] expressions, string[] expectedResults) { if (!string.IsNullOrEmpty(props)) { EmitTestHelperProps(ObjDir.Path, ProjectFileName, props); } var evaluationResultsFile = EmitTestHelperTargets(ObjDir.Path, OutDir.Path, ProjectFileName, expressions); var targetsArg = string.Join(";", targets.Concat(new[] { "Test_EvaluateExpressions" })); var testBinDirectory = Path.GetDirectoryName(typeof(DotNetSdkTests).Assembly.Location); var binLog = Path.Combine(ProjectDir.Path, $"build{_logIndex++}.binlog"); // RoslynTargetsPath is a path to the built-in Roslyn compilers in the .NET SDK. // For testing we are using compilers from custom location (this emulates usage of Microsoft.Net.Compilers package. // The core targets should be imported from CSharpCoreTargetsPath and VisualBasicCoreTargetsPath and the compiler tasks from the same location. var buildResult = ProcessUtilities.Run(DotNetPath, $@"msbuild ""{Project.Path}"" /t:{targetsArg} /p:RoslynTargetsPath=""<nonexistent directory>"" /p:Configuration={Configuration} /bl:""{binLog}""", additionalEnvironmentVars: EnvironmentVariables); Assert.True(buildResult.ExitCode == 0, $"Failed with exit code {buildResult.ExitCode}: {buildResult.Output}"); var evaluationResult = File.ReadAllLines(evaluationResultsFile).Select(l => (l != EmptyValueMarker) ? l : ""); AssertEx.Equal(expectedResults, evaluationResult); }
/// <summary> /// Merges Code coverage results for a machine into a single set of results /// </summary> /// <param name="executionLogPath"></param> internal static void MergeSingleMachineResults(DirectoryInfo executionLogPath) { FileInfo[] covDatas = executionLogPath.GetFiles("*.covdata", SearchOption.AllDirectories); string coverageMergePath = Path.Combine(executionLogPath.FullName, "CodeCoverage"); if (Directory.Exists(coverageMergePath)) { Directory.Delete(coverageMergePath, true); } Directory.CreateDirectory(coverageMergePath); //Specify inputs to merge StringBuilder mergeInput = new StringBuilder(); foreach (FileInfo covData in covDatas) { mergeInput.AppendLine(covData.FullName); } string inputsPath = Path.Combine(executionLogPath.FullName, "CoverageInputs.txt"); File.WriteAllText(inputsPath, mergeInput.ToString()); string command = "/I @" + inputsPath + " /O " + coverageMergePath; ExecutionEventLog.RecordStatus("Merging Coverage results: " + coverageDataToolPath + " " + command); if (ProcessUtilities.Run(coverageDataToolPath, command) != 0) { throw new ApplicationException("Code Coverage Merging failed"); } ExecutionEventLog.RecordStatus("Clearing Redundant inputs coverage data."); DeleteCoverageData(covDatas); }
public void CurrentWorkingDirectory_Change() { var dir = Temp.CreateDirectory(); dir.CreateFile("a.csx").WriteAllText(@"int X = 1;"); dir.CreateFile("C.dll").WriteAllBytes(TestResources.General.C1); var result = ProcessUtilities.Run(CsiPath, "", stdInput: $@"#load ""a.csx"" #r ""C.dll"" Directory.SetCurrentDirectory(@""{dir.Path}"") #load ""a.csx"" #r ""C.dll"" X new C() Environment.Exit(0) "); AssertEx.AssertEqualToleratingWhitespaceDifferences($@" Microsoft (R) Visual C# Interactive Compiler version {s_compilerVersion} Copyright (C) Microsoft Corporation. All rights reserved. Type ""#help"" for more information. > > > > > > 1 > C {{ }} > ", result.Output); AssertEx.AssertEqualToleratingWhitespaceDifferences($@" (1,7): error CS1504: Source file 'a.csx' could not be opened -- Could not find file. (1,1): error CS0006: Metadata file 'C.dll' could not be found ", result.Errors); Assert.Equal(0, result.ExitCode); }
public void ReferenceSearchPaths_Sdk() { var cwd = Temp.CreateDirectory(); cwd.CreateFile("a.csx").WriteAllText(@"Console.Write(typeof(DataSet).Name);"); var result = ProcessUtilities.Run(CsiPath, "/r:System.Data.dll /u:System.Data;System a.csx", workingDirectory: cwd.Path); AssertEx.AssertEqualToleratingWhitespaceDifferences("DataSet", result.Output); Assert.False(result.ContainsErrors); }
/// <summary> /// This is needed for merge to upload cc data to server /// </summary> /// <param name="logDirectory"></param> /// <param name="codeCoverageConnection"></param> internal static void UploadCodeCoverage(DirectoryInfo logDirectory, string codeCoverageConnection) { string codeCoveragePath = Path.Combine(logDirectory.FullName, "CodeCoverage"); string command = "/I \"" + codeCoveragePath + "\" /DB \"" + codeCoverageConnection + "\""; //Run this command in console- we don't do this during execution if (ProcessUtilities.Run(CodeCoverageUtilities.coverageDataToolPath, command, ProcessWindowStyle.Hidden, false) != 0) { throw new ApplicationException("Failed to upload code coverage results to server with:" + coverageDataToolPath + " " + command); } }
internal static void UploadResults(DirectoryInfo executionLogPath, string connectionString) { FileInfo[] covDatas = executionLogPath.GetFiles("*.covdata", SearchOption.AllDirectories); string coverageMergePath = Path.Combine(executionLogPath.FullName, "CodeCoverage"); if (!Directory.Exists(coverageMergePath)) { Directory.CreateDirectory(coverageMergePath); } ProcessUtilities.Run(coverageToolPath, "/Save /db " + connectionString); }
private ProcessResult RunCommandLineCompiler( string compilerPath, string arguments, string currentDirectory, IEnumerable <KeyValuePair <string, string> > additionalEnvironmentVars = null) { return(ProcessUtilities.Run( compilerPath, arguments, currentDirectory, additionalEnvironmentVars: AddForLoggingEnvironmentVars(additionalEnvironmentVars))); }
public void CurrentWorkingDirectory1() { var dir = Temp.CreateDirectory(); dir.CreateFile("a.csx").WriteAllText(@"Console.Write(Environment.CurrentDirectory + ';' + typeof(C).Name);"); dir.CreateFile("C.dll").WriteAllBytes(TestResources.General.C1); var result = ProcessUtilities.Run(CsiPath, "/r:C.dll a.csx", workingDirectory: dir.Path); AssertEx.AssertEqualToleratingWhitespaceDifferences(dir.Path + ";C", result.Output); Assert.False(result.ContainsErrors); }
public void CurrentWorkingDirectory_Change() { var dir = Temp.CreateDirectory(); dir.CreateFile("a.csx").WriteAllText(@"int X = 1;"); dir.CreateFile("C.dll").WriteAllBytes(TestResources.General.C1); var result = ProcessUtilities.Run( CsiPath, "", stdInput: $@"#load ""a.csx"" #r ""C.dll"" Directory.SetCurrentDirectory(@""{dir.Path}"") #load ""a.csx"" #r ""C.dll"" X new C() Environment.Exit(0) " ); var expected = $@" {string.Format(CSharpScriptingResources.LogoLine1, s_compilerVersion)} {CSharpScriptingResources.LogoLine2} {ScriptingResources.HelpPrompt} > > > > > > 1 > C {{ }} > "; // The German translation (and possibly others) contains an en dash (0x2013), // but csi.exe outputs it as a hyphen-minus (0x002d). We need to fix up the // expected string before we can compare it to the actual output. expected = expected.Replace((char)0x2013, (char)0x002d); // EN DASH -> HYPHEN-MINUS AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, result.Output); AssertEx.AssertEqualToleratingWhitespaceDifferences( $@" (1,7): error CS1504: {string.Format(CSharpResources.ERR_NoSourceFile, "a.csx", CSharpResources.CouldNotFindFile)} (1,1): error CS0006: {string.Format(CSharpResources.ERR_NoMetadataFile, "C.dll")} ", result.Errors ); Assert.Equal(0, result.ExitCode); }
public DotNetSdkTestBase() { Assert.True(s_dotnetInstallDir != null, $"SDK not found. Use {nameof(ConditionalFactAttribute)}(typeof({nameof(DotNetSdkAvailable)})) to skip the test if the SDK is not found."); DotNetPath = Path.Combine(s_dotnetInstallDir, s_dotnetExeName); var testBinDirectory = Path.GetDirectoryName(typeof(DotNetSdkTests).Assembly.Location); var sdksDir = Path.Combine(s_dotnetSdkPath, "Sdks"); ProjectName = "test"; ProjectFileName = ProjectName + ".csproj"; Configuration = "Debug"; TargetFramework = "netstandard2.0"; ProjectDir = Temp.CreateDirectory(); ObjDir = ProjectDir.CreateDirectory("obj"); OutDir = ProjectDir.CreateDirectory("bin").CreateDirectory(Configuration).CreateDirectory(TargetFramework); Project = ProjectDir.CreateFile(ProjectFileName).WriteAllText(s_projectSource); ProjectDir.CreateFile("TestClass.cs").WriteAllText(s_classSource); // avoid accidental dependency on files outside of the project directory: ProjectDir.CreateFile("Directory.Build.props").WriteAllText("<Project/>"); ProjectDir.CreateFile("Directory.Build.targets").WriteAllText("<Project/>"); ProjectDir.CreateFile(".editorconfig").WriteAllText("root = true"); var csharpCoreTargets = Path.Combine(testBinDirectory, "Microsoft.CSharp.Core.targets"); var visualBasicCoreTargets = Path.Combine(testBinDirectory, "Microsoft.VisualBasic.Core.targets"); Assert.True(File.Exists(csharpCoreTargets)); Assert.True(File.Exists(visualBasicCoreTargets)); EnvironmentVariables = new Dictionary <string, string>() { { "CSharpCoreTargetsPath", csharpCoreTargets }, { "VisualBasicCoreTargetsPath", visualBasicCoreTargets }, { "MSBuildSDKsPath", sdksDir }, { "DOTNET_MSBUILD_SDK_RESOLVER_SDKS_DIR", sdksDir } }; var restoreResult = ProcessUtilities.Run(DotNetPath, $@"msbuild ""{Project.Path}"" /t:restore /bl:{Path.Combine(ProjectDir.Path, "restore.binlog")}", additionalEnvironmentVars: EnvironmentVariables); Assert.True(restoreResult.ExitCode == 0, $"Failed with exit code {restoreResult.ExitCode}: {restoreResult.Output}"); Assert.True(File.Exists(Path.Combine(ObjDir.Path, "project.assets.json"))); Assert.True(File.Exists(Path.Combine(ObjDir.Path, ProjectFileName + ".nuget.g.props"))); Assert.True(File.Exists(Path.Combine(ObjDir.Path, ProjectFileName + ".nuget.g.targets"))); }
public void ReferenceSearchPaths_LIB() { var cwd = Temp.CreateDirectory(); cwd.CreateFile("a.csx").WriteAllText(@"Console.Write(typeof(C).Name);"); var dir = Temp.CreateDirectory(); dir.CreateFile("C.dll").WriteAllBytes(TestResources.General.C1); var result = ProcessUtilities.Run(CsiPath, "/r:C.dll a.csx", workingDirectory: cwd.Path, additionalEnvironmentVars: new[] { KeyValuePairUtil.Create("LIB", dir.Path) }); // error CS0006: Metadata file 'C.dll' could not be found Assert.True(result.Errors.StartsWith("error CS0006", StringComparison.Ordinal)); Assert.True(result.ContainsErrors); }
private void RunDotNet(string arguments) { Assert.NotNull(DotNetCoreSdk.ExePath); var environmentVariables = new Dictionary <string, string>() { ["NUGET_PACKAGES"] = _nugetCacheDir.Path }; var restoreResult = ProcessUtilities.Run( DotNetCoreSdk.ExePath, arguments, workingDirectory: SolutionDirectory.Path, additionalEnvironmentVars: environmentVariables); Assert.True(restoreResult.ExitCode == 0, $"{DotNetCoreSdk.ExePath} failed with exit code {restoreResult.ExitCode}: {restoreResult.Output}"); }
public void LineNumber_Information_On_Exception() { var source = @"Console.WriteLine(""OK""); throw new Exception(""Error!""); "; var cwd = Temp.CreateDirectory(); cwd.CreateFile("a.csx").WriteAllText(source); var result = ProcessUtilities.Run(CsiPath, "a.csx", workingDirectory: cwd.Path); Assert.True(result.ContainsErrors); AssertEx.AssertEqualToleratingWhitespaceDifferences("OK", result.Output); AssertEx.AssertStartsWithToleratingWhitespaceDifferences($@" System.Exception: Error! at Submission#0.<<Initialize>>d__0.MoveNext() in {cwd}{Path.DirectorySeparatorChar}a.csx:line 2 ", result.Errors); }
public void LineNumber_Information_On_Exception() { var source = @"Console.WriteLine(""OK""); throw new Exception(""Error!""); "; var cwd = Temp.CreateDirectory(); cwd.CreateFile("a.csx").WriteAllText(source); var result = ProcessUtilities.Run(CsiPath, "a.csx", workingDirectory: cwd.Path); Assert.True(result.ContainsErrors); AssertEx.AssertEqualToleratingWhitespaceDifferences("OK", result.Output); AssertEx.AssertEqualToleratingWhitespaceDifferences($@" System.Exception: Error! + <Initialize>.MoveNext(){string.Format(ScriptingResources.AtFileLine, $"{cwd}{Path.DirectorySeparatorChar}a.csx", "2")} ", result.Errors); }
private void RunDotNet(string arguments) { Assert.NotNull(DotNetSdkMSBuildInstalled.SdkPath); var environmentVariables = new Dictionary <string, string>() { ["NUGET_PACKAGES"] = _nugetCacheDir.Path }; var dotNetExeName = "dotnet" + (Path.DirectorySeparatorChar == '/' ? "" : ".exe"); var exePath = Path.Combine(DotNetSdkMSBuildInstalled.SdkPath, dotNetExeName); var restoreResult = ProcessUtilities.Run( exePath, arguments, workingDirectory: SolutionDirectory.Path, additionalEnvironmentVars: environmentVariables); Assert.True(restoreResult.ExitCode == 0, $"{exePath} failed with exit code {restoreResult.ExitCode}: {restoreResult.Output}"); }
/// <summary> /// End Tracing. /// Assembly specific trace files will be generated. /// </summary> internal static void EndTrace(DirectoryInfo coverageLogDirectory, bool retainResult, string traceName) { if (retainResult) { ExecutionEventLog.RecordStatus("Retaining Coverage data for passing test as trace: " + traceName); if (!coverageLogDirectory.Exists) { coverageLogDirectory.Create(); } // List harvested components and then save to disk ProcessUtilities.Run(coverageToolPath, "/List /session ALL"); ProcessUtilities.Run(coverageToolPath, "/SetPath \"" + coverageLogDirectory.FullName + "\""); ProcessUtilities.Run(coverageToolPath, "/session ALL /Save /As " + traceName); } else { ExecutionEventLog.RecordStatus("Clearing Coverage data for non-passing test."); ProcessUtilities.Run(coverageToolPath, "/Reset /session ALL"); } ProcessUtilities.Run(coverageToolPath, "/Close /session ALL"); }
protected void VerifyValues(string props, string[] targets, string[] expressions, string[] expectedResults) { if (!string.IsNullOrEmpty(props)) { EmitTestHelperProps(ObjDir.Path, ProjectFileName, props); } var evaluationResultsFile = EmitTestHelperTargets(ObjDir.Path, OutDir.Path, ProjectFileName, expressions); var targetsArg = string.Join(";", targets.Concat(new[] { "Test_EvaluateExpressions" })); var testBinDirectory = Path.GetDirectoryName(typeof(DotNetSdkTests).Assembly.Location); var binLog = Path.Combine(ProjectDir.Path, $"build{_logIndex++}.binlog"); var buildResult = ProcessUtilities.Run(DotNetPath, $@"msbuild ""{Project.Path}"" /t:{targetsArg} /p:Configuration={Configuration} /p:RoslynTargetsPath=""{testBinDirectory}"" /bl:""{binLog}""", additionalEnvironmentVars: EnvironmentVariables); Assert.True(buildResult.ExitCode == 0, $"Failed with exit code {buildResult.ExitCode}: {buildResult.Output}"); var evaluationResult = File.ReadAllLines(evaluationResultsFile).Select(l => (l != EmptyValueMarker) ? l : ""); AssertEx.Equal(expectedResults, evaluationResult); }
internal static void Uninstall() { ProcessUtilities.Run("cmd", "/K " + magellanSource + " " + unInstallCommand); }
/// <summary> /// Start tracing with Magellan. This can be done at scope of entire run or individual invocations /// </summary> internal static void BeginTrace() { ExecutionEventLog.RecordStatus("Starting Code Coverage session."); ProcessUtilities.Run(coverageToolPath, "/Close /session ALL"); ProcessUtilities.Run(coverageToolPath, "/Reset /session ALL"); }
public static void IlasmTempAssembly(string declarations, bool appendDefaultHeader, bool includePdb, out string assemblyPath, out string pdbPath) { if (declarations == null) { throw new ArgumentNullException(nameof(declarations)); } using (var sourceFile = new DisposableFile(extension: ".il")) { string sourceFileName = Path.GetFileNameWithoutExtension(sourceFile.Path); assemblyPath = Path.Combine( TempRoot.Root, Path.ChangeExtension(Path.GetFileName(sourceFile.Path), "dll")); string completeIL; if (appendDefaultHeader) { const string corLibName = "mscorlib"; const string corLibVersion = "4:0:0:0"; const string corLibKey = "B7 7A 5C 56 19 34 E0 89"; completeIL = $@".assembly '{sourceFileName}' {{}} .assembly extern {corLibName} {{ .publickeytoken = ({corLibKey}) .ver {corLibVersion} }} {declarations}"; } else { completeIL = declarations.Replace("<<GeneratedFileName>>", sourceFileName); } sourceFile.WriteAllText(completeIL); var arguments = $"\"{sourceFile.Path}\" -DLL -out=\"{assemblyPath}\""; if (includePdb && !MonoHelpers.IsRunningOnMono()) { pdbPath = Path.ChangeExtension(assemblyPath, "pdb"); arguments += string.Format(" -PDB=\"{0}\"", pdbPath); } else { pdbPath = null; } var result = ProcessUtilities.Run(IlasmPath, arguments); if (result.ContainsErrors) { throw new ArgumentException( "The provided IL cannot be compiled." + Environment.NewLine + IlasmPath + " " + arguments + Environment.NewLine + result, nameof(declarations)); } } }
/// <summary> /// Copies support files. Throws if files are present already /// </summary> /// <param name="tests"></param> /// <param name="sourceDirectory"></param> /// <param name="destinationRootDirectory"></param> internal static void CopySupportFiles(List <TestRecord> tests, DirectoryInfo sourceDirectory, DirectoryInfo destinationRootDirectory) { // ThrowIfRelativePath(sourceDirectory); ThrowIfRelativePath(destinationRootDirectory); Collection <TestSupportFile> supportFiles; // In the normal case of not having a named execution group, all // tests share the same set of support files, so we can just grab // the first test's set. if (String.IsNullOrEmpty(tests.First().TestInfo.ExecutionGroup)) { supportFiles = tests.First().TestInfo.SupportFiles; } // For a named execution group there can be distinct support files, // so we need to merge each test's set of support files. else { supportFiles = new Collection <TestSupportFile>(); foreach (TestRecord test in tests) { foreach (TestSupportFile supportFile in test.TestInfo.SupportFiles) { if (!supportFiles.Contains(supportFile)) { supportFiles.Add(supportFile); } } } } foreach (TestSupportFile file in supportFiles) { ExecutionEventLog.RecordStatus("Copying File: " + file.Source); string source = Path.Combine(sourceDirectory.FullName, file.Source); source = ReplaceSupportFileVariables(source); DirectoryInfo destinationDirectory; // If the support file specifies an absolute path, that is our destination. if (Path.IsPathRooted(file.Destination)) { destinationDirectory = new DirectoryInfo(file.Destination); } // If the support file specified a path but it wasn't absolute, then it is // relative to the destination base path. else if (!string.IsNullOrEmpty(file.Destination)) { destinationDirectory = new DirectoryInfo(Path.Combine(destinationRootDirectory.FullName, file.Destination)); } // Otherwise the support file didn't specify a destination, so it goes to the base else { destinationDirectory = destinationRootDirectory; } // Given we've determined the destination, make sure the directory exists. if (!destinationDirectory.Exists) { destinationDirectory.Create(); } if (source.Contains("*")) //Copy * Wildcard { ProcessUtilities.Run("cmd", string.Format(CultureInfo.InvariantCulture, "/c copy /y \"{0}\" \"{1}\"", source, destinationDirectory.FullName)); } else if (Directory.Exists(source)) //Copy Directory { ProcessUtilities.Run("cmd", string.Format(CultureInfo.InvariantCulture, "/c xcopy /ey \"{0}\" \"{1}\"\\", source, destinationDirectory.FullName)); } // Exe files in net core generate deps.json and .dll, we need to copy them as well else if (source.Contains(".exe")) { string wildcardedSource = source.Replace(".exe", ".*"); ProcessUtilities.Run("cmd", string.Format(CultureInfo.InvariantCulture, "/c copy /y \"{0}\" \"{1}\"", wildcardedSource, destinationDirectory.FullName)); } else //Copy individual File { string destinationFile = Path.Combine(destinationDirectory.FullName, Path.GetFileName(source)); File.Copy(source, destinationFile, true); File.SetAttributes(destinationFile, FileAttributes.Normal); } } }
private ProcessResult RunCompilerOutput(TempFile file) { return(ProcessUtilities.Run(file.Path, "", Path.GetDirectoryName(file.Path))); }
private void KillWithMoreForce(Process process) { ProcessUtilities.Run("taskkill.exe", "/f /pid " + process.Id.ToString()); }
public void RollbackState(StateModule settings) { ProcessUtilities.Run("regsvr32.exe", "/s /u " + Path.Combine(settings.TestBinariesDirectory.FullName, settings.Path)); }
/// <summary> /// private static void MakeDiagnosticRecord(DirectoryInfo directory) { ProcessUtilities.Run("dxdiag", "/whql:off /t " + Path.Combine(directory.FullName, "HardwareDiagnostic.txt")); }
public static void IlasmTempAssembly(string declarations, bool appendDefaultHeader, bool includePdb, out string assemblyPath, out string pdbPath) { if (declarations == null) { throw new ArgumentNullException(nameof(declarations)); } using (var sourceFile = new DisposableFile(extension: ".il")) { string sourceFileName = Path.GetFileNameWithoutExtension(sourceFile.Path); assemblyPath = Path.Combine( TempRoot.Root, Path.ChangeExtension(Path.GetFileName(sourceFile.Path), "dll")); string completeIL; if (appendDefaultHeader) { completeIL = string.Format( @".assembly '{0}' {{}} .assembly extern mscorlib {{ .publickeytoken = (B7 7A 5C 56 19 34 E0 89) .ver 4:0:0:0 }} {1}", sourceFileName, declarations); } else { completeIL = declarations.Replace("<<GeneratedFileName>>", sourceFileName); } sourceFile.WriteAllText(completeIL); var ilasmPath = Path.Combine( Path.GetDirectoryName(typeof(object).Assembly.Location), "ilasm.exe"); var arguments = string.Format( "\"{0}\" /DLL /OUT=\"{1}\"", sourceFile.Path, assemblyPath); if (includePdb && !MonoHelpers.IsRunningOnMono()) { pdbPath = Path.ChangeExtension(assemblyPath, "pdb"); arguments += string.Format(" /PDB=\"{0}\"", pdbPath); } else { pdbPath = null; } var program = ilasmPath; if (MonoHelpers.IsRunningOnMono()) { arguments = string.Format("{0} {1}", ilasmPath, arguments); arguments = arguments.Replace("\"", ""); arguments = arguments.Replace("=", ":"); program = "mono"; } var result = ProcessUtilities.Run(program, arguments); if (result.ContainsErrors) { throw new ArgumentException( "The provided IL cannot be compiled." + Environment.NewLine + program + " " + arguments + Environment.NewLine + result, nameof(declarations)); } } }