Beispiel #1
0
        static void CreateAndSaveIndexHtml(
            string outputPathAbsolute,
            string startupCode,
            string codeForReferencingAdditionalLibraries,
            string outputRootPath,
            string outputAppFilesPath,
            string outputLibrariesPath,
            string outputResourcesPath,
            string assemblyNameWithoutExtension
            )
        {
            // Read the "index.html" template:
            string indexHtmlFileTemplate = WrapperHelpers.ReadTextFileFromEmbeddedResource("index.html");

            // Replace the placeholders:
            string indexHtmlFile = indexHtmlFileTemplate.Replace("[BOOT_JAVASCRIPT_CODE_GOES_HERE]", startupCode);

            indexHtmlFile = indexHtmlFile.Replace("[ADDITIONAL_LIBRARIES_GO_HERE]", codeForReferencingAdditionalLibraries);
            indexHtmlFile = indexHtmlFile.Replace("[LIBRARIES_PATH_GOES_HERE]", PathsHelper.EnsureNoBackslashAndEnsureItEndsWithAForwardSlash(outputLibrariesPath));
            indexHtmlFile = indexHtmlFile.Replace("[APPFILES_PATH_GOES_HERE]", PathsHelper.EnsureNoBackslashAndEnsureItEndsWithAForwardSlash(outputAppFilesPath));

            // Prevent browser caching of the JSIL and CSHTML5 libraries:
            indexHtmlFile = WrapperHelpers.AppendDateToLibraryFileName("JSIL.js", indexHtmlFile);
            indexHtmlFile = WrapperHelpers.AppendDateToLibraryFileName("cshtml5.js", indexHtmlFile);
            indexHtmlFile = WrapperHelpers.AppendDateToLibraryFileName("cshtml5.css", indexHtmlFile);

            // Read the "App.Config" file for future use by the ClientBase.
            string relativePathToAppConfigFolder = PathsHelper.CombinePathsWhileEnsuringEndingBackslashAndMore(outputResourcesPath, assemblyNameWithoutExtension);
            string relativePathToAppConfig       = Path.Combine(relativePathToAppConfigFolder, "app.config.g.js");

            if (File.Exists(Path.Combine(outputPathAbsolute, relativePathToAppConfig)))
            {
                string scriptToReadAppConfig = "<script type=\"application/javascript\" src=\"" + relativePathToAppConfig + "\"></script>";
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPT_TO_READ_APPCONFIG_GOES_HERE]", scriptToReadAppConfig);
            }
            else
            {
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPT_TO_READ_APPCONFIG_GOES_HERE]", string.Empty);
            }

            // Read the "ServiceReferences.ClientConfig" file for future use by the ClientBase.
            string relativePathToServiceReferencesClientConfig = Path.Combine(relativePathToAppConfigFolder, "servicereferences.clientconfig.g.js");

            if (File.Exists(Path.Combine(outputPathAbsolute, relativePathToServiceReferencesClientConfig)))
            {
                string scriptToReadServiceReferencesClientConfig = "<script src=\"" + relativePathToServiceReferencesClientConfig.Replace('\\', '/') + "\"></script>";
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPT_TO_READ_SERVICEREFERENCESCLIENTCONFIG_GOES_HERE]", scriptToReadServiceReferencesClientConfig);
            }
            else
            {
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPT_TO_READ_SERVICEREFERENCESCLIENTCONFIG_GOES_HERE]", string.Empty);
            }

            // Save the "index.html" to the final folder:
            File.WriteAllText(Path.Combine(outputPathAbsolute, "index.html"), indexHtmlFile);
        }
        public static bool Start(string assemblyPath, string outputPathAbsolute, string outputResourcesPath, HashSet <string> simpleNameOfAssembliesToIgnore, HashSet <string> supportedExtensionsLowercase, ILogger logger, ReflectionOnSeparateAppDomainHandler reflectionOnSeparateAppDomain, bool isBridgeBasedVersion, string nameOfAssembliesThatDoNotContainUserCode, out List <string> resXFilesCopied)
        {
            resXFilesCopied = new List <string>();
            List <string> assemblySimpleNames;

            reflectionOnSeparateAppDomain.LoadAssemblyAndAllReferencedAssembliesRecursively(
                assemblyPath,
                isBridgeBasedVersion: isBridgeBasedVersion,
                isCoreAssembly: false,
                nameOfAssembliesThatDoNotContainUserCode: nameOfAssembliesThatDoNotContainUserCode,
                skipReadingAttributesFromAssemblies: true,
                assemblySimpleNames: out assemblySimpleNames);

            foreach (string assemblySimpleName in assemblySimpleNames)
            {
                if (!simpleNameOfAssembliesToIgnore.Contains(assemblySimpleName))
                {
                    //-----------------------------------------------
                    // Process JavaScript, CSS, Image, Video, Audio files:
                    //-----------------------------------------------

#if !CSHTML5BLAZOR
                    Dictionary <string, byte[]> jsAndCssFiles = reflectionOnSeparateAppDomain.GetResources(assemblySimpleName, supportedExtensionsLowercase);
#else
                    Dictionary <string, byte[]> jsAndCssFiles = reflectionOnSeparateAppDomain.GetManifestResources(assemblySimpleName, supportedExtensionsLowercase);
#endif
                    // Copy files:
                    foreach (KeyValuePair <string, byte[]> file in jsAndCssFiles)
                    {
                        string fileName    = file.Key;
                        byte[] fileContent = file.Value;

                        // Combine the root output path and the relative "resources" folder path, while also ensuring that there is no forward slash, and that the path ends with a backslash:
                        string absoluteOutputResourcesPath = PathsHelper.CombinePathsWhileEnsuringEndingBackslashAndMore(outputPathAbsolute, outputResourcesPath);

                        // Create the destination folders hierarchy if it does not already exist:
                        string destinationFile = Path.Combine(absoluteOutputResourcesPath, assemblySimpleName + "\\", fileName);
                        if (destinationFile.Length < 256)
                        {
                            string destinationDirectory = Path.GetDirectoryName(destinationFile);
                            if (!Directory.Exists(destinationDirectory))
                            {
                                Directory.CreateDirectory(destinationDirectory);
                            }

                            // Create the file:
                            File.WriteAllBytes(destinationFile, fileContent);

                            //put the file name in the list of files:
                            if (fileName.EndsWith(".resx.js"))
                            {
                                resXFilesCopied.Add(destinationFile);
                            }
                        }
                        else
                        {
                            logger.WriteWarning("Could not create the following output file because its path is too long: " + destinationFile);
                        }
                    }


                    #region Commented because this operation is now done in the "JavaScriptGenerator" build task ("ConvertingResXFilesToJavaScript.cs").
                    ////-----------------------------------------------
                    //// Process RESX files:
                    ////-----------------------------------------------

                    //Dictionary<string, byte[]> resXFiles = reflectionOnSeparateAppDomain.GetManifestResources(assemblySimpleName,
                    //    (fn) => fn.ToLower().EndsWith(".resources") && !fn.ToLower().EndsWith(".g.resources"));

                    //foreach (KeyValuePair<string, byte[]> file in resXFiles)
                    //{
                    //    string fileName = file.Key;
                    //    byte[] fileContent = file.Value;

                    //    // Create destination folders hierarchy:
                    //    string destinationFile = Path.Combine(outputPath, ResourceCopier.NAME_OF_FOLDER_THAT_CONTAINS_RESOURCES + "\\", Path.GetFileNameWithoutExtension(fileName) + ".resj");
                    //    string destinationDirectory = Path.GetDirectoryName(destinationFile);
                    //    Directory.CreateDirectory(destinationDirectory);

                    //    // Create JSON from RESX:
                    //    string json = "";
                    //    using (Stream stream = new MemoryStream(fileContent))
                    //    {
                    //        json = ConvertingResXFilesToJavaScript.ConvertResources(stream);
                    //    }

                    //    // Save file:
                    //    File.WriteAllText(destinationFile, json);
                    //}
                    #endregion
                }
            }

            return(true);
        }
Beispiel #3
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
                );
        }
Beispiel #4
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);
            }
        }
Beispiel #5
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
                    );
            }
        }
Beispiel #6
0
        static void CreateAndSaveIndexHtml(
            string outputFileNameWithPath,
            string outputPathAbsolute,
            string outputRootPath,
            string outputAppFilesPath,
            string outputLibrariesPath,
            string outputResourcesPath,
            string[] listOfResXGeneratedFiles,
            string assemblyNameWithoutExtension,
            string title,
            string scriptsForApplicationFiles
            )
        {
            // Read the "index.html" template:
            string indexHtmlFileTemplate = WrapperHelpers.ReadTextFileFromEmbeddedResource("index_BridgeVersion.html");

            // Replace the placeholders:
            string indexHtmlFile = indexHtmlFileTemplate.Replace("[LIBRARIES_PATH_GOES_HERE]", PathsHelper.EnsureNoBackslashAndEnsureItEndsWithAForwardSlash(outputLibrariesPath));

            indexHtmlFile = indexHtmlFile.Replace("[TITLE_GOES_HERE]", title);
            indexHtmlFile = indexHtmlFile.Replace("[SCRIPTS_FOR_APPLICATION_FILES_GO_HERE]", scriptsForApplicationFiles);

            // Read the "App.Config" file for future use by the ClientBase.
            string relativePathToAppConfigFolder = PathsHelper.CombinePathsWhileEnsuringEndingBackslashAndMore(outputResourcesPath, assemblyNameWithoutExtension);
            string relativePathToAppConfig       = Path.Combine(relativePathToAppConfigFolder, "app.config.g.js");

            if (File.Exists(Path.Combine(outputPathAbsolute, relativePathToAppConfig)))
            {
                string scriptToReadAppConfig = "        <script src=\"" + relativePathToAppConfig.Replace('\\', '/') + "\"></script>";
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPT_TO_READ_APPCONFIG_GOES_HERE]", scriptToReadAppConfig);
            }
            else
            {
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPT_TO_READ_APPCONFIG_GOES_HERE]", string.Empty);
            }

            // Read the "ServiceReferences.ClientConfig" file for future use by the ClientBase.
            string relativePathToServiceReferencesClientConfig = Path.Combine(relativePathToAppConfigFolder, "servicereferences.clientconfig.g.js");

            if (File.Exists(Path.Combine(outputPathAbsolute, relativePathToServiceReferencesClientConfig)))
            {
                string scriptToReadServiceReferencesClientConfig = "        <script src=\"" + relativePathToServiceReferencesClientConfig.Replace('\\', '/') + "\"></script>";
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPT_TO_READ_SERVICEREFERENCESCLIENTCONFIG_GOES_HERE]", scriptToReadServiceReferencesClientConfig);
            }
            else
            {
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPT_TO_READ_SERVICEREFERENCESCLIENTCONFIG_GOES_HERE]", string.Empty);
            }

            // Add the scripts for reading the ResX files:
            if (listOfResXGeneratedFiles != null && listOfResXGeneratedFiles.Length > 0)
            {
                string resultingStringForLoadingResXFiles = String.Empty;
                foreach (string str in listOfResXGeneratedFiles)
                {
                    int indexForRelativePath = str.IndexOf(outputResourcesPath);
                    if (indexForRelativePath == -1)
                    {
                        throw new Exception(string.Format("The file path '{0}' does not contain the substring '{1}'.", str, outputResourcesPath));
                    }
                    string relativePath = str.Substring(indexForRelativePath).Replace('\\', '/');
                    resultingStringForLoadingResXFiles += Environment.NewLine + "        <script src=\"" + relativePath + "\"></script>";
                }
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPTS_FOR_RESX_GO_HERE]", resultingStringForLoadingResXFiles);
            }
            else
            {
                indexHtmlFile = indexHtmlFile.Replace("[SCRIPTS_FOR_RESX_GO_HERE]", string.Empty);
            }

            // Add the version number to the files so that they are cached by the web browser only until a new version is available:
            indexHtmlFile = indexHtmlFile.Replace(".js\"", ".js?" + String.Format("?{0:yyyyMMddHHmm}", DateTime.UtcNow) + "\"");
            indexHtmlFile = indexHtmlFile.Replace(".css\"", ".css?" + String.Format("?{0:yyyyMMddHHmm}", DateTime.UtcNow) + "\"");

            // Save the "index.html" to the final folder:
            File.WriteAllText(outputFileNameWithPath, indexHtmlFile);
        }