-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRuntimeCompiler.cs
More file actions
129 lines (114 loc) · 4.83 KB
/
RuntimeCompiler.cs
File metadata and controls
129 lines (114 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System;
using System.IO;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Generic;
namespace GlassLoader
{
public class RuntimeCompiler
{
public static List<MetadataReference> GetSharedDependencies(List<string> deps)
{
var dependencies = new List<MetadataReference>();
//引用程序集
string coreLib = typeof(object).Assembly.Location; // System.Private.CoreLib.dll
//string systemRuntime = Path.Combine(Path.GetDirectoryName(coreLib)!, "System.Runtime.dll");
//string systemConsole = Path.Combine(Path.GetDirectoryName(coreLib)!, "System.Console.dll");
dependencies.Add(MetadataReference.CreateFromFile(coreLib));
foreach (var dep in deps)
{
try
{
string libPath = Path.Combine(Path.GetDirectoryName(coreLib)!, dep);
dependencies.Add(MetadataReference.CreateFromFile(libPath));
}
catch (Exception ex)
{
GLog.Error(ex);
GLog.Error($"An error happened while loading shared dependencies: {dep}");
continue;
}
}
return dependencies;
}
public static List<MetadataReference> GetLocalDependencies(List<string> deps)
{
var dependencies = new List<MetadataReference>();
//引用程序集
foreach (var dep in deps)
{
try
{
string libPath = dep.Replace("${ROOT}", FileManager.DefaultDirectory);
libPath = libPath.Replace("${GAMEVERSION}", Glass.CurrentVersion.directoryInfo.Name);
dependencies.Add(MetadataReference.CreateFromFile(libPath));
}
catch (Exception ex)
{
GLog.Error(ex);
GLog.Error($"An error happened while loading local dependencies: {dep}");
continue;
}
}
return dependencies;
}
public static Dictionary<string, string> GetCsSources(List<FileInfo> fileInfos)
{
Dictionary<string, string> sources = new Dictionary<string, string>();
foreach (var fileInfo in fileInfos)
{
string code = File.ReadAllText(fileInfo.FullName);
sources.Add(fileInfo.Name, code);
}
return sources;
}
public static Assembly? CompileToAssembly(Dictionary<string, string> sources, List<MetadataReference> references, string LibraryName = null)
{
LibraryName ??= "RuntimeMod_" + Guid.NewGuid().ToString();
//解析语法树
var syntaxTrees = new List<SyntaxTree>();
foreach (var source in sources.Values)
{
syntaxTrees.Add(CSharpSyntaxTree.ParseText(source));
}
//引用程序集
// string coreLib = typeof(object).Assembly.Location; // System.Private.CoreLib.dll
// string systemRuntime = Path.Combine(Path.GetDirectoryName(coreLib)!, "System.Runtime.dll");
// string systemConsole = Path.Combine(Path.GetDirectoryName(coreLib)!, "System.Console.dll");
// var references = new List<MetadataReference>
//{
// MetadataReference.CreateFromFile(coreLib),
// MetadataReference.CreateFromFile(systemRuntime),
// MetadataReference.CreateFromFile(systemConsole)
//};
//编译选项
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName: LibraryName,
syntaxTrees: syntaxTrees,
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);
GLog.Info($"Compiling: {LibraryName}");
using (var dllStream = new MemoryStream())
{
var emitResult = compilation.Emit(dllStream);
if (!emitResult.Success)
{
GLog.Error("Compile Failed :");
foreach (var diagnostic in emitResult.Diagnostics)
{
GLog.Error(diagnostic.ToString());
}
return null;
}
GLog.Info($"Compile success: {LibraryName}");
//从内存加载程序集
dllStream.Seek(0, SeekOrigin.Begin);
byte[] assemblyBytes = dllStream.ToArray();
Assembly assembly = Assembly.Load(assemblyBytes);
return assembly;
}
}
}
}