private static void AddAllAssembliesFromAppDomainBinDirectory(
                CompilationConfiguration result, XmlNode child)
            {
                // Get the path to the bin directory
                string binPath = HttpRuntime.BinDirectoryInternal;

                FileInfo[] binDlls;

                if (!FileUtil.DirectoryExists(binPath))
                {
                    // This is expected to fail if there is no 'bin' dir
                    Debug.Trace("Template", "Failed to access bin dir \"" + binPath + "\"");
                }
                else
                {
                    DirectoryInfo binPathDirectory = new DirectoryInfo(binPath);
                    // Get a list of all the DLL's in the bin directory
                    binDlls = binPathDirectory.GetFiles("*.dll");

                    string configFile = ConfigurationException.GetXmlNodeFilename(child);

                    for (int i = 0; i < binDlls.Length; i++)
                    {
                        string assemblyName = Util.GetAssemblyNameFromFileName(binDlls[i].Name);

                        // Remember the config file location info, in case an error
                        // occurs later when we try to load the assembly (ASURT 72183)
                        int configFileLine = ConfigurationException.GetXmlNodeLineNumber(child);
                        result._assemblies[assemblyName] = new object[]
                        { configFile, configFileLine, true /*starDirective*/ };
                    }
                }
            }
示例#2
0
            public static void OnCacheItemRemovedCallback(string key, object value, CacheItemRemovedReason reason)
            {
                CacheItemUpdateReason updateReason;
                SentinelEntry         entry = value as SentinelEntry;

                switch (reason)
                {
                case CacheItemRemovedReason.Expired:
                    updateReason = CacheItemUpdateReason.Expired;
                    break;

                case CacheItemRemovedReason.DependencyChanged:
                    updateReason = CacheItemUpdateReason.DependencyChanged;
                    if (entry.ExpensiveObjectDependency.HasChanged)
                    {
                        // If the expensiveObject has been removed explicitly by Cache.Remove,
                        // return from the SentinelEntry removed callback
                        // thus effectively removing the SentinelEntry from the cache.
                        return;
                    }
                    break;

                case CacheItemRemovedReason.Underused:
                    Debug.Fail("Reason should never be CacheItemRemovedReason.Underused since the entry was inserted as NotRemovable.");
                    return;

                default:
                    // do nothing if reason is Removed
                    return;
                }

                CacheDependency         cacheDependency;
                DateTime                absoluteExpiration;
                TimeSpan                slidingExpiration;
                object                  expensiveObject;
                CacheItemUpdateCallback callback = entry.CacheItemUpdateCallback;

                // invoke update callback
                try {
                    callback(entry.Key, updateReason, out expensiveObject, out cacheDependency, out absoluteExpiration, out slidingExpiration);
                    // Dev10 861163 - Only update the "expensive" object if the user returns a new object and the
                    // cache dependency hasn't changed.  (Inserting with a cache dependency that has already changed will cause recursion.)
                    if (expensiveObject != null && (cacheDependency == null || !cacheDependency.HasChanged))
                    {
                        HttpRuntime.Cache.Insert(entry.Key, expensiveObject, cacheDependency, absoluteExpiration, slidingExpiration, entry.CacheItemUpdateCallback);
                    }
                    else
                    {
                        HttpRuntime.Cache.Remove(entry.Key);
                    }
                }
                catch (Exception e) {
                    HttpRuntime.Cache.Remove(entry.Key);
                    try {
                        WebBaseEvent.RaiseRuntimeError(e, value);
                    }
                    catch {
                    }
                }
            }
        /// <include file='doc\BaseCompiler.uex' path='docs/doc[@for="BaseCompiler.GetGeneratedClassName"]/*' />
        /// <devdoc>
        ///     Create a name for the generated class
        /// </devdoc>
        private string GetGeneratedClassName()
        {
            string className;

            // If the user specified the class name, just use that
            if (Parser.GeneratedClassName != null)
            {
                return(Parser.GeneratedClassName);
            }

            // If we know the input file name, use it to generate the class name
            if (Parser.InputFile != null)
            {
                // Make sure we have the file name's correct case (ASURT 59179)
                className = Util.CheckExistsAndGetCorrectCaseFileName(Parser.InputFile);

                Debug.Assert(className != null);

                // Get rid of the path
                className = Path.GetFileName(className);

                // Change invalid chars to underscores
                className = Util.MakeValidTypeNameFromString(className);
            }
            else
            {
                // Otherwise, use a default name
                className = tempClassName;
            }

            return(className);
        }
示例#4
0
        /*
         * Delete an assembly that is out of date, as well as the associated files
         */
        internal static void RemoveOutOfDateAssembly(string assemblyName)
        {
            DirectoryInfo directory = new DirectoryInfo(HttpRuntime.CodegenDirInternal);

            FileInfo[] files = directory.GetFiles(assemblyName + ".*");
            foreach (FileInfo f in files)
            {
                try {
                    // First, just try to delete the file
                    f.Delete();
                }
                catch (Exception) {
                    try {
                        // If the delete failed, rename it to ".delete", so it'll get
                        // cleaned up next time by RemoveOldTempFiles()
                        // Don't do that if it already has the delete extension
                        if (f.Extension != ".delete")
                        {
                            f.MoveTo(f.FullName + ".delete");
                        }
                    }
                    catch (Exception) {
                        // Ignore all exceptions
                        Debug.Assert(false, "Cannot delete " + f.Name + " from " + directory);
                    }
                }
            }
        }
        /*
         * Set some fields that are needed for code generation
         */
        internal BaseCompiler(TemplateParser parser)
        {
            _parser = parser;

            _baseClassType = Parser.BaseType;
            Debug.Assert(_baseClassType != null);
        }
        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;
                IApplicationHost appHost;

                ApplicationManager appManager = ApplicationManager.GetApplicationManager();

                host = (BuildManagerHost)appManager.CreateObjectWithDefaultAppHostAndAppId(
                    _physicalPath, _virtualPath,
                    typeof(BuildManagerHost), false /*failIfExists*/,
                    _hostingParameters, out appId, out appHost);

                // host appdomain cannot be unloaded during creation.
                host.AddPendingCall();

                host.Configure(this);

                _host    = host;
                _appId   = appId;
                _appHost = appHost;

                _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");
        }
示例#7
0
        internal /*public*/ static void BatchCompile(string virtualDir, HttpContext context)
        {
            string prevConfigPath = context.ConfigPath;

            try {
                try {
                    // Set the config path to the virtual path that we're batching
                    Debug.Trace("Batching", "Setting ConfigPath to " + virtualDir);
                    context.ConfigPath = virtualDir;

                    BatchCompileInternal(virtualDir, context);
                }
                catch (Exception e) {
                    // Save the exception
                    _batchErrors[virtualDir] = e;
                    throw;
                }
                finally {
                    // Restore the config path to its previous value
                    Debug.Trace("Batching", "Restoring ConfigPath to " + prevConfigPath);
                    context.ConfigPath = prevConfigPath;
                }
            }
            catch { throw; } // Prevent Exception Filter Security Issue (ASURT 122825)
        }
示例#8
0
        internal static PreservedAssemblyEntry GetPreservedAssemblyEntry(HttpContext context,
                                                                         string virtualPath, bool fApplicationFile)
        {
            Debug.Trace("PreservedAssemblyEntry", "Checking for " + virtualPath);

            EnsureFirstTimeInit(context);

            string baseVirtualDir = UrlPath.GetDirectory(virtualPath);

            // No batching for global.asax
            if (!fApplicationFile)
            {
                BatchCompileDirectory(context, baseVirtualDir);
            }

            PreservedAssemblyEntry entry = new PreservedAssemblyEntry(context,
                                                                      virtualPath, fApplicationFile);

            // Try to load the entry.  It must exist, and be up to date
            if (!entry.LoadDataFromFile(fApplicationFile))
            {
                return(null);
            }

            return(entry);
        }
示例#9
0
        /*
         * Delete all temporary files from the codegen directory (e.g. source files, ...)
         */
        private static void RemoveOldTempFiles()
        {
            Debug.Trace("PreservedAssemblyEntry", "Deleting old temporary files from " + HttpRuntime.CodegenDirInternal);

            string codegen = HttpRuntime.CodegenDirInternal + "\\";

            UnsafeNativeMethods.WIN32_FIND_DATA wfd;
            IntPtr hFindFile = UnsafeNativeMethods.FindFirstFile(codegen + "*.*", out wfd);

            // No files: do nothing
            if (hFindFile == new IntPtr(-1))
            {
                return;
            }

            try {
                // Go through all the files in the codegen dir. We use the Win32 native API's
                // directly for perf and memory usage reason (ASURT 97791)
                for (bool more = true; more; more = UnsafeNativeMethods.FindNextFile(hFindFile, out wfd))
                {
                    // Skip directories
                    if ((wfd.dwFileAttributes & UnsafeNativeMethods.FILE_ATTRIBUTE_DIRECTORY) != 0)
                    {
                        continue;
                    }

                    // If it has a known extension, skip it
                    string ext = Path.GetExtension(wfd.cFileName);
                    if (ext == ".dll" || ext == ".pdb" || ext == ".web" || ext == ".xml")
                    {
                        continue;
                    }

                    // Don't delete the temp file if it's named after a dll that's still around
                    // since it could still be useful for debugging.
                    // Note that we can't use GetFileNameWithoutExtension here because
                    // some of the files are named 5hvoxl6v.0.cs, and it would return
                    // 5hvoxl6v.0 instead of just 5hvoxl6v
                    int periodIndex = wfd.cFileName.IndexOf('.');
                    if (periodIndex > 0)
                    {
                        string baseName = wfd.cFileName.Substring(0, periodIndex);

                        if (FileUtil.FileExists(codegen + baseName + ".dll"))
                        {
                            continue;
                        }
                    }

                    try {
                        File.Delete(codegen + wfd.cFileName);
                    }
                    catch { } // Ignore all exceptions
                }
            }
            finally {
                UnsafeNativeMethods.FindClose(hFindFile);
            }
        }
        /*
         * 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());
        }
        /*
         * 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());
        }
示例#13
0
        private static void BatchCompileInternal(string virtualDir, HttpContext context)
        {
            string directory = context.Request.MapPath(virtualDir);

            // Prescan all files in the current directory to see inter-file dependencies
            DirectoryInfo       filesDirectory = new DirectoryInfo(directory);
            BatchTemplateParser btp            = new BatchTemplateParser(context);

            AddFileSet(virtualDir, filesDirectory, "*.aspx", btp);
            AddFileSet(virtualDir, filesDirectory, "*.ascx", btp);

            // Based on dependencies, split into phases

            SourceReference[][] sources = BatchDependencyWalker.Split(btp.GetSourceReferences());
            btp = null;

            // Tell the server that we're still running to make sure it doesn't kill us (ASURT 96452)
            context.SendEmptyResponse();

#if DBG
            for (int i = 0; i < sources.Length; i++)
            {
                SourceReference[] bucket = sources[i];
                Debug.Trace("Batching", "");
                Debug.Trace("Batching", "Bucket " + i + " contains " + bucket.Length + " files");

                for (int j = 0; j < bucket.Length; j++)
                {
                    Debug.Trace("Batching", bucket[j].Filename);
                }
            }
#endif

            // Batch compile each phase separately

            for (int i = 0; i < sources.Length; i++)
            {
                SourceReference[] batch = sources[i];
                ArrayList         list  = new ArrayList();

                // cons up the TemplateParserParameters

                for (int j = 0; j < batch.Length; j++)
                {
                    string filename    = batch[j].Filename;
                    string virtualPath = UrlPath.Combine(virtualDir,
                                                         Path.GetFileName(filename));
                    list.Add(new BatchCompilationEntry(virtualPath, filename, context));
                }

                // Now batch compile them

                if (list.Count > 0)
                {
                    BatchCompile(list, context, virtualDir);
                }
            }
        }
        public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path)
        {
            Debug.Trace("PageHandlerFactory", "PageHandlerFactory: " + virtualPath);

            // This should never get called in ISAPI mode but currently is in integrated mode
            // Debug.Assert(false);

            return(GetHandlerHelper(context, requestType, VirtualPath.CreateNonRelative(virtualPath), path));
        }
        /*
         * 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));
        }
        static bool GetSiteNameFromISAPI()
        {
            Debug.Trace("config_loc", "GetSiteNameFromISAPI()");
            HttpContext context = HttpContext.Current;

            if (context != null)
            {
                string       metabaseAppKey = context.Request.ServerVariables["INSTANCE_META_PATH"];
                const string KEY_LMW3SVC    = "/LM/W3SVC/";
                Debug.Assert(metabaseAppKey.StartsWith(KEY_LMW3SVC));
                string appNumber = metabaseAppKey.Substring(KEY_LMW3SVC.Length - 1);
                //string appServerComment = "/" + appNumber + "/ServerComment";
                Debug.Trace("config_loc", "appNumber:" + appNumber + " INSTANCE_META_PATH:" + metabaseAppKey);

                UnicodeEncoding encoding = new UnicodeEncoding();

                // null-terminate appNumber and convert to byte array
                byte [] byteAppNumber = encoding.GetBytes(appNumber + "\0");

                int     retVal   = 2;
                byte [] outBytes = new byte[64];
                while (retVal == 2)
                {
                    retVal = context.CallISAPI(UnsafeNativeMethods.CallISAPIFunc.GetSiteServerComment,
                                               byteAppNumber, outBytes);
                    if (retVal == 2)
                    {
                        if (outBytes.Length > 1024)   // should never happen
                        {
                            throw new ConfigurationException(HttpRuntime.FormatResourceString(
                                                                 SR.Config_site_name_too_long,
                                                                 metabaseAppKey));
                        }
                        outBytes = new byte[outBytes.Length * 2];
                    }
                }

                // find WCHAR null terminator in byte array
                int i = 0;
                while (i + 1 < outBytes.Length && (outBytes[i] != 0 || outBytes[i + 1] != 0))
                {
                    i += 2;
                }

                // decode up to null terminator
                s_siteName = encoding.GetString(outBytes, 0, i);
                Debug.Trace("config_loc", "i: " + i + " site name:" + s_siteName);

                return(true);
            }
            else
            {
                Debug.Trace("config_loc", "could not query site name.  No Context.");
            }

            return(false); // keep trying to evaluate
        }
        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));
            }
        }
        // GetSection
        //
        // Get the Config for a specific path
        //
        static internal object GetSection(string sectionName, VirtualPath path)
        {
            Debug.Assert(UseHttpConfigurationSystem, "UseHttpConfigurationSystem");

            CachedPathData pathData;

            pathData = CachedPathData.GetVirtualPathData(path, true);

            return(pathData.ConfigRecord.GetSection(sectionName));
        }
        // GetAppSection
        //
        // Get the Config for a specific path
        //
        static internal object GetApplicationSection(string sectionName)
        {
            Debug.Assert(UseHttpConfigurationSystem, "UseHttpConfigurationSystem");

            CachedPathData pathData;

            pathData = CachedPathData.GetApplicationPathData();

            return(pathData.ConfigRecord.GetSection(sectionName));
        }
示例#20
0
        protected SimpleWebHandlerParser(HttpContext context, string virtualPath, string physicalPath)
        {
            // These obsolete parameters should never be set
            Debug.Assert(context == null);
            Debug.Assert(physicalPath == null);

            Debug.Assert(virtualPath != null);

            _virtualPath = VirtualPath.Create(virtualPath);
        }
        // Called by BuildManagerHost when the ASP appdomain is unloaded
        internal void OnAppDomainUnloaded(ApplicationShutdownReason reason)
        {
            Debug.Trace("CBM", "OnAppDomainUnloaded " + reason.ToString());

            _reason          = reason;
            _waitForCallBack = false;

            // Don't do anything that can be slow here.  Instead queue in a worker thread
            ThreadPool.QueueUserWorkItem(_onAppDomainUnloadedCallback);
        }
示例#22
0
        /*
         * Build first-time intialization statements
         */
        protected override void BuildInitStatements(CodeStatementCollection trueStatements, CodeStatementCollection topLevelStatements)
        {
            base.BuildInitStatements(trueStatements, topLevelStatements);

            CodeMemberField fileDependencies = new CodeMemberField(typeof(ArrayList), fileDependenciesName);

            fileDependencies.Attributes |= MemberAttributes.Static;
            _sourceDataClass.Members.Add(fileDependencies);

            // Note: it may look like this local variable declaraiton is redundant. However it is necessary
            // to make this init code re-entrant safe. This way, even if two threads enter the contructor
            // at the same time, they will not add multiple dependencies.

            // e.g. ArrayList dependencies;
            CodeVariableDeclarationStatement dependencies = new CodeVariableDeclarationStatement();

            dependencies.Type = new CodeTypeReference(typeof(ArrayList));
            dependencies.Name = dependenciesLocalName;
            topLevelStatements.Insert(0, dependencies);

            // e.g. dependencies = new System.Collections.ArrayList();
            CodeAssignStatement assignDependencies = new CodeAssignStatement();

            assignDependencies.Left  = new CodeVariableReferenceExpression(dependenciesLocalName);
            assignDependencies.Right = new CodeObjectCreateExpression(typeof(ArrayList));
            // Note: it is important to add all local variables at the top level for CodeDom Subset compliance.
            trueStatements.Add(assignDependencies);

            Debug.Assert(Parser.FileDependencies != null);
            if (Parser.FileDependencies != null)
            {
                int count = Parser.FileDependencies.Length;
                for (int i = 0; i < count; i++)
                {
                    // depdendencies.Add("...");
                    CodeMethodInvokeExpression addFileDep = new CodeMethodInvokeExpression();
                    addFileDep.Method.TargetObject = new CodeVariableReferenceExpression(dependenciesLocalName);
                    addFileDep.Method.MethodName   = "Add";
                    addFileDep.Parameters.Add(new CodePrimitiveExpression((string)Parser.FileDependencies[i]));
                    trueStatements.Add(new CodeExpressionStatement(addFileDep));
                }
            }

            // e.g. __fileDependencies = dependencies;
            CodeAssignStatement initFile = new CodeAssignStatement();

            initFile.Left = new CodeFieldReferenceExpression(_classTypeExpr,
                                                             fileDependenciesName);
            initFile.Right = new CodeVariableReferenceExpression(dependenciesLocalName);

#if DBG
            AppendDebugComment(trueStatements);
#endif
            trueStatements.Add(initFile);
        }
示例#23
0
 internal static void RemoveBackgroundBatchCompilation(BackgroundBatchCompiler bbc)
 {
     lock (_backgroundBatchCompilations) {
         try {
             _backgroundBatchCompilations.Remove(bbc);
         }
         catch {
             Debug.Assert(false, "RemoveBackgroundBatchCompilation failed");
         }
     }
 }
示例#24
0
        protected void AddDependency(VirtualPath virtualPath)
        {
            virtualPath = ResolveVirtualPath(virtualPath);
            Debug.Trace("Template", "Parsed dependency: " + _virtualPath + " depends on " + virtualPath);

            if (_virtualPathDependencies == null)
            {
                _virtualPathDependencies = new CaseInsensitiveStringSet();
            }

            _virtualPathDependencies.Add(virtualPath.VirtualPathString);
        }
        /// <devdoc>
        /// Returns an IEnumerable that is the DataSource, which either came
        /// from the DataSource property or from the control bound via the
        /// DataSourceID property.
        /// </devdoc>
        protected virtual IEnumerable GetData()
        {
            DataSourceView view = ConnectToDataSourceView();

            Debug.Assert(_currentViewValid);

            if (view != null)
            {
                return(view.ExecuteSelect(DataSourceSelectArguments.Empty));
            }
            return(null);
        }
        /*
         * Build a ProcessRequest override which just calls the base.  This is used to make sure
         * there is user code on the stack when requests are executed (VSWhidbey 499386)
         */
        private void BuildProcessRequestOverride()
        {
            //  public override void ProcessRequest(HttpContext context) {
            //      base.ProcessRequest(context);
            //  }

            CodeMemberMethod method = new CodeMemberMethod();

            AddDebuggerNonUserCodeAttribute(method);
            method.Name        = "ProcessRequest";
            method.Attributes &= ~MemberAttributes.AccessMask;
            method.Attributes &= ~MemberAttributes.ScopeMask;

            // If the base type is non-default (i.e. not Page) we have to be careful overriding
            // ProcessRequest, because if the base has its own IHttpHandler.ProcessRequest implementation
            // and it's not overridable, we would fail to compile.  So when we detect this situation,
            // we instead generate it as a new IHttpHandler.ProcessRequest implementation instead of an
            // override.  In theory, we could *always* do this, but it's safer to limit it to this
            // constrained scenario (VSWhidbey 517240)
            MethodInfo methodInfo = null;

            if (Parser.BaseType != typeof(Page))
            {
                methodInfo = Parser.BaseType.GetMethod("ProcessRequest",
                                                       BindingFlags.Public | BindingFlags.Instance,
                                                       null, new Type[] { typeof(HttpContext) }, null);
                Debug.Assert(methodInfo != null);
            }

            _sourceDataClass.BaseTypes.Add(new CodeTypeReference(typeof(IHttpHandler)));

            if (methodInfo != null && methodInfo.DeclaringType != typeof(Page))
            {
                method.Attributes |= MemberAttributes.New | MemberAttributes.Public;
            }
            else
            {
                method.Attributes |= MemberAttributes.Override | MemberAttributes.Public;
            }

            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(HttpContext), "context"));

            CodeMethodInvokeExpression invokeExpr = new CodeMethodInvokeExpression();

            invokeExpr.Method.TargetObject = new CodeBaseReferenceExpression();
            invokeExpr.Method.MethodName   = "ProcessRequest";
            invokeExpr.Parameters.Add(new CodeArgumentReferenceExpression("context"));

            method.Statements.Add(invokeExpr);

            _sourceDataClass.Members.Add(method);
        }
        /*
         * 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 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 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));
        }
        public bool Unload()
        {
            Debug.Trace("CBM", "Unload");

            BuildManagerHost host = _host;

            if (host != null)
            {
                _host = null;
                return(host.UnloadAppDomain());
            }

            return(false);
        }