Ejemplo n.º 1
0
        /// <summary>
        /// Generates the name of the cache directory for the specified script file.
        /// </summary>
        /// <param name="file">Script file name.</param>
        /// <returns>Cache directory name.</returns>
        public static string GetCacheDirectory(string file)
        {
            string commonCacheDir = Path.Combine(CSScript.GetScriptTempDir(), "cache");

            string cacheDir;
            string directoryPath = Path.GetDirectoryName(Path.GetFullPath(file));
            string dirHash;

            if (Runtime.IsWin)
            {
                //Win is not case-sensitive so ensure, both lower and capital case path yield the same hash
                dirHash = directoryPath.ToLower().GetHashCodeEx().ToString();
            }
            else
            {
                dirHash = directoryPath.GetHashCodeEx().ToString();
            }

            cacheDir = Path.Combine(commonCacheDir, dirHash);

            if (!Directory.Exists(cacheDir))
            {
                try
                {
                    Directory.CreateDirectory(cacheDir);
                }
                catch (UnauthorizedAccessException)
                {
                    var parentDir = commonCacheDir;

                    if (!Directory.Exists(commonCacheDir))
                    {
                        parentDir = Path.GetDirectoryName(commonCacheDir); // GetScriptTempDir()
                    }
                    throw new Exception("You do not have write privileges for the CS-Script cache directory (" + parentDir + "). " +
                                        "Make sure you have sufficient privileges or use an alternative location as the CS-Script " +
                                        "temporary  directory (cscs -config:set=CustomTempDirectory=<new temp dir>)");
                }
            }

            string infoFile = Path.Combine(cacheDir, "css_info.txt");

            if (!File.Exists(infoFile))
            {
                try
                {
                    using (var sw = new StreamWriter(infoFile))
                    {
                        sw.WriteLine(Environment.Version.ToString());
                        sw.WriteLine(directoryPath);
                    }
                }
                catch
                {
                    //there can be many reasons for the failure (e.g. file is already locked by another writer),
                    //which in most of the cases does not constitute the error but rather a runtime condition
                }
            }

            return(cacheDir);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Compiles the specified script text.
        /// </summary>
        /// <param name="scriptText">The script text.</param>
        /// <param name="scriptFile">The script file.</param>
        /// <param name="info">The information.</param>
        /// <returns>The method result.</returns>
        override protected (byte[] asm, byte[] pdb) Compile(string scriptText, string scriptFile, CompileInfo info)
        {
            string tempScriptFile = null;
            string injection_file = null;

            try
            {
                if (scriptFile == null)
                {
                    tempScriptFile = CSScript.GetScriptTempFile();
                    File.WriteAllText(tempScriptFile, scriptText);
                }

                var project = Project.GenerateProjectFor(tempScriptFile ?? scriptFile);
                var refs    = project.Refs.Concat(this.GetReferencedAssembliesFiles()).Distinct().ToArray();
                var sources = project.Files;

                if (info?.AssemblyFile != null)
                {
                    injection_file = CoreExtensions.GetScriptedCodeAttributeInjectionCode(info.AssemblyFile);
                    sources        = sources.Concat(new[] { injection_file }).ToArray();
                }

                int scriptHash = 0;

                if (IsCachingEnabled)
                {
                    var hashableCode = new StringBuilder();
                    hashableCode.Append($"{scriptText}.{scriptFile?.GetFullPath()}");
                    foreach (string dependencyScript in sources)
                    {
                        hashableCode.Append(File.ReadAllText(dependencyScript).GetHashCode());
                    }

                    scriptHash = $"{scriptText}.{scriptFile?.GetFullPath()}".GetHashCode(); // not very sophisticated (e.g. not all ref asms are
                                                                                            // included in hashing)
                                                                                            // but adequate

                    if (scriptCache.ContainsKey(scriptHash))
                    {
                        return(scriptCache[scriptHash]);
                    }
                }

                (byte[], byte[])result = CompileAssemblyFromFileBatch_with_Csc(sources, refs, info?.AssemblyFile, this.IsDebug, info);

                if (IsCachingEnabled)
                {
                    scriptCache[scriptHash] = result;
                }

                return(result);
            }
            finally
            {
                if (this.IsDebug)
                {
                    CSScript.NoteTempFile(tempScriptFile);
                }
                else
                {
                    tempScriptFile.FileDelete(rethrow: false);
                }

                injection_file.FileDelete(rethrow: false);

                CSScript.StartPurgingOldTempFiles(ignoreCurrentProcessScripts: true);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Wraps C# code fragment into auto-generated class (type name <c>DynamicClass</c>), evaluates it and loads
        /// the class to the current AppDomain.
        /// </summary>
        /// <example>The following is the simple example of the LoadMethod usage:
        /// <code>
        /// dynamic script = CSScript.RoslynEvaluator
        ///                          .LoadMethod(@"int Product(int a, int b)
        ///                                        {
        ///                                            return a * b;
        ///                                        }");
        ///
        /// int result = script.Product(3, 2);
        /// </code>
        /// </example>
        /// <param name="code">The C# script text.</param>
        /// <returns>Instance of the first class defined in the script.</returns>
        public object LoadMethod(string code)
        {
            string scriptText = CSScript.WrapMethodToAutoClass(code, false, false);

            return(LoadCodeByName(scriptText, $"*.{Globals.DynamicWrapperClassName}"));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Wraps C# code fragment into auto-generated class (type name <c>DynamicClass</c>), evaluates it and loads
        /// the class to the current AppDomain.
        /// <para>
        /// After initializing the class instance it is aligned to the interface specified by the parameter <c>T</c>.
        /// </para>
        /// </summary>
        /// <example>The following is the simple example of the interface alignment:
        /// <code>
        /// public interface ICalc
        /// {
        ///     int Sum(int a, int b);
        ///     int Div(int a, int b);
        /// }
        /// ....
        /// ICalc script = CSScript.RoslynEvaluator
        ///                        .LoadMethod&lt;ICalc&gt;(@"public int Sum(int a, int b)
        ///                                             {
        ///                                                 return a + b;
        ///                                             }
        ///                                             public int Div(int a, int b)
        ///                                             {
        ///                                                 return a/b;
        ///                                             }");
        /// int result = script.Div(15, 3);
        /// </code>
        /// </example>
        /// <typeparam name="T">The type of the interface type the script class instance should be aligned to.</typeparam>
        /// <param name="code">The C# script text.</param>
        /// <returns>Aligned to the <c>T</c> interface instance of the auto-generated class defined in the script.</returns>
        public T LoadMethod <T>(string code) where T : class
        {
            string scriptText = CSScript.WrapMethodToAutoClass(code, false, false, typeof(T).FullName);

            return(LoadCode <T>(scriptText));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Wraps C# code fragment into auto-generated class (type name <c>DynamicClass</c>) and evaluates it.
        /// <para>
        /// This method is a logical equivalent of <see cref="CSScriptLib.IEvaluator.CompileCode"/> but is allows you to define
        /// your script class by specifying class method instead of whole class declaration.</para>
        /// </summary>
        /// <example>
        ///<code>
        /// dynamic script = CSScript.RoslynEvaluator
        ///                          .CompileMethod(@"int Sum(int a, int b)
        ///                                           {
        ///                                               return a+b;
        ///                                           }")
        ///                          .CreateObject("*");
        ///
        /// var result = script.Sum(7, 3);
        /// </code>
        /// </example>
        /// <param name="code">The C# code.</param>
        /// <returns>The compiled assembly.</returns>
        public Assembly CompileMethod(string code)
        {
            string scriptText = CSScript.WrapMethodToAutoClass(code, false, false);

            return(CompileCode(scriptText));
        }