#pragma warning restore 0649 internal static BuildResult CreateBuildResultFromCode(BuildResultTypeCode code, VirtualPath virtualPath) { BuildResult ret = null; switch (code) { case BuildResultTypeCode.BuildResultCompiledAssembly: ret = new BuildResultCompiledAssembly(); break; case BuildResultTypeCode.BuildResultCompiledType: ret = new BuildResultCompiledType(); break; case BuildResultTypeCode.BuildResultCompiledTemplateType: ret = new BuildResultCompiledTemplateType(); break; case BuildResultTypeCode.BuildResultCompiledGlobalAsaxType: ret = new BuildResultCompiledGlobalAsaxType(); break; case BuildResultTypeCode.BuildResultCustomString: ret = new BuildResultCustomString(); break; case BuildResultTypeCode.BuildResultMainCodeAssembly: ret = new BuildResultMainCodeAssembly(); break; case BuildResultTypeCode.BuildResultResourceAssembly: ret = new BuildResultResourceAssembly(); break; case BuildResultTypeCode.BuildResultCodeCompileUnit: ret = new BuildResultCodeCompileUnit(); break; default: Debug.Assert(false, "code=" + code); return null; } ret.VirtualPath = virtualPath; // Set _nextUpToDateCheck to MinValue, to make sure the next call to IsUpToDate() // actually makes the check ret._nextUpToDateCheck = DateTime.MinValue; return ret; }
internal virtual BuildResult CreateBuildResult(CompilerResults results) { BuildResult result; if (this.flags[2]) { return(null); } if (!BuildManagerHost.InClientBuildManager && (results != null)) { Assembly compiledAssembly = results.CompiledAssembly; } Type generatedType = this.GetGeneratedType(results); if (generatedType != null) { BuildResultCompiledType type2 = this.CreateBuildResult(generatedType); if (!type2.IsDelayLoadType && ((results == null) || (generatedType.Assembly != results.CompiledAssembly))) { type2.UsesExistingAssembly = true; } result = type2; } else { string customString = this.GetCustomString(results); if (customString != null) { result = new BuildResultCustomString(this.flags[0x20] ? results.CompiledAssembly : null, customString); } else { if (results == null) { return(null); } result = new BuildResultCompiledAssembly(results.CompiledAssembly); } } int resultFlags = (int)this.GetResultFlags(results); if (resultFlags != 0) { resultFlags &= 0xffff; result.Flags |= resultFlags; } return(result); }
internal virtual BuildResult CreateBuildResult(CompilerResults results) { BuildResult result; if (this.flags[2]) { return null; } if (!BuildManagerHost.InClientBuildManager && (results != null)) { Assembly compiledAssembly = results.CompiledAssembly; } Type generatedType = this.GetGeneratedType(results); if (generatedType != null) { BuildResultCompiledType type2 = this.CreateBuildResult(generatedType); if (!type2.IsDelayLoadType && ((results == null) || (generatedType.Assembly != results.CompiledAssembly))) { type2.UsesExistingAssembly = true; } result = type2; } else { string customString = this.GetCustomString(results); if (customString != null) { result = new BuildResultCustomString(this.flags[0x20] ? results.CompiledAssembly : null, customString); } else { if (results == null) { return null; } result = new BuildResultCompiledAssembly(results.CompiledAssembly); } } int resultFlags = (int) this.GetResultFlags(results); if (resultFlags != 0) { resultFlags &= 0xffff; result.Flags |= resultFlags; } return result; }
internal static BuildResult CreateBuildResultFromCode(BuildResultTypeCode code, System.Web.VirtualPath virtualPath) { BuildResult result = null; switch (code) { case BuildResultTypeCode.BuildResultCompiledAssembly: result = new BuildResultCompiledAssembly(); break; case BuildResultTypeCode.BuildResultCompiledType: result = new BuildResultCompiledType(); break; case BuildResultTypeCode.BuildResultCompiledTemplateType: result = new BuildResultCompiledTemplateType(); break; case BuildResultTypeCode.BuildResultCustomString: result = new BuildResultCustomString(); break; case BuildResultTypeCode.BuildResultMainCodeAssembly: result = new BuildResultMainCodeAssembly(); break; case BuildResultTypeCode.BuildResultCodeCompileUnit: result = new BuildResultCodeCompileUnit(); break; case BuildResultTypeCode.BuildResultCompiledGlobalAsaxType: result = new BuildResultCompiledGlobalAsaxType(); break; case BuildResultTypeCode.BuildResultResourceAssembly: result = new BuildResultResourceAssembly(); break; default: return(null); } result.VirtualPath = virtualPath; result._nextUpToDateCheck = DateTime.MinValue; return(result); }
internal static Assembly GetCodeDirectoryAssembly(VirtualPath virtualDir, CodeDirectoryType dirType, string assemblyName, StringSet excludedSubdirectories, bool isDirectoryAllowed) { string path = virtualDir.MapPath(); if (!isDirectoryAllowed && Directory.Exists(path)) { throw new HttpException(System.Web.SR.GetString("Bar_dir_in_precompiled_app", new object[] { virtualDir })); } bool supportLocalization = IsResourceCodeDirectoryType(dirType); string cacheKey = assemblyName; BuildResult buildResultFromCache = BuildManager.GetBuildResultFromCache(cacheKey); Assembly a = null; if ((buildResultFromCache != null) && (buildResultFromCache is BuildResultCompiledAssembly)) { if (buildResultFromCache is BuildResultMainCodeAssembly) { _mainCodeBuildResult = (BuildResultMainCodeAssembly)buildResultFromCache; } a = ((BuildResultCompiledAssembly)buildResultFromCache).ResultAssembly; if (!supportLocalization) { return(a); } if (!isDirectoryAllowed) { return(a); } BuildResultResourceAssembly assembly2 = (BuildResultResourceAssembly)buildResultFromCache; if (HashCodeCombiner.GetDirectoryHash(virtualDir) == assembly2.ResourcesDependenciesHash) { return(a); } } if (!isDirectoryAllowed) { return(null); } if ((dirType != CodeDirectoryType.LocalResources) && !StringUtil.StringStartsWithIgnoreCase(path, HttpRuntime.AppDomainAppPathInternal)) { throw new HttpException(System.Web.SR.GetString("Virtual_codedir", new object[] { virtualDir.VirtualPathString })); } if (!Directory.Exists(path)) { if (dirType != CodeDirectoryType.MainCode) { return(null); } if (!ProfileBuildProvider.HasCompilableProfile) { return(null); } } BuildManager.ReportDirectoryCompilationProgress(virtualDir); DateTime utcNow = DateTime.UtcNow; CodeDirectoryCompiler compiler = new CodeDirectoryCompiler(virtualDir, dirType, excludedSubdirectories); string outputAssemblyName = null; if (a != null) { outputAssemblyName = a.GetName().Name; compiler._onlyBuildLocalizedResources = true; } else { outputAssemblyName = BuildManager.GenerateRandomAssemblyName(assemblyName); } BuildProvidersCompiler compiler2 = new BuildProvidersCompiler(virtualDir, supportLocalization, outputAssemblyName); compiler._bpc = compiler2; compiler.FindBuildProviders(); compiler2.SetBuildProviders(compiler._buildProviders); CompilerResults results = compiler2.PerformBuild(); if (results != null) { DateTime time2 = DateTime.UtcNow.AddMilliseconds(3000.0); do { if (UnsafeNativeMethods.GetModuleHandle(results.PathToAssembly) == IntPtr.Zero) { a = results.CompiledAssembly; goto Label_01E6; } Thread.Sleep(250); }while (DateTime.UtcNow <= time2); throw new HttpException(System.Web.SR.GetString("Assembly_already_loaded", new object[] { results.PathToAssembly })); } Label_01E6: if (a == null) { return(null); } if (dirType == CodeDirectoryType.MainCode) { _mainCodeBuildResult = new BuildResultMainCodeAssembly(a); buildResultFromCache = _mainCodeBuildResult; } else if (supportLocalization) { buildResultFromCache = new BuildResultResourceAssembly(a); } else { buildResultFromCache = new BuildResultCompiledAssembly(a); } buildResultFromCache.VirtualPath = virtualDir; if (BuildManager.OptimizeCompilations && (dirType != CodeDirectoryType.LocalResources)) { buildResultFromCache.AddVirtualPathDependencies(new SingleObjectCollection(virtualDir.AppRelativeVirtualPathString)); } if (dirType != CodeDirectoryType.LocalResources) { buildResultFromCache.CacheToMemory = false; } BuildManager.CacheBuildResult(cacheKey, buildResultFromCache, utcNow); return(a); }
internal virtual BuildResult CreateBuildResult(CompilerResults results) { // If the build provider is not supposed to have a build result, just return if (flags[noBuildResult]) { return(null); } // Access the CompiledAssembly property to make sure the assembly gets loaded // Otherwise, the user code in GetGeneratedType() will fail to load it in medium trust since // they don't have access to the codegen folder if (!BuildManagerHost.InClientBuildManager && results != null) { // The ClientBuildManager runs in full trust, so we skip this statement // to avoid unnecessary loading of the assembly. var assembly = results.CompiledAssembly; } // Ask the build provider if it wants to persist a Type Type type = GetGeneratedType(results); BuildResult result; if (type != null) { // Create a BuildResult for it BuildResultCompiledType resultCompiledType = CreateBuildResult(type); if (!resultCompiledType.IsDelayLoadType) { // If the returned type doesn't come from the generated assembly, set a flag if (results == null || type.Assembly != results.CompiledAssembly) { resultCompiledType.UsesExistingAssembly = true; } } result = resultCompiledType; } else { // Ask the build provider if it instead wants to persist a custom string string customString = GetCustomString(results); // If it does, persist it if (customString != null) { // Only preserve an assembly if the BuildProvider has actually contributed code // to the compilation. result = new BuildResultCustomString( flags[contributedCode] ? results.CompiledAssembly : null, customString); } else { // Nothing was built: nothing to persist if (results == null) { return(null); } // Otherwise, just persist the assembly, if any result = new BuildResultCompiledAssembly(results.CompiledAssembly); } } // Ask the provider it it wants to set some flags on the result int resultFlags = (int)GetResultFlags(results); if (resultFlags != 0) { // Make sure only the lower bits are set Debug.Assert((resultFlags & 0xFFFF0000) == 0); resultFlags &= 0x0000FFFF; result.Flags |= resultFlags; } return(result); }
internal virtual BuildResult CreateBuildResult(CompilerResults results) { // If the build provider is not supposed to have a build result, just return if (flags[noBuildResult]) return null; // Access the CompiledAssembly property to make sure the assembly gets loaded // Otherwise, the user code in GetGeneratedType() will fail to load it in medium trust since // they don't have access to the codegen folder if (!BuildManagerHost.InClientBuildManager && results != null) { // The ClientBuildManager runs in full trust, so we skip this statement // to avoid unnecessary loading of the assembly. var assembly = results.CompiledAssembly; } // Ask the build provider if it wants to persist a Type Type type = GetGeneratedType(results); BuildResult result; if (type != null) { // Create a BuildResult for it BuildResultCompiledType resultCompiledType = CreateBuildResult(type); if (!resultCompiledType.IsDelayLoadType) { // If the returned type doesn't come from the generated assembly, set a flag if (results == null || type.Assembly != results.CompiledAssembly) resultCompiledType.UsesExistingAssembly = true; } result = resultCompiledType; } else { // Ask the build provider if it instead wants to persist a custom string string customString = GetCustomString(results); // If it does, persist it if (customString != null) { // Only preserve an assembly if the BuildProvider has actually contributed code // to the compilation. result = new BuildResultCustomString( flags[contributedCode] ? results.CompiledAssembly : null, customString); } else { // Nothing was built: nothing to persist if (results == null) return null; // Otherwise, just persist the assembly, if any result = new BuildResultCompiledAssembly(results.CompiledAssembly); } } // Ask the provider it it wants to set some flags on the result int resultFlags = (int) GetResultFlags(results); if (resultFlags != 0) { // Make sure only the lower bits are set Debug.Assert((resultFlags & 0xFFFF0000) == 0); resultFlags &= 0x0000FFFF; result.Flags |= resultFlags; } return result; }
internal static Assembly GetCodeDirectoryAssembly(VirtualPath virtualDir, CodeDirectoryType dirType, string assemblyName, StringSet excludedSubdirectories, bool isDirectoryAllowed) { string physicalDir = virtualDir.MapPath(); if (!isDirectoryAllowed) { // The directory should never exist in a precompiled app if (Directory.Exists(physicalDir)) { throw new HttpException(SR.GetString(SR.Bar_dir_in_precompiled_app, virtualDir)); } } bool supportLocalization = IsResourceCodeDirectoryType(dirType); // Determine the proper cache key based on the type of directory we're processing string cacheKey = assemblyName; // Try the cache first BuildResult result = BuildManager.GetBuildResultFromCache(cacheKey); Assembly resultAssembly = null; // If it's cached, just return it if (result != null) { // It should always be a BuildResultCompiledAssembly, though if there is // a VirtualPathProvider doing very bad things, it may not (VSWhidbey 341701) Debug.Assert(result is BuildResultCompiledAssembly); if (result is BuildResultCompiledAssembly) { // If it's the main code assembly, keep track of it so we can later call // the AppInitialize method if (result is BuildResultMainCodeAssembly) { Debug.Assert(dirType == CodeDirectoryType.MainCode); Debug.Assert(_mainCodeBuildResult == null); _mainCodeBuildResult = (BuildResultMainCodeAssembly) result; } resultAssembly = ((BuildResultCompiledAssembly)result).ResultAssembly; if (!supportLocalization) return resultAssembly; // We found a preserved resource assembly. However, we may not be done, // as the culture specific files may have changed. // But don't make any further checks if the directory is not allowed (precomp secenario). // In that case, we should always return the assembly (VSWhidbey 533498) if (!isDirectoryAllowed) return resultAssembly; BuildResultResourceAssembly buildResultResAssembly = (BuildResultResourceAssembly)result; string newResourcesDependenciesHash = HashCodeCombiner.GetDirectoryHash(virtualDir); // If the resources hash (which includes satellites) is up to date, we're done if (newResourcesDependenciesHash == buildResultResAssembly.ResourcesDependenciesHash) return resultAssembly; } } // If app was precompiled, don't attempt compilation if (!isDirectoryAllowed) return null; // Check whether the virtual dir is mapped to a different application, // which we don't support (VSWhidbey 218603). But don't do this for LocalResource (VSWhidbey 237935) if (dirType != CodeDirectoryType.LocalResources && !StringUtil.StringStartsWithIgnoreCase(physicalDir, HttpRuntime.AppDomainAppPathInternal)) { throw new HttpException(SR.GetString(SR.Virtual_codedir, virtualDir.VirtualPathString)); } // If the directory doesn't exist, we may be done if (!Directory.Exists(physicalDir)) { // We're definitely done if it's not the main code dir if (dirType != CodeDirectoryType.MainCode) return null; // If it is the main code dir, we're only done is there is no profile to compile // since the profice gets built as part of the main assembly. if (!ProfileBuildProvider.HasCompilableProfile) return null; } // Otherwise, compile it BuildManager.ReportDirectoryCompilationProgress(virtualDir); DateTime utcStart = DateTime.UtcNow; CodeDirectoryCompiler cdc = new CodeDirectoryCompiler(virtualDir, dirType, excludedSubdirectories); string outputAssemblyName = null; if (resultAssembly != null) { // If resultAssembly is not null, we are in the case where we just need to build // the localized resx file in a resources dir (local or global) Debug.Assert(supportLocalization); outputAssemblyName = resultAssembly.GetName().Name; cdc._onlyBuildLocalizedResources = true; } else { outputAssemblyName = BuildManager.GenerateRandomAssemblyName(assemblyName); } BuildProvidersCompiler bpc = new BuildProvidersCompiler(virtualDir, supportLocalization, outputAssemblyName); cdc._bpc = bpc; // Find all the build provider we want to compile from the code directory cdc.FindBuildProviders(); // Give them to the BuildProvidersCompiler bpc.SetBuildProviders(cdc._buildProviders); // Compile them into an assembly CompilerResults results = bpc.PerformBuild(); // Did we just compile something? if (results != null) { Debug.Assert(result == null); Debug.Assert(resultAssembly == null); // If there is already a loaded module with the same path, try to wait for it to be unloaded. // Otherwise, we would end up loading this old assembly instead of the new one (VSWhidbey 554697) DateTime waitLimit = DateTime.UtcNow.AddMilliseconds(3000); for (;;) { IntPtr hModule = UnsafeNativeMethods.GetModuleHandle(results.PathToAssembly); if (hModule == IntPtr.Zero) break; Debug.Trace("CodeDirectoryCompiler", results.PathToAssembly + " is already loaded. Waiting a bit"); System.Threading.Thread.Sleep(250); // Stop trying if the timeout was reached if (DateTime.UtcNow > waitLimit) { Debug.Trace("CodeDirectoryCompiler", "Timeout waiting for old assembly to unload: " + results.PathToAssembly); throw new HttpException(SR.GetString(SR.Assembly_already_loaded, results.PathToAssembly)); } } resultAssembly = results.CompiledAssembly; } // It is possible that there was nothing to compile (and we're not in the // satellite resources case) if (resultAssembly == null) return null; // For the main code directory, use a special BuildResult that takes care of // calling AppInitialize if it finds one if (dirType == CodeDirectoryType.MainCode) { // Keep track of it so we can later call the AppInitialize method _mainCodeBuildResult = new BuildResultMainCodeAssembly(resultAssembly); result = _mainCodeBuildResult; } else if (supportLocalization) { result = new BuildResultResourceAssembly(resultAssembly); } else { result = new BuildResultCompiledAssembly(resultAssembly); } result.VirtualPath = virtualDir; // If compilations are optimized, we need to include the right dependencies, since we can no longer // rely on everything getting wiped out when something in App_Code changes. // But don't do this for local resources, since they have their own special way of // dealing with dependencies (in BuildResultResourceAssembly.ComputeSourceDependenciesHashCode). // It's crucial *not* to do it as it triggers a tricky infinite recursion due to the fact // that GetBuildResultFromCacheInternal calls EnsureFirstTimeDirectoryInitForDependencies if // there is at least one dependency if (BuildManager.OptimizeCompilations && dirType != CodeDirectoryType.LocalResources) { result.AddVirtualPathDependencies(new SingleObjectCollection(virtualDir.AppRelativeVirtualPathString)); } // Top level assembly should not be cached to memory. But LocalResources are *not* // top level files, and do benefit from memory caching if (dirType != CodeDirectoryType.LocalResources) result.CacheToMemory = false; // Cache it for next time BuildManager.CacheBuildResult(cacheKey, result, utcStart); return resultAssembly; }
internal static Assembly GetCodeDirectoryAssembly(VirtualPath virtualDir, CodeDirectoryType dirType, string assemblyName, StringSet excludedSubdirectories, bool isDirectoryAllowed) { string physicalDir = virtualDir.MapPath(); if (!isDirectoryAllowed) { // The directory should never exist in a precompiled app if (Directory.Exists(physicalDir)) { throw new HttpException(SR.GetString(SR.Bar_dir_in_precompiled_app, virtualDir)); } } bool supportLocalization = IsResourceCodeDirectoryType(dirType); // Determine the proper cache key based on the type of directory we're processing string cacheKey = assemblyName; // Try the cache first BuildResult result = BuildManager.GetBuildResultFromCache(cacheKey); Assembly resultAssembly = null; // If it's cached, just return it if (result != null) { // It should always be a BuildResultCompiledAssembly, though if there is // a VirtualPathProvider doing very bad things, it may not (VSWhidbey 341701) Debug.Assert(result is BuildResultCompiledAssembly); if (result is BuildResultCompiledAssembly) { // If it's the main code assembly, keep track of it so we can later call // the AppInitialize method if (result is BuildResultMainCodeAssembly) { Debug.Assert(dirType == CodeDirectoryType.MainCode); Debug.Assert(_mainCodeBuildResult == null); _mainCodeBuildResult = (BuildResultMainCodeAssembly)result; } resultAssembly = ((BuildResultCompiledAssembly)result).ResultAssembly; if (!supportLocalization) { return(resultAssembly); } // We found a preserved resource assembly. However, we may not be done, // as the culture specific files may have changed. // But don't make any further checks if the directory is not allowed (precomp secenario). // In that case, we should always return the assembly (VSWhidbey 533498) if (!isDirectoryAllowed) { return(resultAssembly); } BuildResultResourceAssembly buildResultResAssembly = (BuildResultResourceAssembly)result; string newResourcesDependenciesHash = HashCodeCombiner.GetDirectoryHash(virtualDir); // If the resources hash (which includes satellites) is up to date, we're done if (newResourcesDependenciesHash == buildResultResAssembly.ResourcesDependenciesHash) { return(resultAssembly); } } } // If app was precompiled, don't attempt compilation if (!isDirectoryAllowed) { return(null); } // Check whether the virtual dir is mapped to a different application, // which we don't support (VSWhidbey 218603). But don't do this for LocalResource (VSWhidbey 237935) if (dirType != CodeDirectoryType.LocalResources && !StringUtil.StringStartsWithIgnoreCase(physicalDir, HttpRuntime.AppDomainAppPathInternal)) { throw new HttpException(SR.GetString(SR.Virtual_codedir, virtualDir.VirtualPathString)); } // If the directory doesn't exist, we may be done if (!Directory.Exists(physicalDir)) { // We're definitely done if it's not the main code dir if (dirType != CodeDirectoryType.MainCode) { return(null); } // If it is the main code dir, we're only done is there is no profile to compile // since the profice gets built as part of the main assembly. if (!ProfileBuildProvider.HasCompilableProfile) { return(null); } } // Otherwise, compile it BuildManager.ReportDirectoryCompilationProgress(virtualDir); DateTime utcStart = DateTime.UtcNow; CodeDirectoryCompiler cdc = new CodeDirectoryCompiler(virtualDir, dirType, excludedSubdirectories); string outputAssemblyName = null; if (resultAssembly != null) { // If resultAssembly is not null, we are in the case where we just need to build // the localized resx file in a resources dir (local or global) Debug.Assert(supportLocalization); outputAssemblyName = resultAssembly.GetName().Name; cdc._onlyBuildLocalizedResources = true; } else { outputAssemblyName = BuildManager.GenerateRandomAssemblyName(assemblyName); } BuildProvidersCompiler bpc = new BuildProvidersCompiler(virtualDir, supportLocalization, outputAssemblyName); cdc._bpc = bpc; // Find all the build provider we want to compile from the code directory cdc.FindBuildProviders(); // Give them to the BuildProvidersCompiler bpc.SetBuildProviders(cdc._buildProviders); // Compile them into an assembly CompilerResults results = bpc.PerformBuild(); // Did we just compile something? if (results != null) { Debug.Assert(result == null); Debug.Assert(resultAssembly == null); // If there is already a loaded module with the same path, try to wait for it to be unloaded. // Otherwise, we would end up loading this old assembly instead of the new one (VSWhidbey 554697) DateTime waitLimit = DateTime.UtcNow.AddMilliseconds(3000); for (;;) { IntPtr hModule = UnsafeNativeMethods.GetModuleHandle(results.PathToAssembly); if (hModule == IntPtr.Zero) { break; } Debug.Trace("CodeDirectoryCompiler", results.PathToAssembly + " is already loaded. Waiting a bit"); System.Threading.Thread.Sleep(250); // Stop trying if the timeout was reached if (DateTime.UtcNow > waitLimit) { Debug.Trace("CodeDirectoryCompiler", "Timeout waiting for old assembly to unload: " + results.PathToAssembly); throw new HttpException(SR.GetString(SR.Assembly_already_loaded, results.PathToAssembly)); } } resultAssembly = results.CompiledAssembly; } // It is possible that there was nothing to compile (and we're not in the // satellite resources case) if (resultAssembly == null) { return(null); } // For the main code directory, use a special BuildResult that takes care of // calling AppInitialize if it finds one if (dirType == CodeDirectoryType.MainCode) { // Keep track of it so we can later call the AppInitialize method _mainCodeBuildResult = new BuildResultMainCodeAssembly(resultAssembly); result = _mainCodeBuildResult; } else if (supportLocalization) { result = new BuildResultResourceAssembly(resultAssembly); } else { result = new BuildResultCompiledAssembly(resultAssembly); } result.VirtualPath = virtualDir; // If compilations are optimized, we need to include the right dependencies, since we can no longer // rely on everything getting wiped out when something in App_Code changes. // But don't do this for local resources, since they have their own special way of // dealing with dependencies (in BuildResultResourceAssembly.ComputeSourceDependenciesHashCode). // It's crucial *not* to do it as it triggers a tricky infinite recursion due to the fact // that GetBuildResultFromCacheInternal calls EnsureFirstTimeDirectoryInitForDependencies if // there is at least one dependency if (BuildManager.OptimizeCompilations && dirType != CodeDirectoryType.LocalResources) { result.AddVirtualPathDependencies(new SingleObjectCollection(virtualDir.AppRelativeVirtualPathString)); } // Top level assembly should not be cached to memory. But LocalResources are *not* // top level files, and do benefit from memory caching if (dirType != CodeDirectoryType.LocalResources) { result.CacheToMemory = false; } // Cache it for next time BuildManager.CacheBuildResult(cacheKey, result, utcStart); return(resultAssembly); }
internal static Assembly GetCodeDirectoryAssembly(VirtualPath virtualDir, CodeDirectoryType dirType, string assemblyName, StringSet excludedSubdirectories, bool isDirectoryAllowed) { string path = virtualDir.MapPath(); if (!isDirectoryAllowed && Directory.Exists(path)) { throw new HttpException(System.Web.SR.GetString("Bar_dir_in_precompiled_app", new object[] { virtualDir })); } bool supportLocalization = IsResourceCodeDirectoryType(dirType); string cacheKey = assemblyName; BuildResult buildResultFromCache = BuildManager.GetBuildResultFromCache(cacheKey); Assembly a = null; if ((buildResultFromCache != null) && (buildResultFromCache is BuildResultCompiledAssembly)) { if (buildResultFromCache is BuildResultMainCodeAssembly) { _mainCodeBuildResult = (BuildResultMainCodeAssembly) buildResultFromCache; } a = ((BuildResultCompiledAssembly) buildResultFromCache).ResultAssembly; if (!supportLocalization) { return a; } if (!isDirectoryAllowed) { return a; } BuildResultResourceAssembly assembly2 = (BuildResultResourceAssembly) buildResultFromCache; if (HashCodeCombiner.GetDirectoryHash(virtualDir) == assembly2.ResourcesDependenciesHash) { return a; } } if (!isDirectoryAllowed) { return null; } if ((dirType != CodeDirectoryType.LocalResources) && !StringUtil.StringStartsWithIgnoreCase(path, HttpRuntime.AppDomainAppPathInternal)) { throw new HttpException(System.Web.SR.GetString("Virtual_codedir", new object[] { virtualDir.VirtualPathString })); } if (!Directory.Exists(path)) { if (dirType != CodeDirectoryType.MainCode) { return null; } if (!ProfileBuildProvider.HasCompilableProfile) { return null; } } BuildManager.ReportDirectoryCompilationProgress(virtualDir); DateTime utcNow = DateTime.UtcNow; CodeDirectoryCompiler compiler = new CodeDirectoryCompiler(virtualDir, dirType, excludedSubdirectories); string outputAssemblyName = null; if (a != null) { outputAssemblyName = a.GetName().Name; compiler._onlyBuildLocalizedResources = true; } else { outputAssemblyName = BuildManager.GenerateRandomAssemblyName(assemblyName); } BuildProvidersCompiler compiler2 = new BuildProvidersCompiler(virtualDir, supportLocalization, outputAssemblyName); compiler._bpc = compiler2; compiler.FindBuildProviders(); compiler2.SetBuildProviders(compiler._buildProviders); CompilerResults results = compiler2.PerformBuild(); if (results != null) { DateTime time2 = DateTime.UtcNow.AddMilliseconds(3000.0); do { if (UnsafeNativeMethods.GetModuleHandle(results.PathToAssembly) == IntPtr.Zero) { a = results.CompiledAssembly; goto Label_01E6; } Thread.Sleep(250); } while (DateTime.UtcNow <= time2); throw new HttpException(System.Web.SR.GetString("Assembly_already_loaded", new object[] { results.PathToAssembly })); } Label_01E6: if (a == null) { return null; } if (dirType == CodeDirectoryType.MainCode) { _mainCodeBuildResult = new BuildResultMainCodeAssembly(a); buildResultFromCache = _mainCodeBuildResult; } else if (supportLocalization) { buildResultFromCache = new BuildResultResourceAssembly(a); } else { buildResultFromCache = new BuildResultCompiledAssembly(a); } buildResultFromCache.VirtualPath = virtualDir; if (BuildManager.OptimizeCompilations && (dirType != CodeDirectoryType.LocalResources)) { buildResultFromCache.AddVirtualPathDependencies(new SingleObjectCollection(virtualDir.AppRelativeVirtualPathString)); } if (dirType != CodeDirectoryType.LocalResources) { buildResultFromCache.CacheToMemory = false; } BuildManager.CacheBuildResult(cacheKey, buildResultFromCache, utcNow); return a; }