private static void BasicBatchCompilation(HttpContext context, CompilerInfo compInfo, PagesWithSameCompilerInfo pwsci) { ICodeCompiler compiler = pwsci.CodeProvider.CreateCompiler(); Debug.Trace("Batching", "Compiling " + pwsci.PageCount + " pages"); CompilerParameters compilParams = compInfo.CompilParams; compilParams.TempFiles = new TempFileCollection(HttpRuntime.CodegenDirInternal); // Create the resource file (shared by all the pages in the bucket) if (pwsci._stringResourceBuilder.HasStrings) { string resFileName = compilParams.TempFiles.AddExtension("res"); pwsci._stringResourceBuilder.CreateResourceFile(resFileName); compilParams.Win32Resource = resFileName; } // Never generate debug code when we're batching compilParams.TempFiles.KeepFiles = false; compilParams.IncludeDebugInformation = false; // Compute a table of all the assemblies used by all the pages in the // bucket, removing duplicates Hashtable allAssemblies = new Hashtable(); // Place all the generated source file names in an array string[] files = new string[pwsci.PageCount]; int fileCount = 0; foreach (BatchCompilationEntry e in pwsci.Pages) { Debug.Assert(FileUtil.FileExists(e.GeneratedSourceFile), e.GeneratedSourceFile + " is missing!"); files[fileCount++] = e.GeneratedSourceFile; // Add all the assemblies if (e.AssemblyDependencies != null) { foreach (Assembly assembly in e.AssemblyDependencies.Keys) { string assemblyName = Util.GetAssemblyCodeBase(assembly); allAssemblies[assemblyName] = null; } } } Debug.Assert(fileCount == pwsci.PageCount, "fileCount == pwsci.PageCount"); // Now, add all the (non-duplicate) assemblies to the compilParams foreach (string aname in allAssemblies.Keys) { compilParams.ReferencedAssemblies.Add(aname); } // Compile them all together into an assembly CompilerResults results; try { results = compiler.CompileAssemblyFromFileBatch(compilParams, files); } catch (Exception e) { Debug.Trace("Batching", "Compilation failed! " + e.Message); throw new HttpUnhandledException(HttpRuntime.FormatResourceString(SR.CompilationUnhandledException, pwsci.CodeProvider.GetType().FullName), e); } finally { // Delete all the generated source files for (int i = 0; i < fileCount; i++) { File.Delete(files[i]); } } BaseCompiler.ThrowIfCompilerErrors(results, pwsci.CodeProvider, null, null, null); // Note the assembly that everything ended up in foreach (BatchCompilationEntry e in pwsci.Pages) { e.SetTargetAssembly(results.CompiledAssembly); CacheResults(context, e); // Do some cleanup e.PostCompilation(); } }
private SourceCompilerCachedEntry CompileAndCache() { BaseCompiler.GenerateCompilerParameters(_compilParams); // Get the set of config assemblies for our context IDictionary configAssemblies = CompilationConfiguration.GetAssembliesFromContext(_context); if (_assemblies == null) { _assemblies = new Hashtable(); } // Add all the assemblies from the config object to the hashtable // This guarantees uniqueness if (configAssemblies != null) { foreach (Assembly asm in configAssemblies.Values) { _assemblies[asm] = null; } } // And the assembly of the application object (global.asax) _assemblies[HttpApplicationFactory.ApplicationType.Assembly] = null; // Now add all the passed in assemblies to the compilParams foreach (Assembly asm in _assemblies.Keys) { _compilParams.ReferencedAssemblies.Add(Util.GetAssemblyCodeBase(asm)); } // Instantiate the Compiler CodeDomProvider codeProvider = (CodeDomProvider)HttpRuntime.CreatePublicInstance(_compilerType); ICodeCompiler compiler = codeProvider.CreateCompiler(); CompilerResults results; // Compile the source file or string into an assembly try { _utcStart = DateTime.UtcNow; // If we have a source file, read it as a string and compile it. This way, // the compiler never needs to read the original file, avoiding permission // issues (see ASURT 112718) if (_sourceString == null) { _sourceString = Util.StringFromFile(_physicalPath, _context); // Put in some context so that the file can be debugged. _linePragma = new CodeLinePragma(_physicalPath, 1); } CodeSnippetCompileUnit snippetCompileUnit = new CodeSnippetCompileUnit(_sourceString); snippetCompileUnit.LinePragma = _linePragma; results = compiler.CompileAssemblyFromDom(_compilParams, snippetCompileUnit); } catch (Exception e) { throw new HttpUnhandledException(HttpRuntime.FormatResourceString(SR.CompilationUnhandledException, codeProvider.GetType().FullName), e); } BaseCompiler.ThrowIfCompilerErrors(results, codeProvider, null, _physicalPath, _sourceString); SourceCompilerCachedEntry scce = new SourceCompilerCachedEntry(); // Load the assembly scce._assembly = results.CompiledAssembly; // If we have a type name, load the type from the assembly if (_typeName != null) { scce._type = scce._assembly.GetType(_typeName); // If the type could not be loaded, delete the assembly and rethrow if (scce._type == null) { PreservedAssemblyEntry.RemoveOutOfDateAssembly(scce._assembly.GetName().Name); // Remember why we failed _typeNotFoundInAssembly = true; throw new HttpException( HttpRuntime.FormatResourceString(SR.Could_not_create_type, _typeName)); } } CacheEntryToDisk(scce); CacheEntryToMemory(scce); return(scce); }