예제 #1
0
        /// <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 { } });
            }
        }
예제 #2
0
        /// <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();
            }
        }