Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / fx / src / xsp / System / Web / Compilation / CodeDirectoryCompiler.cs / 6 / CodeDirectoryCompiler.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.Compilation { using System; using System.IO; using System.Collections; using System.CodeDom.Compiler; using System.Configuration; using System.Globalization; using System.Web.Configuration; using System.Reflection; using System.Web.Hosting; using System.Web.Util; using System.Web.UI; // The different types of directory that we treat as 'Code' (with minor differences) internal enum CodeDirectoryType { MainCode, // The main /code directory SubCode, // Code subdirectories registered to be compiled separately AppResources, // The /Resources directory LocalResources, // A /LocalResources directory (at any level) WebReferences // The /WebReferences directory } internal class CodeDirectoryCompiler { private VirtualPath _virtualDir; private CodeDirectoryType _dirType; private StringSet _excludedSubdirectories; private BuildProvidersCompiler _bpc; private BuildProviderSet _buildProviders = new BuildProviderSet(); private bool _onlyBuildLocalizedResources; static internal BuildResultMainCodeAssembly _mainCodeBuildResult; internal static bool IsResourceCodeDirectoryType(CodeDirectoryType dirType) { return dirType == CodeDirectoryType.AppResources || dirType == CodeDirectoryType.LocalResources; } 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 ( 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 ( 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 ( 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 ( 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; // 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; } // Call the AppInitialize method in the Code assembly if there is one internal static void CallAppInitializeMethod() { if (_mainCodeBuildResult != null) _mainCodeBuildResult.CallAppInitializeMethod(); } internal const string sourcesDirectoryPrefix = "Sources_"; internal static void GetCodeDirectoryInformation( VirtualPath virtualDir, CodeDirectoryType dirType, StringSet excludedSubdirectories, int index, out Type codeDomProviderType, out CompilerParameters compilerParameters, out string generatedFilesDir) { // Compute the full path to the directory we'll use to generate all // the code files generatedFilesDir = HttpRuntime.CodegenDirInternal + "\\" + sourcesDirectoryPrefix + virtualDir.FileName; bool supportLocalization = IsResourceCodeDirectoryType(dirType); // the index is used to retrieve the correct referenced assemblies BuildProvidersCompiler bpc = new BuildProvidersCompiler(virtualDir, supportLocalization, generatedFilesDir, index); CodeDirectoryCompiler cdc = new CodeDirectoryCompiler(virtualDir, dirType, excludedSubdirectories); 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); // Generate all the sources into the directory generatedFilesDir bpc.GenerateSources(out codeDomProviderType, out compilerParameters); } private CodeDirectoryCompiler(VirtualPath virtualDir, CodeDirectoryType dirType, StringSet excludedSubdirectories) { _virtualDir = virtualDir; _dirType = dirType; _excludedSubdirectories = excludedSubdirectories; } private void FindBuildProviders() { // If we need to build the profile, add its build provider if (_dirType == CodeDirectoryType.MainCode && ProfileBuildProvider.HasCompilableProfile) { _buildProviders.Add(ProfileBuildProvider.Create()); } VirtualDirectory vdir = HostingEnvironment.VirtualPathProvider.GetDirectory(_virtualDir); ProcessDirectoryRecursive(vdir, true /*topLevel*/); } private void ProcessDirectoryRecursive(VirtualDirectory vdir, bool topLevel) { // If it's a WebReferences directory, handle it using a single WebReferencesBuildProvider // instead of creating a different BuildProvider for each file. if (_dirType == CodeDirectoryType.WebReferences) { // Create a build provider for the current directory BuildProvider buildProvider = new WebReferencesBuildProvider(vdir); buildProvider.SetVirtualPath(vdir.VirtualPathObject); _buildProviders.Add(buildProvider); } // Go through all the files in the directory foreach (VirtualFileBase child in vdir.Children) { if (child.IsDirectory) { // If we are at the top level of this code directory, and the current // subdirectory is in the exclude list, skip it if (topLevel && _excludedSubdirectories != null && _excludedSubdirectories.Contains(child.Name)) { continue; } // Exclude the special FrontPage directory ( if (child.Name == "_vti_cnf") continue; ProcessDirectoryRecursive(child as VirtualDirectory, false /*topLevel*/); continue; } // Don't look at individual files for WebReferences directories if (_dirType == CodeDirectoryType.WebReferences) continue; // Skip neutral files if _onlyBuildLocalizedResources is true if (IsResourceCodeDirectoryType(_dirType)) { if (_onlyBuildLocalizedResources && System.Web.UI.Util.GetCultureName(child.VirtualPath) == null) { continue; } } BuildProvider buildProvider = BuildManager.CreateBuildProvider(child.VirtualPathObject, (IsResourceCodeDirectoryType(_dirType)) ? BuildProviderAppliesTo.Resources : BuildProviderAppliesTo.Code, _bpc.CompConfig, _bpc.ReferencedAssemblies, false /*failIfUnknown*/); // Non-supported file type if (buildProvider == null) continue; // For Page resources, don't generate a strongly typed class if (_dirType == CodeDirectoryType.LocalResources && buildProvider is BaseResourcesBuildProvider) { ((BaseResourcesBuildProvider)buildProvider).DontGenerateStronglyTypedClass(); } _buildProviders.Add(buildProvider); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SizeConverter.cs
- WorkflowHostingResponseContext.cs
- PeerPresenceInfo.cs
- Adorner.cs
- PhysicalAddress.cs
- UserInitiatedNavigationPermission.cs
- PenLineJoinValidation.cs
- SizeAnimation.cs
- LeftCellWrapper.cs
- EntityDataSourceDataSelection.cs
- MatrixStack.cs
- EarlyBoundInfo.cs
- XmlLoader.cs
- ListParaClient.cs
- CompilerHelpers.cs
- ComPlusTypeValidator.cs
- SymbolPair.cs
- RelationshipWrapper.cs
- Marshal.cs
- RuntimeConfig.cs
- CallbackHandler.cs
- Figure.cs
- CharacterString.cs
- CultureInfo.cs
- ExpressionLink.cs
- ToolStripItemEventArgs.cs
- PropertyItem.cs
- StringConverter.cs
- EntityDataSourceWizardForm.cs
- DocumentPageViewAutomationPeer.cs
- TlsnegoTokenProvider.cs
- StreamResourceInfo.cs
- CodeParameterDeclarationExpression.cs
- BinHexEncoder.cs
- ListControlConvertEventArgs.cs
- PageThemeBuildProvider.cs
- NumberSubstitution.cs
- InputLanguageEventArgs.cs
- ClientScriptManagerWrapper.cs
- UseLicense.cs
- KeyedHashAlgorithm.cs
- infer.cs
- XmlWriterDelegator.cs
- ImageSourceConverter.cs
- XmlDataImplementation.cs
- MobileControlsSection.cs
- Run.cs
- PreservationFileReader.cs
- FormsAuthenticationTicket.cs
- DbConnectionFactory.cs
- SerialPinChanges.cs
- ThemeableAttribute.cs
- EntityFunctions.cs
- WebDescriptionAttribute.cs
- RepeaterItem.cs
- CompilationUnit.cs
- DiagnosticTrace.cs
- XmlSiteMapProvider.cs
- Walker.cs
- DependencyPropertyHelper.cs
- ReferencedCollectionType.cs
- AutoSizeComboBox.cs
- XmlHierarchyData.cs
- RemotingConfiguration.cs
- DelayedRegex.cs
- CatalogPart.cs
- InArgument.cs
- AsyncDataRequest.cs
- MetadataSerializer.cs
- FixedElement.cs
- XhtmlBasicObjectListAdapter.cs
- ObjectDataSourceMethodEventArgs.cs
- UserControl.cs
- InvalidPropValue.cs
- CqlGenerator.cs
- XPathSelectionIterator.cs
- Viewport2DVisual3D.cs
- Padding.cs
- CodeAttachEventStatement.cs
- ListViewSelectEventArgs.cs
- ServiceHostingEnvironment.cs
- DataGridViewColumnDesigner.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- HtmlListAdapter.cs
- DtrList.cs
- ExpandSegmentCollection.cs
- QueryOperationResponseOfT.cs
- InstanceDescriptor.cs
- DelegateHelpers.cs
- CodeTypeDeclarationCollection.cs
- Condition.cs
- DataList.cs
- DataGridDefaultColumnWidthTypeConverter.cs
- TriState.cs
- SetterTriggerConditionValueConverter.cs
- FormViewDesigner.cs
- TransactionFlowProperty.cs
- DataBindingCollection.cs
- RequestQueue.cs
- SystemIPGlobalStatistics.cs