static CSharpCodeProvider GetPathHackedProvider() { var provider = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider(); var settings = provider .GetType() .GetField("_compilerSettings", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(provider); var path = settings.GetType().GetField("_compilerFullPath", BindingFlags.Instance | BindingFlags.NonPublic); path.SetValue(settings, ((string)path.GetValue(settings)).Replace(@"bin\roslyn\", @"roslyn\")); return(provider); }
private List <Assembly> CompilePluginsFromSource(DirectoryInfo[] sourcePlugins) { using (CodeDomProvider provider = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider()) using (new PerformanceTimer("Compile and load source plugins")) { var _compilerSettings = provider.GetType().GetField("_compilerSettings", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(provider); var _compilerFullPath = _compilerSettings .GetType().GetField("_compilerFullPath", BindingFlags.Instance | BindingFlags.NonPublic); _compilerFullPath.SetValue(_compilerSettings, ((string)_compilerFullPath.GetValue(_compilerSettings)).Replace(@"bin\roslyn\", @"roslyn\")); var rootDirInfo = new DirectoryInfo(RootDirectory); var dllFiles = rootDirInfo.GetFiles("*.dll", SearchOption.TopDirectoryOnly).WhereF(x => !x.Name.Equals("cimgui.dll")) .SelectF(x => x.FullName).ToArray(); var results = new List <Assembly>(sourcePlugins.Length); foreach (var info in sourcePlugins) { using (new PerformanceTimer($"Compile and load source plugin: {info.Name}")) { var csFiles = info.GetFiles("*.cs", SearchOption.AllDirectories).Select(x => x.FullName).ToArray(); var parameters = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = true, CompilerOptions = "/optimize /unsafe" }; parameters.ReferencedAssemblies.AddRange(dllFiles); var csprojPath = Path.Combine(info.FullName, $"{info.Name}.csproj"); if (File.Exists(csprojPath)) { var refer = File.ReadAllLines(csprojPath) .WhereF(x => x.TrimStart().StartsWith("<Reference Include=") && x.TrimEnd().EndsWith("/>")); foreach (var r in refer) { var arr = new int[2] { 0, 0 }; var j = 0; for (var i = 0; i < r.Length; i++) { if (r[i] == '"') { arr[j] = i; j++; } } if (arr[1] != 0) { var dll = $"{r.Substring(arr[0] + 1, arr[1] - arr[0] - 1)}.dll"; parameters.ReferencedAssemblies.Add(dll); } } } var libsFolder = Path.Combine(info.FullName, "libs"); if (Directory.Exists(libsFolder)) { var libsDll = Directory.GetFiles(libsFolder, "*.dll"); parameters.ReferencedAssemblies.AddRange(libsDll); } // parameters.TempFiles = new TempFileCollection($"{MainDir}\\{PluginsDirectory}\\Temp"); // parameters.CoreAssemblyFileName = info.Name; var result = provider.CompileAssemblyFromFile(parameters, csFiles); if (result.Errors.HasErrors) { var AllErrors = ""; foreach (CompilerError compilerError in result.Errors) { AllErrors += compilerError + Environment.NewLine; Logger.Log.Error($"{info.Name} -> {compilerError.ToString()}"); } File.WriteAllText(Path.Combine(info.FullName, "Errors.txt"), AllErrors); // throw new Exception("Offsets file corrupted"); } else { results.Add(result.CompiledAssembly); } } } return(results); } }