Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / Compilation / ClientBuildManager.cs / 4 / ClientBuildManager.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /************************************************************************************************************/ namespace System.Web.Compilation { using System; using System.Collections; using System.Collections.Specialized; using System.Configuration; using System.Diagnostics; using System.IO; using System.Threading; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Globalization; using System.CodeDom; using System.CodeDom.Compiler; using System.Web; using System.Web.Configuration; using System.Web.Util; using System.Web.UI; using System.Web.Hosting; using System.Xml; using Debug=System.Web.Util.Debug; // Flags that drive the behavior of precompilation [Flags] public enum PrecompilationFlags { Default = 0x00000000, // determines whether the deployed app will be updatable Updatable = 0x00000001, // determines whether the target directory can be overwritten OverwriteTarget = 0x00000002, // determines whether the compiler will emit debug information ForceDebug = 0x00000004, // determines whether the application is built clean Clean = 0x00000008, // determines whether the /define:CodeAnalysis flag needs to be added // as compilation symbol CodeAnalysis = 0x00000010, // determines whether to generate APTCA attribute. AllowPartiallyTrustedCallers = 0x00000020, // determines whether to delaySign the generate assemblies. DelaySign = 0x00000040, // determines whether to use fixed assembly names FixedNames = 0x00000080, } [Serializable] [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] public class ClientBuildManagerParameter { private string _strongNameKeyFile; private string _strongNameKeyContainer; private PrecompilationFlags _precompilationFlags = PrecompilationFlags.Default; // Determines the behavior of the precompilation public PrecompilationFlags PrecompilationFlags { get { return _precompilationFlags; } set { _precompilationFlags = value; } } public string StrongNameKeyFile { get { return _strongNameKeyFile; } set { _strongNameKeyFile = value; } } public string StrongNameKeyContainer { get { return _strongNameKeyContainer; } set { _strongNameKeyContainer = value; } } } // // This class provide access to the BuildManager outside of an IIS environment // Instances of this class are created in the caller's App Domain. // // It creates and configures the new App Domain for handling BuildManager calls // using System.Web.Hosting.ApplicationHost.CreateApplicationHost() // [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)] [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)] public sealed class ClientBuildManager : MarshalByRefObject, IDisposable { private VirtualPath _virtualPath; private string _physicalPath; private string _installPath; private string _appId; private string _codeGenDir; private HostingEnvironmentParameters _hostingParameters; private WaitCallback _onAppDomainUnloadedCallback; private WaitCallback _onAppDomainShutdown; private ApplicationShutdownReason _reason; private BuildManagerHost _host; private Exception _hostCreationException; private bool _hostCreationPending; public event BuildManagerHostUnloadEventHandler AppDomainUnloaded; public event EventHandler AppDomainStarted; public event BuildManagerHostUnloadEventHandler AppDomainShutdown; // internal lock used for host creation. private object _lock = new object(); // Whether to wait for the call back from the previous host unloading before creating a new one private bool _waitForCallBack; /* * Creates an instance of the ClientBuildManager. * appPhysicalSourceDir points to the physical root of the application (e.g "c:\myapp") * virtualPath is the virtual path to the app root. It can be anything (e.g. "/dummy"), * but ideally it should match the path later given to Cassini, in order for * compilation that happens here to be reused there. */ public ClientBuildManager(string appVirtualDir, string appPhysicalSourceDir) : this(appVirtualDir, appPhysicalSourceDir, null /*appPhysicalTargetDir*/, null /*ClientBuildManagerParameter*/) { } /* * Creates an instance of the PrecompilationManager. * appPhysicalSourceDir points to the physical root of the application (e.g "c:\myapp") * appVirtualDir is the virtual path to the app root. It can be anything (e.g. "/dummy"), * but ideally it should match the path later given to Cassini, in order for * compilation that happens here to be reused there. * appPhysicalTargetDir is the directory where the precompiled site is placed */ public ClientBuildManager(string appVirtualDir, string appPhysicalSourceDir, string appPhysicalTargetDir) : this(appVirtualDir, appPhysicalSourceDir, appPhysicalTargetDir, null /*ClientBuildManagerParameter*/) { } /* * Creates an instance of the PrecompilationManager. * appPhysicalSourceDir points to the physical root of the application (e.g "c:\myapp") * appVirtualDir is the virtual path to the app root. It can be anything (e.g. "/dummy"), * but ideally it should match the path later given to Cassini, in order for * compilation that happens here to be reused there. * appPhysicalTargetDir is the directory where the precompiled site is placed * flags determines the behavior of the precompilation */ public ClientBuildManager(string appVirtualDir, string appPhysicalSourceDir, string appPhysicalTargetDir, ClientBuildManagerParameter parameter) { if (parameter == null) { parameter = new ClientBuildManagerParameter(); } // Always build clean in precompilation for deployment mode, // since building incrementally raises all kind of issues (VSWhidbey 382954). if (!String.IsNullOrEmpty(appPhysicalTargetDir)) { parameter.PrecompilationFlags |= PrecompilationFlags.Clean; } _hostingParameters = new HostingEnvironmentParameters(); _hostingParameters.HostingFlags = HostingEnvironmentFlags.DontCallAppInitialize | HostingEnvironmentFlags.ClientBuildManager; _hostingParameters.ClientBuildManagerParameter = parameter; _hostingParameters.PrecompilationTargetPhysicalDirectory = appPhysicalTargetDir; // Make sure the app virtual dir starts with / if (appVirtualDir[0] != '/') appVirtualDir = "/" + appVirtualDir; Initialize(VirtualPath.CreateNonRelative(appVirtualDir), appPhysicalSourceDir); } /* * returns the codegendir used by runtime appdomain */ public string CodeGenDir { get { if (_codeGenDir == null) { EnsureHostCreated(); _codeGenDir = _host.CodeGenDir; } return _codeGenDir; } } /* * Indicates whether the host is created. */ public bool IsHostCreated { get { return _host != null; } } /* * Create an object in the runtime appdomain */ public IRegisteredObject CreateObject(Type type, bool failIfExists) { if (type == null) { throw new ArgumentNullException("type"); } EnsureHostCreated(); Debug.Assert(_appId != null); _host.RegisterAssembly(type.Assembly.FullName, type.Assembly.Location); ApplicationManager appManager = ApplicationManager.GetApplicationManager(); return appManager.CreateObjectInternal(_appId, type, _host.ApplicationHost, failIfExists); } /* * Return the list of directories that would cause appdomain shutdown. */ public string[] GetAppDomainShutdownDirectories() { Debug.Trace("CBM", "GetAppDomainShutdownDirectories"); return FileChangesMonitor.s_dirsToMonitor; } /* * Makes sure that all the top level files are compiled (code, global.asax, ...) */ public void CompileApplicationDependencies() { Debug.Trace("CBM", "CompileApplicationDependencies"); EnsureHostCreated(); _host.CompileApplicationDependencies(); } public IDictionary GetBrowserDefinitions() { Debug.Trace("CBM", "GetBrowserDefinitions"); EnsureHostCreated(); return _host.GetBrowserDefinitions(); } /* * Returns the physical path of the generated file corresponding to the virtual directory. * Note the virtualPath needs to use this format: * "/[appname]/App_WebReferences/{[subDir]/}" */ public string GetGeneratedSourceFile(string virtualPath) { Debug.Trace("CBM", "GetGeneratedSourceFile " + virtualPath); if (virtualPath == null) { throw new ArgumentNullException("virtualPath"); } EnsureHostCreated(); return _host.GetGeneratedSourceFile(VirtualPath.CreateTrailingSlash(virtualPath)); } /* * Returns the virtual path of the corresponding generated file. * Note the filepath needs to be a full path. */ public string GetGeneratedFileVirtualPath(string filePath) { Debug.Trace("CBM", "GetGeneratedFileVirtualPath " + filePath); if (filePath == null) { throw new ArgumentNullException("filePath"); } EnsureHostCreated(); return _host.GetGeneratedFileVirtualPath(filePath); } /* * Returns an array of the virtual paths to all the code directories in the app thru the hosted appdomain */ public string[] GetVirtualCodeDirectories() { Debug.Trace("CBM", "GetHostedVirtualCodeDirectories"); EnsureHostCreated(); return _host.GetVirtualCodeDirectories(); } /* * Returns an array of the assemblies defined in the bin and assembly reference config section */ public String[] GetTopLevelAssemblyReferences(string virtualPath) { Debug.Trace("CBM", "GetHostedVirtualCodeDirectories"); if (virtualPath == null) { throw new ArgumentNullException("virtualPath"); } EnsureHostCreated(); return _host.GetTopLevelAssemblyReferences(VirtualPath.Create(virtualPath)); } /* * Returns the compiler type and parameters that need to be used to build * a given code directory. Also, returns the directory containing all the code * files generated from non-code files in the code directory (e.g. wsdl files) */ public void GetCodeDirectoryInformation(string virtualCodeDir, out Type codeDomProviderType, out CompilerParameters compilerParameters, out string generatedFilesDir) { Debug.Trace("CBM", "GetCodeDirectoryInformation " + virtualCodeDir); if (virtualCodeDir == null) { throw new ArgumentNullException("virtualCodeDir"); } EnsureHostCreated(); _host.GetCodeDirectoryInformation(VirtualPath.CreateTrailingSlash(virtualCodeDir), out codeDomProviderType, out compilerParameters, out generatedFilesDir); Debug.Trace("CBM", "GetCodeDirectoryInformation " + virtualCodeDir + " end"); } /* * Returns the compiler type and parameters that need to be used to build * a given file. */ public void GetCompilerParameters(string virtualPath, out Type codeDomProviderType, out CompilerParameters compilerParameters) { Debug.Trace("CBM", "GetCompilerParameters " + virtualPath); if (virtualPath == null) { throw new ArgumentNullException("virtualPath"); } EnsureHostCreated(); _host.GetCompilerParams(VirtualPath.Create(virtualPath), out codeDomProviderType, out compilerParameters); } /* * Returns the codedom tree and the compiler type/param for a given file. */ public CodeCompileUnit GenerateCodeCompileUnit( string virtualPath, out Type codeDomProviderType, out CompilerParameters compilerParameters, out IDictionary linePragmasTable) { Debug.Trace("CBM", "GenerateCodeCompileUnit " + virtualPath); return GenerateCodeCompileUnit(virtualPath, null, out codeDomProviderType, out compilerParameters, out linePragmasTable); } public CodeCompileUnit GenerateCodeCompileUnit( string virtualPath, String virtualFileString, out Type codeDomProviderType, out CompilerParameters compilerParameters, out IDictionary linePragmasTable) { Debug.Trace("CBM", "GenerateCodeCompileUnit " + virtualPath); if (virtualPath == null) { throw new ArgumentNullException("virtualPath"); } EnsureHostCreated(); return _host.GenerateCodeCompileUnit(VirtualPath.Create(virtualPath), virtualFileString, out codeDomProviderType, out compilerParameters, out linePragmasTable); } public string GenerateCode( string virtualPath, String virtualFileString, out IDictionary linePragmasTable) { Debug.Trace("CBM", "GenerateCode " + virtualPath); if (virtualPath == null) { throw new ArgumentNullException("virtualPath"); } EnsureHostCreated(); return _host.GenerateCode(VirtualPath.Create(virtualPath), virtualFileString, out linePragmasTable); } /* * Returns the compiled type for an input file */ public Type GetCompiledType(string virtualPath) { Debug.Trace("CBM", "GetCompiledType " + virtualPath); if (virtualPath == null) { throw new ArgumentNullException("virtualPath"); } EnsureHostCreated(); string[] typeAndAsemblyName = _host.GetCompiledTypeAndAssemblyName(VirtualPath.Create(virtualPath), null); if (typeAndAsemblyName == null) return null; Assembly a = Assembly.LoadFrom(typeAndAsemblyName[1]); Type t = a.GetType(typeAndAsemblyName[0]); return t; } /* * Compile a file */ public void CompileFile(string virtualPath) { CompileFile(virtualPath, null); } public void CompileFile(string virtualPath, ClientBuildManagerCallback callback) { Debug.Trace("CBM", "CompileFile " + virtualPath); if (virtualPath == null) { throw new ArgumentNullException("virtualPath"); } EnsureHostCreated(); _host.GetCompiledTypeAndAssemblyName(VirtualPath.Create(virtualPath), callback); } /* * Indicates whether an assembly is a code assembly. */ public bool IsCodeAssembly(string assemblyName) { Debug.Trace("CBM", "IsCodeAssembly " + assemblyName); if (assemblyName == null) { throw new ArgumentNullException("assemblyName"); } // EnsureHostCreated(); bool result = _host.IsCodeAssembly(assemblyName); Debug.Trace("CBM", "IsCodeAssembly " + result.ToString()); return result; } public bool Unload() { Debug.Trace("CBM", "Unload"); BuildManagerHost host = _host; if (host != null) { _host = null; return host.UnloadAppDomain(); } return false; } /* * Precompile an application */ public void PrecompileApplication() { PrecompileApplication(null); } /* * Precompile an application with callback support */ public void PrecompileApplication(ClientBuildManagerCallback callback) { PrecompileApplication(callback, false); } public void PrecompileApplication(ClientBuildManagerCallback callback, bool forceCleanBuild) { Debug.Trace("CBM", "PrecompileApplication"); PrecompilationFlags savedFlags = _hostingParameters.ClientBuildManagerParameter.PrecompilationFlags; if (forceCleanBuild) { // If there was a previous host, it will be unloaded by CBM and we will wait for the callback. // If there was no previous host, we don't do any waiting. // DevDiv 46290 _waitForCallBack = _host != null; Debug.Trace("CBM", "Started Unload"); // Unload the existing appdomain so the new one will be created with the clean flag Unload(); _hostingParameters.ClientBuildManagerParameter.PrecompilationFlags = savedFlags | PrecompilationFlags.Clean; WaitForCallBack(); } try { EnsureHostCreated(); _host.PrecompileApp(callback); } finally { if (forceCleanBuild) { // Revert precompilationFlags _hostingParameters.ClientBuildManagerParameter.PrecompilationFlags = savedFlags; } } } // _waitForCallBack is set to false in OnAppDomainUnloaded. // This method waits until it is set to false before continuing, so that // we do not run into a concurrency issue where _host could be set to null. // DevDiv 46290 private void WaitForCallBack() { Debug.Trace("CBM", "WaitForCallBack"); int waited = 0; while (_waitForCallBack && waited <= 50) { Thread.Sleep(200); waited++; } if (_waitForCallBack) { Debug.Trace("CBM", "timeout while waiting for callback"); } else { Debug.Trace("CBM", "callback received before timeout"); } } public override Object InitializeLifetimeService() { return null; // never expire lease } internal void Initialize(VirtualPath virtualPath, string physicalPath) { Debug.Trace("CBM", "Initialize"); _virtualPath = virtualPath; _physicalPath = FileUtil.FixUpPhysicalDirectory(physicalPath); _onAppDomainUnloadedCallback = new WaitCallback(OnAppDomainUnloadedCallback); _onAppDomainShutdown = new WaitCallback(OnAppDomainShutdownCallback); _installPath = RuntimeEnvironment.GetRuntimeDirectory(); // Do not create host during intialization. It will be done on demand. //CreateHost(); } private void EnsureHostCreated() { if (_host == null) { lock (_lock) { // Create the host if necessary if (_host == null) { CreateHost(); Debug.Trace("CBM", "EnsureHostCreated: after CreateHost()"); } } } // If an exception happened during host creation, rethrow it if (_hostCreationException != null) { Debug.Trace("CBM", "EnsureHostCreated: failed. " + _hostCreationException); // We need to wrap it in a new exception, otherwise we lose the original stack. throw new HttpException(_hostCreationException.Message, _hostCreationException); } } private void CreateHost() { Debug.Trace("CBM", "CreateHost"); Debug.Assert(_host == null); Debug.Assert(!_hostCreationPending, "CreateHost: creation already pending"); _hostCreationPending = true; // Use a local to avoid having a partially created _host BuildManagerHost host = null; try { string appId; ApplicationManager appManager = ApplicationManager.GetApplicationManager(); host = (BuildManagerHost) appManager.CreateObjectWithDefaultAppHostAndAppId( _physicalPath, _virtualPath, typeof(BuildManagerHost), false /*failIfExists*/, _hostingParameters, out appId); // host appdomain cannot be unloaded during creation. host.AddPendingCall(); host.Configure(this); _host = host; _appId = appId; _hostCreationException = _host.InitializationException; } catch (Exception e) { // If an exception happens, keep track of it _hostCreationException = e; // Even though the host initialization failed, keep track of it so subsequent // request will see the error _host = host; } finally { _hostCreationPending = false; if (host != null) { // Notify the client that the host is ready if (AppDomainStarted != null) { AppDomainStarted(this, EventArgs.Empty); } // The host can be unloaded safely now. host.RemovePendingCall(); } } Debug.Trace("CBM", "CreateHost LEAVE"); } // Called by BuildManagerHost when the ASP appdomain is unloaded internal void OnAppDomainUnloaded(ApplicationShutdownReason reason) { Debug.Trace("CBM", "OnAppDomainUnloaded " + reason.ToString()); // Don't try to use this host anymore _host = null; _hostCreationException = null; _reason = reason; _waitForCallBack = false; // Don't do anything that can be slow here. Instead queue in a worker thread ThreadPool.QueueUserWorkItem(_onAppDomainUnloadedCallback); } private void OnAppDomainUnloadedCallback(Object unused) { Debug.Trace("CBM", "OnAppDomainUnloadedCallback"); // Notify the client that the appdomain is unloaded if (AppDomainUnloaded != null) { AppDomainUnloaded(this, new BuildManagerHostUnloadEventArgs(_reason)); } } private void OnAppDomainShutdownCallback(Object o) { if (AppDomainShutdown != null) { AppDomainShutdown(this, new BuildManagerHostUnloadEventArgs((ApplicationShutdownReason)o)); } } internal void OnAppDomainShutdown(ApplicationShutdownReason reason) { // Don't do anything that can be slow here. Instead queue in a worker thread ThreadPool.QueueUserWorkItem(_onAppDomainShutdown, reason); } #region IDisposable //Dispose the runtime appdomain properly when CBM is disposed void IDisposable.Dispose() { Unload(); } #endregion } [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)] [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)] public class BuildManagerHostUnloadEventArgs : EventArgs { ApplicationShutdownReason _reason; public BuildManagerHostUnloadEventArgs(ApplicationShutdownReason reason) { _reason = reason; } // Get the reason for the hosted appdomain shutdown public ApplicationShutdownReason Reason { get { return _reason; } } } public delegate void BuildManagerHostUnloadEventHandler(object sender, BuildManagerHostUnloadEventArgs e); /* * Type of the entries in the table returned by GenerateCodeCompileUnit */ [Serializable] [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] public sealed class LinePragmaCodeInfo { public LinePragmaCodeInfo() { } public LinePragmaCodeInfo(int startLine, int startColumn, int startGeneratedColumn, int codeLength, bool isCodeNugget) { this._startLine = startLine; this._startColumn = startColumn; this._startGeneratedColumn = startGeneratedColumn; this._codeLength = codeLength; this._isCodeNugget = isCodeNugget; } // Starting line in ASPX file internal int _startLine; public int StartLine { get { return _startLine; } } // Starting column in the ASPX file internal int _startColumn; public int StartColumn { get { return _startColumn; } } // Starting column in the generated source file (assuming no indentations are used) internal int _startGeneratedColumn; public int StartGeneratedColumn { get { return _startGeneratedColumn; } } // Length of the code snippet internal int _codeLength; public int CodeLength { get { return _codeLength; } } // Whether the script block is a nugget. internal bool _isCodeNugget; public bool IsCodeNugget { get { return _isCodeNugget; } } } }
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- NavigationFailedEventArgs.cs
- Exceptions.cs
- EntityDataSourceMemberPath.cs
- ArglessEventHandlerProxy.cs
- RectangleGeometry.cs
- ISAPIApplicationHost.cs
- StateMachine.cs
- AnonymousIdentificationSection.cs
- SelectedPathEditor.cs
- PointAnimationUsingPath.cs
- TimeZoneNotFoundException.cs
- GeneralTransform.cs
- DocumentSequenceHighlightLayer.cs
- ComPersistableTypeElementCollection.cs
- ComponentChangedEvent.cs
- FormParameter.cs
- ListViewDeleteEventArgs.cs
- CompiledQueryCacheEntry.cs
- UDPClient.cs
- RegexTypeEditor.cs
- NegatedConstant.cs
- EventMappingSettingsCollection.cs
- ToolStripProgressBar.cs
- columnmapfactory.cs
- HtmlTextArea.cs
- EntityTemplateUserControl.cs
- MetadataCollection.cs
- ObjectQuery_EntitySqlExtensions.cs
- StylusPointPropertyInfo.cs
- HashStream.cs
- DataError.cs
- BooleanStorage.cs
- DefaultParameterValueAttribute.cs
- DataStorage.cs
- iisPickupDirectory.cs
- NGCPageContentSerializerAsync.cs
- SqlEnums.cs
- KeyValueSerializer.cs
- ProcessingInstructionAction.cs
- IteratorDescriptor.cs
- CheckedPointers.cs
- SqlServices.cs
- TextDpi.cs
- StringSorter.cs
- DBSqlParserColumn.cs
- DBDataPermissionAttribute.cs
- StylusButtonCollection.cs
- XappLauncher.cs
- ResourceExpressionBuilder.cs
- FontSource.cs
- ConnectionsZone.cs
- CanExecuteRoutedEventArgs.cs
- DataRelation.cs
- TextTreeUndoUnit.cs
- SqlDataSourceRefreshSchemaForm.cs
- VarRefManager.cs
- MimeMapping.cs
- DoubleStorage.cs
- LicenseException.cs
- ApplicationSecurityInfo.cs
- HtmlInputImage.cs
- ConsoleCancelEventArgs.cs
- DebugInfoGenerator.cs
- AnchorEditor.cs
- TCPClient.cs
- UIElement3D.cs
- TableCell.cs
- SafeRegistryHandle.cs
- ResXResourceWriter.cs
- AddingNewEventArgs.cs
- DragDropHelper.cs
- OuterGlowBitmapEffect.cs
- SslStreamSecurityElement.cs
- ObjectListCommandCollection.cs
- TraceListener.cs
- ImageKeyConverter.cs
- InternalBufferOverflowException.cs
- BasicKeyConstraint.cs
- BaseCAMarshaler.cs
- Transform.cs
- DropDownHolder.cs
- ConfigXmlComment.cs
- ProgressPage.cs
- IndentTextWriter.cs
- MenuBase.cs
- DesignerAutoFormatCollection.cs
- XmlDomTextWriter.cs
- PartialArray.cs
- Link.cs
- TimeSpanSecondsOrInfiniteConverter.cs
- Span.cs
- SecurityKeyType.cs
- CqlParser.cs
- StrictAndMessageFilter.cs
- GenericWebPart.cs
- OdbcFactory.cs
- AbstractDataSvcMapFileLoader.cs
- PageSettings.cs
- AnnouncementSendsAsyncResult.cs
- InvokeBase.cs