/// <summary> /// Compile plugin<br/> /// 编译插件<br/> /// </summary> /// <param name="info">Plugin information</param> public static void Compile(this PluginInfo info) { // Get source files and releated paths var sourceDirectory = info.SourceDirectory(); var sourceFiles = info.SourceFiles(); var assemblyName = info.DirectoryName(); var assemblyPath = info.AssemblyPath(); var assemblyPdbPath = info.AssemblyPdbPath(); var compileInfoPath = info.CompileInfoPath(); // Load reference assemblies var assemblyLoader = Application.Ioc.Resolve <IAssemblyLoader>(); foreach (var reference in info.References) { assemblyLoader.Load(reference); } // Check if recompile is needed // If no source files exists then no need to compile var existCompileInfo = ""; if (File.Exists(compileInfoPath)) { existCompileInfo = File.ReadAllText(compileInfoPath); } var compileInfo = string.Join("\r\n", sourceFiles .Select(s => new { path = s.Substring(sourceDirectory.Length + 1), time = File.GetLastWriteTime(s) }) // Relative path and modify time .OrderBy(s => s.path) // Order by path .Select(s => $"{s.path} {s.time}")); // Generate line if (sourceFiles.Length > 0 && compileInfo != existCompileInfo) { // Rename old files if (File.Exists(assemblyPath)) { File.Move(assemblyPath, $"{assemblyPath}.{DateTime.UtcNow.Ticks}.old"); } if (File.Exists(assemblyPdbPath)) { File.Move(assemblyPdbPath, $"{assemblyPdbPath}.{DateTime.UtcNow.Ticks}.old"); } // Invoke compile service // Default use debug configuration Directory.CreateDirectory(Path.GetDirectoryName(assemblyPath)); var configManager = Application.Ioc.Resolve <WebsiteConfigManager>(); var release = configManager.WebsiteConfig.Extra.GetOrDefault <bool?>( ExtraConfigKeys.CompilePluginsWithReleaseConfiguration) ?? false; var compilerService = Application.Ioc.Resolve <ICompilerService>(); var options = new CompilationOptions(); options.Release = release; options.GeneratePdbFile = true; compilerService.Compile(sourceFiles, assemblyName, assemblyPath, options); // Write compile information File.WriteAllText(compileInfoPath, compileInfo); // Remove old files, maybe they are locking but that's not matter Directory.EnumerateFiles(info.BinDirectory(), "*.old") .ForEach(path => { try { File.Delete(path); } catch { } }); } }
/// <summary> /// Get pdb file path<br/> /// 获取pdb文件的路径<br/> /// </summary> /// <param name="info">Plugin information</param> /// <returns></returns> public static string AssemblyPdbPath(this PluginInfo info) { return(Path.Combine(info.BinDirectory(), $"{info.DirectoryName()}.pdb")); }
/// <summary> /// Compile plugin<br/> /// 编译插件<br/> /// </summary> /// <param name="info">Plugin information</param> public static void Compile(this PluginInfo info) { // Get source files and releated paths var sourceDirectory = info.SourceDirectory(); var sourceFiles = info.SourceFiles(); var assemblyName = info.DirectoryName(); var assemblyPath = info.AssemblyPath(); var assemblyPdbPath = info.AssemblyPdbPath(); var compileInfoPath = info.CompileInfoPath(); // Load reference assemblies var assemblyLoader = Application.Ioc.Resolve <IAssemblyLoader>(); foreach (var reference in info.References) { assemblyLoader.Load(reference); } // Check if recompile is needed // If no source files exists then no need to compile var existCompileInfo = ""; if (File.Exists(compileInfoPath)) { existCompileInfo = File.ReadAllText(compileInfoPath); } var compileInfoBuilder = new StringBuilder(); compileInfoBuilder.AppendLine(Application.FullVersion); sourceFiles .Select(s => new { path = s.Substring(sourceDirectory.Length + 1), time = File.GetLastWriteTime(s) }) // Relative path and modify time .OrderBy(s => s.path) // Order by path .Select(s => $"{s.path} {s.time}") .ForEach(s => compileInfoBuilder.AppendLine(s)); var compileInfo = compileInfoBuilder.ToString(); if (sourceFiles.Length > 0 && compileInfo != existCompileInfo) { // Rename old files if (File.Exists(assemblyPath)) { File.Move(assemblyPath, $"{assemblyPath}.{DateTime.UtcNow.Ticks}.old"); } if (File.Exists(assemblyPdbPath)) { File.Move(assemblyPdbPath, $"{assemblyPdbPath}.{DateTime.UtcNow.Ticks}.old"); } // Invoke compile service // Default use debug configuration Directory.CreateDirectory(Path.GetDirectoryName(assemblyPath)); var configManager = Application.Ioc.Resolve <WebsiteConfigManager>(); var release = configManager.WebsiteConfig.Extra.GetOrDefault <bool?>( ExtraConfigKeys.CompilePluginsWithReleaseConfiguration) ?? false; var compilerService = Application.Ioc.Resolve <ICompilerService>(); var options = new CompilationOptions(); options.Release = release; options.GeneratePdbFile = true; compilerService.Compile(sourceFiles, assemblyName, assemblyPath, options); // Write compile information File.WriteAllText(compileInfoPath, compileInfo); // Remove old files, maybe they are locking but that's not matter Directory.EnumerateFiles(info.BinDirectory(), "*.old") .ForEach(path => { try { File.Delete(path); } catch { /* ignore error */ } }); // Call gc collect to avoid OOM #pragma warning disable S1215 // "GC.Collect" should not be called GC.Collect(); #pragma warning restore S1215 // "GC.Collect" should not be called GC.WaitForFullGCComplete(-1); GC.WaitForPendingFinalizers(); } }