Skip to content

Instantly share code, notes, and snippets.

@ishisaka
Last active November 24, 2020 00:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ishisaka/eff1a8ba5fcc629a63763082d9926b70 to your computer and use it in GitHub Desktop.
Save ishisaka/eff1a8ba5fcc629a63763082d9926b70 to your computer and use it in GitHub Desktop.
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