Last active
November 24, 2020 00:10
-
-
Save ishisaka/eff1a8ba5fcc629a63763082d9926b70 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text; | |
using System.IO; | |
using Microsoft.CodeAnalysis.CSharp; | |
using Microsoft.CodeAnalysis; | |
using Microsoft.CodeAnalysis.Text; | |
using System.Reflection; | |
namespace RoslynComple | |
{ | |
class Program | |
{ | |
// デフォルトして使用するネームスペースを定義 | |
private static readonly List<string> DefaultNamepaces = | |
new List<string> | |
{ | |
"System", | |
"System.IO", | |
"System.Net", | |
"System.Linq", | |
"System.Text", | |
"System.Text.RegularExpressions", | |
"System.Collections.Generic" | |
}; | |
// デフォルトで使用する参照アセンブリの設定 | |
private static string runtimePath | |
= @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\{0}.dll"; | |
private static readonly List<MetadataReference> DefaultRefrences = | |
new List<MetadataReference> | |
{ | |
MetadataReference.CreateFromFile(string.Format(runtimePath, "mscorlib")), | |
MetadataReference.CreateFromFile(string.Format(runtimePath, "System")), | |
MetadataReference.CreateFromFile(string.Format(runtimePath, "System.Core")) | |
}; | |
// DLLを出力、オーバーフローチェックはする、最適化オプションはRelease、 | |
// 先に定義したネームスペースをデフォルトとのネームスペースとして使用、 | |
// 決定論的コンパイラの出力をON | |
private static readonly CSharpCompilationOptions DefaultCompletionOpsions = | |
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) | |
.WithOverflowChecks(true).WithOptimizationLevel(OptimizationLevel.Release) | |
.WithUsings(DefaultNamepaces).WithDeterministic(true); | |
// パース処理の定義 | |
public static SyntaxTree Parse(string text, string filename = "", CSharpParseOptions options = null) | |
{ | |
var stringText = SourceText.From(text, Encoding.UTF8); | |
return SyntaxFactory.ParseSyntaxTree(stringText, options, filename); | |
} | |
static void Main(string[] args) | |
{ | |
// DLL Source Code | |
var fileToCompile = @"C:\temp\Test.cs"; | |
var source = File.ReadAllText(fileToCompile); | |
// パースのオプションとしてC# 7.3を使用するように指定 | |
var parseSyntaxTree | |
= Parse(source, fileToCompile, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_3)); | |
var compliation | |
= CSharpCompilation.Create("Test", | |
new SyntaxTree[] { parseSyntaxTree }, | |
DefaultRefrences, DefaultCompletionOpsions); | |
//コンパイル結果をファイルに出力する。 | |
var dllFileName = @"c:\temp\Test.dll"; | |
try | |
{ | |
var result = compliation.Emit(dllFileName); | |
Console.WriteLine(result.Success ? "Sucess!!" : "Failed"); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex); | |
throw; | |
} | |
// コンパイル結果をメモリーストリームに出力し、そのコンパイル結果からインスタンスを作成する。 | |
object instance; | |
using (var ms = new MemoryStream()) | |
{ | |
try | |
{ | |
var result = compliation.Emit(ms); | |
Console.WriteLine(result.Success ? "Sucess!!" : "Failed"); | |
if (!result.Success) | |
{ | |
foreach (var diag in result.Diagnostics) | |
{ | |
// コンパイルエラーメッセージを表示 | |
Console.WriteLine(diag.ToString()); | |
// 以下でコンパイルエラーメッセージだけ取れそうだが、返ってくるのは空文字 | |
Console.WriteLine("Description :" + diag.Descriptor.Description.ToString()); | |
} | |
Console.Read(); | |
return; | |
} | |
ms.Seek(0, SeekOrigin.Begin); | |
var assembly = Assembly.Load(ms.ToArray()); | |
//instance = assembly.CreateInstance("TEST.Test", true); | |
var types = assembly.GetExportedTypes(); | |
instance = assembly.CreateInstance(types[0].FullName); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex); | |
throw; | |
} | |
} | |
Console.WriteLine(instance.GetType()); | |
Console.Read(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment