Ejemplo n.º 1
0
        public static void CreateAndCopySupportFiles(
            string pathOfAssemblyThatContainsEntryPoint,
            List <string> librariesFolders,
            string outputRootPath,
            string outputAppFilesPath,
            string outputLibrariesPath,
            string outputResourcesPath,
            string assemblyNameWithoutExtension
            )
        {
            StringBuilder codeForReferencingAdditionalLibraries = new StringBuilder();

            // Determine the output path:
            string outputPathAbsolute = PathsHelper.GetOutputPathAbsolute(pathOfAssemblyThatContainsEntryPoint, outputRootPath);

            // Combine the output path and the relative "Libraries" folder path, while also ensuring that there is no forward slash, and that the path ends with a backslash:
            string absoluteOutputLibrariesPath = PathsHelper.CombinePathsWhileEnsuringEndingBackslashAndMore(outputPathAbsolute, outputLibrariesPath); // Note: when it was hard-coded, it was Path.Combine(outputPath, @"Libraries\");

            // Create the destination folders hierarchy if it does not already exist:
            if (!Directory.Exists(absoluteOutputLibrariesPath))
            {
                Directory.CreateDirectory(absoluteOutputLibrariesPath);
            }

            // Copy the content of the "Libraries" files:
            bool mainJsilFileFound = false;

            foreach (string librariesFolder in librariesFolders)
            {
                foreach (var file in Directory.GetFiles(librariesFolder))
                {
                    string fileName = Path.GetFileName(file);
                    string outputFileWithFullPath = Path.Combine(absoluteOutputLibrariesPath, fileName);
                    if (fileName.ToUpper() == "JSIL.JS")
                    {
                        // Replace some JS code that is inside the file "JSIL.js":
                        string stringToReplace = @"src=\"""" + uri + ""\""";
                        string replaceWith     = @"src=\"""" + uri + """ + String.Format("?{0:yyyyMdHHmm}", DateTime.Now) + @"\""";
                        CopyFileWhilePerformingStringReplace(file, outputFileWithFullPath, stringToReplace, replaceWith, throwIfNotFound: true);
                        mainJsilFileFound = true;
                    }
                    else
                    {
                        File.Copy(file, Path.Combine(absoluteOutputLibrariesPath, fileName), true);
                    }
                    if (!fileName.ToUpper().StartsWith("JSIL."))
                    {
                        codeForReferencingAdditionalLibraries.AppendLine(string.Format(@"<script src=""{0}{1}"" type=""text/javascript""></script>", PathsHelper.EnsureNoBackslashAndEnsureItEndsWithAForwardSlash(outputLibrariesPath), fileName + String.Format("?{0:yyyyMdHHmm}", DateTime.Now)));
                    }
                }
            }
            if (!mainJsilFileFound)
            {
                throw new Exception("The file \"jsil.js\" was not found.");
            }

            // Generate the startup code that instantiates the application class:
            string startupCode = GenerateStartupCode(pathOfAssemblyThatContainsEntryPoint);

            // Create and save the "index.html" file:
            CreateAndSaveIndexHtml(
                outputPathAbsolute,
                startupCode,
                codeForReferencingAdditionalLibraries.ToString(),
                outputRootPath,
                outputAppFilesPath,
                outputLibrariesPath,
                outputResourcesPath,
                assemblyNameWithoutExtension
                );
        }
Ejemplo n.º 2
0
        public static void CreateAndCopySupportFiles(
            string pathOfAssemblyThatContainsEntryPoint,
            List <string> librariesFolders,
            string outputRootPath,
            string outputAppFilesPath,
            string outputLibrariesPath,
            string outputResourcesPath,
            string[] listOfResXGeneratedFiles,
            string assemblyNameWithoutExtension
            )
        {
            StringBuilder codeForReferencingAdditionalLibraries = new StringBuilder();

            // Determine the application title:
            string title = assemblyNameWithoutExtension;

            // Determine the output path:
            string outputPathAbsolute = PathsHelper.GetOutputPathAbsolute(pathOfAssemblyThatContainsEntryPoint, outputRootPath);

            // Combine the output path and the relative "Libraries" folder path, while also ensuring that there is no forward slash, and that the path ends with a backslash:
            string absoluteOutputLibrariesPath = PathsHelper.CombinePathsWhileEnsuringEndingBackslashAndMore(outputPathAbsolute, outputLibrariesPath); // Note: when it was hard-coded, it was Path.Combine(outputPath, @"Libraries\");

            // Create the destination folders hierarchy if it does not already exist:
            if (!Directory.Exists(absoluteOutputLibrariesPath))
            {
                Directory.CreateDirectory(absoluteOutputLibrariesPath);
            }

            // Copy the content of the "Libraries" files:
            foreach (string librariesFolder in librariesFolders)
            {
                foreach (var file in Directory.GetFiles(librariesFolder))
                {
                    string fileName = Path.GetFileName(file);
                    string outputFileWithFullPath = Path.Combine(absoluteOutputLibrariesPath, fileName);
                    File.Copy(file, Path.Combine(absoluteOutputLibrariesPath, fileName), true);
                }
            }

            // Read the application files from the "index.html" and "index.min.html" files generated by Bridge.NET (if found):
            // Note: the idea here is that we copy all the <script> tabs from the "index.html" file generated by Bridge to ours.
            bool   skipIndexGeneration;
            bool   skipIndexMinGeneration;
            string indexFullPath    = Path.Combine(outputPathAbsolute, "index.html");
            string indexMinFullPath = Path.Combine(outputPathAbsolute, "index.min.html");
            string scriptForApplicationFiles_readFromIndex    = ReadApplicationFilesFromBridgeGeneratedOutput(indexFullPath, out skipIndexGeneration);
            string scriptForApplicationFiles_readFromIndexMin = ReadApplicationFilesFromBridgeGeneratedOutput(indexMinFullPath, out skipIndexMinGeneration);

            // Create and save the "index.html" file:
            if (!skipIndexGeneration)
            {
                //------------
                // index.html
                //------------
                CreateAndSaveIndexHtml(
                    indexFullPath,
                    outputPathAbsolute,
                    outputRootPath,
                    outputAppFilesPath,
                    outputLibrariesPath,
                    outputResourcesPath,
                    listOfResXGeneratedFiles,
                    assemblyNameWithoutExtension,
                    title,
                    scriptForApplicationFiles_readFromIndex
                    );
            }

            // Create and save the "index.min.html" file:
            if (!skipIndexMinGeneration)
            {
                //----------------
                // index.min.html
                //----------------
                CreateAndSaveIndexHtml(
                    indexMinFullPath,
                    outputPathAbsolute,
                    outputRootPath,
                    outputAppFilesPath,
                    outputLibrariesPath,
                    outputResourcesPath,
                    listOfResXGeneratedFiles,
                    assemblyNameWithoutExtension,
                    title,
                    scriptForApplicationFiles_readFromIndexMin
                    );
            }
        }
Ejemplo n.º 3
0
        public static bool Execute(string sourceAssembly, string outputRootPath, string outputAppFilesPath, string outputLibrariesPath, string outputResourcesPath, ILogger logger)
        {
            string operationName = "C#/XAML for HTML5: OutputPathsEraser";

            try
            {
                using (var executionTimeMeasuring = new ExecutionTimeMeasuring())
                {
                    // Validate input strings:
                    if (string.IsNullOrEmpty(sourceAssembly))
                    {
                        throw new Exception(operationName + " failed because the source assembly argument is invalid.");
                    }

                    //------- DISPLAY THE PROGRESS -------
                    logger.WriteMessage(operationName + " started for assembly \"" + sourceAssembly + "\".");

                    // Determine the absolute output path:
                    string outputPathAbsolute = PathsHelper.GetOutputPathAbsolute(sourceAssembly, outputRootPath);

                    // Create the output directory if it does not already exist:
                    Directory.CreateDirectory(Path.GetDirectoryName(outputPathAbsolute));

                    // Verify that the paths are relative, not absolute, because the HTML app will use them at runtime to locate the resources, so they must be located in a subfolder of the output folder. Futhermore, this reduces the chances of accidentally deleting other user files:
                    if (Path.IsPathRooted(outputAppFilesPath))
                    {
                        throw new Exception("The output app files path ('Cshtml5OutputAppFilesPath') must be relative, not absolute: " + outputAppFilesPath);
                    }
                    if (Path.IsPathRooted(outputLibrariesPath))
                    {
                        throw new Exception("The output libraries path ('Cshtml5OutputLibrariesPath') must be relative, not absolute: " + outputLibrariesPath);
                    }
                    if (Path.IsPathRooted(outputResourcesPath))
                    {
                        throw new Exception("The output resources path ('Cshtml5OutputResourcesPath') must be relative, not absolute: " + outputResourcesPath);
                    }

                    // Determine the absolute path of the AppFiles, Libraries, and Resources subfolders of the output folder:
                    string absoluteOutputAppFilesPath  = PathsHelper.CombinePathsWhileEnsuringEndingBackslashAndMore(outputPathAbsolute, outputAppFilesPath);
                    string absoluteOutputLibrariesPath = PathsHelper.CombinePathsWhileEnsuringEndingBackslashAndMore(outputPathAbsolute, outputLibrariesPath);
                    string absoluteOutputResourcesPath = PathsHelper.CombinePathsWhileEnsuringEndingBackslashAndMore(outputPathAbsolute, outputResourcesPath);

                    // Make sure that the AppFiles, Libraries, and Resources subfolders of the output directories are empty:
                    if (Directory.Exists(absoluteOutputLibrariesPath))
                    {
                        FileHelpers.DeleteAllFilesAndFoldersInDirectory(absoluteOutputLibrariesPath); //todo: Display a warning in case that the user has specified an output path that contains stuff other than ours, such as "C:\"?
                    }
                    if (Directory.Exists(absoluteOutputResourcesPath))
                    {
                        FileHelpers.DeleteAllFilesAndFoldersInDirectory(absoluteOutputResourcesPath); //todo: Display a warning in case that the user has specified an output path that contains stuff other than ours, such as "C:\"?
                    }

                    /*
                     * NOTE: The following line was commented on October 24, 2017. In fact, starting in CSHTML5 Beta 12.3, we no longer clean up the "app" folder on recompilation, in order to speed the compilation up by re-using the assemblies that have already been compiled.
                     * if (Directory.Exists(absoluteOutputAppFilesPath))
                     *  FileHelpers.DeleteAllFilesAndFoldersInDirectory(absoluteOutputAppFilesPath);
                     */

                    //------- DISPLAY THE PROGRESS -------
                    logger.WriteMessage(operationName + " completed in " + executionTimeMeasuring.StopAndGetTimeInSeconds() + " seconds.");

                    return(true);
                }
            }
            catch (Exception ex)
            {
                logger.WriteError(operationName + " failed: " + ex.ToString());
                return(false);
            }
        }
        public static bool Execute(string sourceAssembly, string outputRootPath, string outputResourcesPath, string assembliesToIgnore, string supportedExtensions, ILogger logger, bool isBridgeBasedVersion, string typeForwardingAssemblyPath, string nameOfAssembliesThatDoNotContainUserCode, string coreAssemblyFiles, out List <string> listOfCopiedResXFiles)
        {
            string operationName = "C#/XAML for HTML5: ResourcesExtractorAndCopier";

            try
            {
                using (var executionTimeMeasuring = new ExecutionTimeMeasuring())
                {
                    // Validate input strings:
                    if (string.IsNullOrEmpty(sourceAssembly))
                    {
                        throw new Exception(operationName + " failed because the source assembly argument is invalid.");
                    }

                    //------- DISPLAY THE PROGRESS -------
                    logger.WriteMessage(operationName + " started for assembly \"" + sourceAssembly + "\".");

                    // Determine the absolute output path:
                    string outputPathAbsolute = PathsHelper.GetOutputPathAbsolute(sourceAssembly, outputRootPath);

                    // Create a separate AppDomain so that the types loaded for reflection can be unloaded when done.
                    bool isSuccess = false;
                    using (var reflectionOnSeparateAppDomain = new ReflectionOnSeparateAppDomainHandler(typeForwardingAssemblyPath))
                    {
#if BRIDGE || CSHTML5BLAZOR
                        // Load for the core assemblies first:
                        string[] coreAssemblyFilesArray = coreAssemblyFiles.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string coreAssemblyFile in coreAssemblyFilesArray)
                        {
                            reflectionOnSeparateAppDomain.LoadAssembly(coreAssemblyFile, loadReferencedAssembliesToo: false, isBridgeBasedVersion: isBridgeBasedVersion, isCoreAssembly: true, nameOfAssembliesThatDoNotContainUserCode: nameOfAssembliesThatDoNotContainUserCode, skipReadingAttributesFromAssemblies: true);
                        }
#endif

                        // Prepare some dictionaries:
                        string[] arrayWithSimpleNameOfAssembliesToIgnore = assembliesToIgnore != null?assembliesToIgnore.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries) : new string[]
                        {
                        };
                        HashSet <string> simpleNameOfAssembliesToIgnore = new HashSet <string>(arrayWithSimpleNameOfAssembliesToIgnore);
                        string[]         arrayOfSupportedExtensions     = supportedExtensions != null?supportedExtensions.ToLowerInvariant().Split(new char[]
                        {
                            '|'
                        }, StringSplitOptions.RemoveEmptyEntries) : new string[] { };
                        HashSet <string> supportedExtensionsLowercase = new HashSet <string>(arrayOfSupportedExtensions);

                        // Do the extraction and copy:
                        isSuccess = ExtractingAndCopyingResources.Start(
                            sourceAssembly,
                            outputPathAbsolute,
                            outputResourcesPath,
                            simpleNameOfAssembliesToIgnore,
                            supportedExtensionsLowercase,
                            logger,
                            reflectionOnSeparateAppDomain,
                            isBridgeBasedVersion,
                            nameOfAssembliesThatDoNotContainUserCode,
                            out listOfCopiedResXFiles);
                    }

                    //------- DISPLAY THE PROGRESS -------
                    logger.WriteMessage(operationName + (isSuccess ? " completed in " + executionTimeMeasuring.StopAndGetTimeInSeconds() + " seconds." : " failed."));

                    return(isSuccess);
                }
            }
            catch (Exception ex)
            {
                logger.WriteError(operationName + " failed: " + ex.ToString());
                listOfCopiedResXFiles = null;
                return(false);
            }
        }