Пример #1
0
            private static string CreateProject(string scriptFile, string tempDir, ProcessSourceFile fileHandler, bool copyLocalAsm)
            {
                string srcProjDir = @"Lib\Debug\VS10.0"; //relative to CSSCRIPT_DIR
                string scHomeDir = VS100IDE.GetEnvironmentVariable("CSSCRIPT_DIR");
                string scriptShortName = Path.GetFileName(scriptFile);
                string projFile = Path.Combine(tempDir, "DebugScript.csproj");
                string solutionFile = Path.Combine(tempDir, "DebugScript.sln");

                //copy project template
                if (!Directory.Exists(tempDir))
                    Directory.CreateDirectory(tempDir);

                foreach (string file in Directory.GetFiles(Path.Combine(scHomeDir, srcProjDir)))
                {
                    if (Path.GetExtension(file) != ".resx")
                    {
                        if (string.Compare(Path.GetFileName(file), "AssemblyInfo.cs", true) == 0)
                        {
                            using (StreamReader sr = new StreamReader(file))
                            using (StreamWriter sw = new StreamWriter(Path.Combine(tempDir, Path.GetFileName(file))))
                            {
                                string code = sr.ReadToEnd().Replace("ScriptDebugger", Path.GetFileNameWithoutExtension(scriptFile));
                                sw.Write(code);
                            }
                        }
                        else
                        {
                            File.Copy(file, Path.Combine(tempDir, Path.GetFileName(file)), true);
                        }
                    }
                }

                //update project template with script specific data
                VS100IDE ide = new VS100IDE();

                ScriptParser parser = new ScriptParser(scriptFile, Script.SearchDirs, VS100IDE.isolating);
                AssemblyResolver asmResolver = new AssemblyResolver();

                foreach (string dir in parser.SearchDirs)
                    AddSearchDir(dir);

                string resxSrcFile = Path.Combine(Path.Combine(scHomeDir, srcProjDir), "Form1.resx");
                bool XAML = false;
                bool WWF = false;

                ArrayList importerdScripts = new ArrayList();
                ArrayList precompilibleScripts = new ArrayList();
                importerdScripts.AddRange(parser.SaveImportedScripts());

                string srcFile = fileHandler(scriptFile, tempDir);
                XAML = srcFile.ToLower().EndsWith(".xaml");

                string associatedXml = FindAssociatedXml(srcFile, (string[])importerdScripts.ToArray(typeof(string)));

                string precompiler = "";
                if (UsesPreprocessor(srcFile, out precompiler))
                    precompilibleScripts.Add(new string[] { srcFile, precompiler });

                if (VS100IDE.IsResxRequired(srcFile) && associatedXml == "")
                    ide.InsertFile(srcFile, projFile, resxSrcFile, "");
                else
                {
                    if (associatedXml != "")
                        ide.InsertXamlCSFile(srcFile, projFile, associatedXml);
                    else
                        ide.InsertFile(srcFile, projFile, "", "");
                }

                foreach (string file in importerdScripts)
                {
                    if (UsesPreprocessor(file, out precompiler))
                        precompilibleScripts.Add(new string[] { file, precompiler });

                    srcFile = fileHandler(file, tempDir);
                    associatedXml = FindAssociatedXml(srcFile, (string[])importerdScripts.ToArray(typeof(string)));
                    XAML = srcFile.ToLower().EndsWith(".xaml");
                    if (!Path.GetFileName(srcFile).StartsWith("i_") && VS100IDE.IsResxRequired(srcFile) && associatedXml == "")
                    {
                        ide.InsertFile(srcFile, projFile, resxSrcFile, "");
                    }
                    else
                    {
                        if (associatedXml != "")
                            ide.InsertXamlCSFile(srcFile, projFile, associatedXml);
                        else
                            ide.InsertFile(srcFile, projFile, "", "");
                    }
                }

                if (XAML)
                    ide.InsertImport(@"$(MSBuildBinPath)\Microsoft.WinFX.targets", projFile);

                ArrayList referencedNamespaces = new ArrayList(parser.ReferencedNamespaces);

                string[] defaultAsms = (CSScript.GlobalSettings.DefaultRefAssemblies ?? "")
                                        .Replace(" ", "")
                                        .Split(";,".ToCharArray());
                referencedNamespaces.AddRange(defaultAsms);

                if (precompilibleScripts.Count > 0)
                {
                    referencedNamespaces.Add("CSScriptLibrary");

                    Hashtable ht = new Hashtable();
                    foreach (string[] info in precompilibleScripts)
                    {
                        if (!ht.ContainsKey(info[1])) //to avoid duplication
                        {
                            ht[info[1]] = true;
                            string t = Path.GetDirectoryName(scriptFile);

                            ide.InsertFile(Path.Combine(Path.GetDirectoryName(scriptFile), info[1]), projFile, "", "");
                        }
                    }

                    string commands = "";
                    foreach (string[] info in precompilibleScripts)
                        commands += "cscs.exe \"" + Path.Combine(Path.GetDirectoryName(scriptFile), info[1]) + "\" \"" + info[0] + "\" \"/primary:" + scriptFile + "\"" + "\r\n";

                    string firstPrecompiler = (precompilibleScripts[0] as string[])[1];
                    ide.InsertFile(Path.Combine(scHomeDir, "Lib\\precompile.part.cs"), projFile, "", firstPrecompiler);
                    ide.InsertPreBuildEvent(commands, projFile);
                    //<PropertyGroup>
                    //<PreBuildEvent>cscs.exe "C:\cs-script\Dev\Macros C#\precompile.cs" "C:\cs-script\Dev\Macros C#\code.cs"</PreBuildEvent>
                    //</PropertyGroup>
                }

                foreach (string name in referencedNamespaces)
                {
                    bool ignore = false;
                    foreach (string ignoreName in parser.IgnoreNamespaces)
                        if (ignore = (name == ignoreName))
                            break;

                    if (ignore)
                        continue;

                    string[] asmFiles = AssemblyResolver.FindAssembly(name, SearchDirs);
                    foreach (string file in asmFiles)
                    {
                        if (!WWF && file.ToLower().IndexOf("system.workflow.runtime") != -1)
                            WWF = true;

                        if (!copyLocalAsm || file.IndexOf("assembly\\GAC") != -1 || file.IndexOf("assembly/GAC") != -1)
                            ide.InsertReference(file, projFile);
                        else
                        {
                            string asmCopy = Path.Combine(tempDir, Path.GetFileName(file));
                            File.Copy(file, asmCopy, true);

                            ide.InsertReference(Path.GetFileName(asmCopy), projFile);
                        }
                    }
                }

                foreach (string asm in parser.ReferencedAssemblies) //some assemblies were referenced from code
                {
                    foreach (string file in AssemblyResolver.FindAssembly(asm, SearchDirs))
                    {
                        if (!WWF && file.ToLower().IndexOf("system.workflow.runtime") != -1)
                            WWF = true;

                        if (!copyLocalAsm || file.IndexOf("assembly\\GAC") != -1 || file.IndexOf("assembly\\GAC") != -1)
                            ide.InsertReference(file, projFile);
                        else
                        {
                            string asmCopy = Path.Combine(tempDir, Path.GetFileName(file));
                            if (Path.IsPathRooted(file) || File.Exists(file))
                                File.Copy(file, asmCopy, true);
                            ide.InsertReference(Path.GetFileName(asmCopy), projFile);
                        }
                    }
                }

                //adjust project settings
                if (WWF)
                {
                    ide.InsertProjectTypeGuids("{14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", projFile);
                    ide.InsertImport(@"$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.0\Workflow.Targets", projFile);

                    foreach (string file in importerdScripts)
                        if (file.ToLower().IndexOf("designer.cs") != -1)
                        {
                            string className = Path.GetFileNameWithoutExtension(file.ToLower()).Replace(".designer", "");
                            string template = Path.Combine(tempDir, "wwf.layout");
                            string layoutFile = file.Replace("designer.cs", "layout");

                            if (copyLocalAsm) //isolating
                                layoutFile = Path.Combine(Path.GetDirectoryName(projFile), Path.GetFileName(layoutFile));

                            File.Copy(template, layoutFile, true);
                            ReplaceInFile(layoutFile, "WFInitialState", className + "InitialState");

                            ide.InsertResource(layoutFile, projFile);
                        }
                }

                CSharpParser fileParser = new CSharpParser(scriptFile, true, new string[] { "//css_dbg", "//css_args", "//css_co" });

                //foreach (string statement in fileParser.CustomDirectives["//css_dbg"] as List<string>)//should be  reenabled when CS-Script is compiled for  .NET 2.0
                foreach (string statement in fileParser.CustomDirectives["//css_dbg"] as IEnumerable)
                    foreach (string directive in statement.Split(','))
                    {
                        string d = directive.Trim();
                        if (d.StartsWith("/t:"))
                            ide.SetOutputType(d.Substring("/t:".Length), projFile);
                        else if (d.StartsWith("/platform:"))
                            ide.SetPlatformType(d.Substring("/platform:".Length), projFile, solutionFile);
                        else if (d.Trim().StartsWith("/args:"))
                            ide.SetArguments(d.Substring("/args:".Length), projFile + ".user");
                    }

                //foreach (string statement in fileParser.CustomDirectives["//css_args"] as List<string>) //should be  reenabled when CS-Script is compiled for  .NET 2.0
                foreach (string statement in fileParser.CustomDirectives["//css_args"] as IEnumerable)
                    foreach (string directive in statement.Split(','))
                    {
                        string d = directive.Trim();
                        if (d.StartsWith("/co"))
                        {
                            string[] compilerOptions = d.Substring(4).Split(',');
                            foreach (string option in compilerOptions)
                            {
                                string o = option.Trim();
                                if (o.StartsWith("/unsafe"))
                                    ide.SetAllowUnsafe(projFile);
                                else if (o.StartsWith("/platform:"))
                                    ide.SetPlatformType(o.Substring("/platform:".Length), projFile, solutionFile);
                            }
                        }
                    }

                foreach (string statement in fileParser.CustomDirectives["//css_co"] as IEnumerable)
                    foreach (string directive in statement.Split(','))
                    {
                        string d = directive.Trim();
                        if (d.StartsWith("/platform:"))
                            ide.SetPlatformType(d.Substring("/platform:".Length), projFile, solutionFile);
                    }

                Settings settings = GetSystemWideSettings();
                if (settings != null)
                    ide.SetTargetFramework(settings.TargetFramework, projFile);

                ide.SetWorkingDir(Path.GetDirectoryName(scriptFile), projFile + ".user");

                if (!VS100IDE.isolating)
                    ide.RemoveFile("AssemblyInfo.cs", projFile);

                string appConfigFile = "";

                if (File.Exists(Path.ChangeExtension(scriptFile, ".cs.config")))
                    appConfigFile = Path.ChangeExtension(scriptFile, ".cs.config");
                else if (File.Exists(Path.ChangeExtension(scriptFile, ".exe.config")))
                    appConfigFile = Path.ChangeExtension(scriptFile, ".exe.config");

                if (appConfigFile != "")
                    ide.InsertAppConfig(appConfigFile, projFile);

                ///////////////////////////////////
                //rename project files
                string newSolutionFile = Path.Combine(tempDir, Path.GetFileNameWithoutExtension(scriptFile) + " (script).sln");
                string newProjectFile = Path.Combine(tempDir, Path.GetFileNameWithoutExtension(newSolutionFile) + ".csproj");

                FileMove(solutionFile, newSolutionFile);
                FileMove(projFile, newProjectFile);
                FileMove(projFile + ".user", newProjectFile + ".user");

                ReplaceInFile(newSolutionFile, Path.GetFileNameWithoutExtension(projFile), Path.GetFileNameWithoutExtension(newProjectFile));
                ReplaceInFile(newProjectFile, "DebugScript", Path.GetFileNameWithoutExtension(scriptFile));

                //remove xmlns=""
                VSProjectDoc.FixFile(newProjectFile);
                VSProjectDoc.FixFile(newProjectFile + ".user");

                ///////////////////////
                return newSolutionFile;
            }
Пример #2
0
        public static void Main(string[] args)
        {
            SetEnvironmentVariable("CSScriptDebugging", "VS10.0");
            if (args.Length == 0 || (args.Length == 1 && (args[0] == "?" || args[0] == "/?" || args[0] == "-?" || args[0].ToLower() == "help")))
            {
                Console.WriteLine(usage);
            }
            else if (args[0].Trim().ToLower() == "/prj")
            {
                scriptFile = ResolveScriptFile(args[1]);
                try
                {
                    VS100IDE.IsolateProject(scriptFile, Path.Combine(Path.GetDirectoryName(scriptFile), Path.GetFileNameWithoutExtension(scriptFile)));
                }
                catch (Exception e)
                {
                    MessageBox.Show("Specified file could not be linked to the temp project:\n" + e.Message);
                }
            }
            else if (args[0].Trim().ToLower() == "/r")
            {
                string projFile = args[1];
                try
                {
                    VS100IDE.RefreshProject(projFile);
                }
                catch (Exception e)
                {
                    MessageBox.Show("Specified file could not be linked to the temp project:\n" + e.Message);
                }
            }
            else if (args[0].Trim().ToLower() == "/print")
            {
                try
                {
                    // Note "/print" is to be only invoked from VSX, which  can only be hosted by full VS. Thus "/print" and "/e" cannot come together.
                    scriptFile = args[1];

                    ScriptParser parser = new ScriptParser(scriptFile, Script.SearchDirs, false);

                    foreach (string dir in parser.SearchDirs)
                        AddSearchDir(dir);

                    Console.WriteLine("Src:{0}", scriptFile);

                    foreach (string file in parser.SaveImportedScripts())
                        Console.WriteLine("Src:{0}", file);

                    string[] defaultAsms = (CSScript.GlobalSettings.DefaultRefAssemblies ?? "")
                                            .Replace(" ", "")
                                            .Split(";,".ToCharArray());

                    List<string> referencedAssemblies = new List<string>();

                    List<string> referencedNamespaces = new List<string>();
                    referencedNamespaces.AddRange(parser.ReferencedNamespaces);
                    referencedNamespaces.AddRange(defaultAsms);

                    foreach (string name in referencedNamespaces)
                        if (!parser.IgnoreNamespaces.Contains(name))
                            referencedAssemblies.AddRange(AssemblyResolver.FindAssembly(name, SearchDirs));

                    foreach (string asm in parser.ReferencedAssemblies) //some assemblies were referenced from code
                        referencedAssemblies.AddRange(AssemblyResolver.FindAssembly(asm, SearchDirs));

                    foreach (string file in referencedAssemblies.Distinct())
                        Console.WriteLine("Asm:{0}", file);
                }
                catch (Exception e)
                {
                    MessageBox.Show("Specified file could not be linked to the temp project:\n" + e.Message);
                }
            }
            else
            {
                try
                {
                    bool doNotOpenIDE = false;

                    IDEEditions edition = IDEEditions.normal;
                    scriptFile = args[0];

                    if (args[0].Trim().ToLower() == "/e")
                    {
                        edition = IDEEditions.express;
                        scriptFile = args[1];
                    }

                    // Note "/noide" is to be only invoked from VSX, which  can only be hosted by full VS. Thus "/noide" and "/e" cannot come together.
                    if (args[0].Trim().ToLower() == "/noide")
                    {
                        doNotOpenIDE = true;
                        scriptFile = args[1];
                    }

                    scriptFile = ResolveScriptFile(scriptFile);
                    RunPreScripts(scriptFile);
                    string tempDir = Path.Combine(GetTempCSSDir(), Environment.TickCount.ToString());
                    string solutionFile = VS100IDE.CreateProject(scriptFile, tempDir);
                    string projFile = Path.ChangeExtension(solutionFile, ".csproj");

                    //"lock" the directory to indicate that it is in use
                    File.WriteAllText(Path.Combine(tempDir, "host.pid"), Process.GetCurrentProcess().Id.ToString());

                    //open project
                    Environment.CurrentDirectory = Path.GetDirectoryName(scriptFile);

                    Process myProcess = new Process();
                    myProcess.StartInfo.FileName = VS100IDE.GetIDEFile(edition);

                    if (myProcess.StartInfo.FileName == "<not defined>")
                    {
                        if (edition == IDEEditions.express)
                            myProcess.StartInfo.FileName = VS100IDE.GetIDEFile(IDEEditions.normal);
                        else
                            myProcess.StartInfo.FileName = VS100IDE.GetIDEFile(IDEEditions.express);
                    }

                    AddToRecentScripts(scriptFile);

                    if (!doNotOpenIDE)
                    {
                        myProcess.StartInfo.Arguments = "\"" + solutionFile + "\" " + " /command Edit.OpenFile " + "\"" + scriptFile + "\"";
                        //MessageBox.Show("About to start the VS2010");
                        myProcess.Start();
                        myProcess.WaitForExit();
                    }
                    else
                    {
                        Console.WriteLine("Solution File: " + solutionFile);
                    }

                    if (doNotOpenIDE)
                    {
                        //calling party is responsible for cleanup
                    }
                    else
                    {
                        //do clean up
                        foreach (string file in VS100IDE.GetImportedScripts(projFile))
                        {
                            DeleteSatelliteFiles(file);
                            if (Path.GetFileName(file).StartsWith("i_")) //imported modified files have name "i_file_XXXXXX.cs>"
                            {
                                DeleteSatelliteFiles(file);
                                File.SetAttributes(file, FileAttributes.Normal);
                                File.Delete(file);
                            }
                        }

                        try
                        {
                            Directory.Delete(tempDir, true);
                        }
                        catch { }

                        RunPostScripts(scriptFile);
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show("Specified file could not be linked to the temp project:\n" + e);
                }
            }
        }
Пример #3
0
        void ProcessCompilingResult(CompilerResults results, CompilerParameters compilerParams, ScriptParser parser, string scriptFileName, string assemblyFileName, string[] additionalDependencies)
        {
            LastCompileResult = results;

            if (results.Errors.HasErrors)
            {
                CompilerException ex = CompilerException.Create(results.Errors, options.hideCompilerWarnings);
                if (options.syntaxCheck)
                    Console.WriteLine("Compile: {0} error(s)\n{1}", ex.ErrorCount, ex.Message);
                else
                    throw ex;
            }
            else
            {
                if (options.syntaxCheck)
                    Console.WriteLine("Compile: OK");

                if (options.verbose)
                {
                    Console.WriteLine("  Compiler Output: ", options);
                    foreach (CompilerError err in results.Errors)
                        Console.WriteLine("  {0}({1},{2}):{3} {4} {5}", err.FileName, err.Line, err.Column, (err.IsWarning ? "warning" : "error"), err.ErrorNumber, err.ErrorText);
                    Console.WriteLine("> ----------------", options);
                }

                if (!options.DBG) //.pdb and imported files might be needed for the debugger
                {
                    parser.DeleteImportedFiles();
                    string pdbFile = Path.Combine(Path.GetDirectoryName(assemblyFileName), Path.GetFileNameWithoutExtension(assemblyFileName) + ".pdb");
                    Utils.FileDelete(pdbFile);
                }

                if (options.useCompiled)
                {
                    if (options.useSmartCaching)
                    {
                        MetaDataItems depInfo = new MetaDataItems();

                        string[] searchDirs = Utils.RemovePathDuplicates(options.searchDirs);

                        //save imported scripts info
                        depInfo.AddItems(parser.ImportedFiles, false, searchDirs);

                        //additionalDependencies (precompilers) are warranted to be as absolute path so no need to pass searchDirs or isAssembly
                        depInfo.AddItems(additionalDependencies, false, new string[0]);

                        //save referenced local assemblies info
                        string[] newProbingDirs = depInfo.AddItems(compilerParams.ReferencedAssemblies, true, searchDirs);
                        foreach (string dir in newProbingDirs)
                            options.AddSearchDir(dir); //needed to be added at Compilation for further resolving during the Invoking stage

                        depInfo.StampFile(assemblyFileName);
                    }

                    FileInfo scriptFile = new FileInfo(scriptFileName);
                    FileInfo asmFile = new FileInfo(assemblyFileName);

                    if (scriptFile != null && asmFile != null)
                    {
                        asmFile.LastWriteTimeUtc = scriptFile.LastWriteTimeUtc;
                    }
                }
            }
        }
		static public void Main(string[] args)
		{
			if (args.Length == 0 || (args.Length == 1 && (args[0] == "?" || args[0] == "/?" || args[0] == "-?" || args[0].ToLower() == "help")))
			{
				Console.WriteLine(usage);
			}
			else if (args[0].Trim().ToLower() == "/i")
			{
				SharpDevelopIDE.InstallShellExtension();
			}
			else if (args[0].Trim().ToLower() == "/u")
			{
				SharpDevelopIDE.UninstallShellExtension();
			}
			else
			{
				try
				{
					FileInfo info = new FileInfo(args[0]);
					scriptFile = info.FullName;
					string srcProjDir = @"Lib\Debug\#D1.1"; //relative to CSSCRIPT_DIR
					string scHomeDir = SharpDevelopIDE.GetEnvironmentVariable("CSSCRIPT_DIR");
					string tempDir = Path.Combine(Path.Combine(Path.GetTempPath(), "CSSCRIPT"), Environment.TickCount.ToString());

					string projFile = Path.Combine(tempDir, "DebugScript.prjx");
					string solutionFile = Path.Combine(tempDir, "DebugScript.cmbx");


					//copy project template
					Directory.CreateDirectory(tempDir);

					foreach (string file in Directory.GetFiles(Path.Combine(scHomeDir, srcProjDir)))
						File.Copy(file, Path.Combine(tempDir, Path.GetFileName(file)), true);

					//update project template with script specific data
					SharpDevelopIDE ide = new SharpDevelopIDE();
					ScriptParser parser = new ScriptParser(scriptFile, SearchDirs);
					AssemblyResolver asmResolver = new AssemblyResolver();

					ide.InsertFile(scriptFile, projFile);

					string[] importerdScripts = parser.SaveImportedScripts();
					foreach (string file in importerdScripts)
						ide.InsertFile(file, projFile);
					
					System.Diagnostics.Debug.Assert(false);
					foreach (string name in parser.ReferencedNamespaces)
					{
                        bool ignore = false;
                        foreach (string ignoreName in parser.IgnoreNamespaces)
                            if (ignore = (name == ignoreName))
                                break;

                        if (ignore)
                            continue;

						string[] asmFiles = AssemblyResolver.FindAssembly(name, SearchDirs);
						
						foreach (string file in asmFiles)
						{
							ide.InsertReference(file, projFile);
						}
					}

					foreach (string asmName in parser.ReferencedAssemblies) //some assemblies were referenced from code
					{
						string[] asmFiles = AssemblyResolver.FindAssembly(asmName, SearchDirs);
						foreach (string file in asmFiles)
							ide.InsertReference(file, projFile);
					}

					//open project
					Environment.CurrentDirectory = Path.GetDirectoryName(scriptFile);

					Process myProcess = new Process();
					myProcess.StartInfo.FileName = SharpDevelopIDE.GetIDEFile();
					myProcess.StartInfo.Arguments = "\"" + solutionFile + "\" ";
					myProcess.Start();
					myProcess.WaitForExit();

					//do clean up
					Directory.Delete(tempDir, true);
					foreach (string file in importerdScripts)
					{
						if (Path.GetFileName(file).StartsWith("i_")) //imported modified files have name "i_file_XXXXXX.cs>"
						{
							File.SetAttributes(file, FileAttributes.Normal);
							File.Delete(file);
						}
					}
				}
				catch (Exception e)
				{
					MessageBox.Show("Specified file could not be linked to the temp project:\n" + e.Message);
				}
			}
		}
Пример #5
0
        /// <summary>
        /// Compiles C# script file.
        /// </summary>
        string Compile(string scriptFileName)
        {
            //System.Diagnostics.Debug.Assert(false);
            bool generateExe = options.buildExecutable;
            string scriptDir = Path.GetDirectoryName(scriptFileName);
            string assemblyFileName = "";

            //options may be uninitialized in case we are compiling from CSScriptLibrary
            if (options.searchDirs.Length == 0)
                options.searchDirs = new string[] { scriptDir };

            //parse source file in order to find all referenced assemblies
            //ASSUMPTION: assembly name is the same as namespace + ".dll"
            //if script doesn't follow this assumption user will need to
            //specify assemblies explicitly
            ScriptParser parser = new ScriptParser(scriptFileName, options.searchDirs);
            options.searchDirs = Utils.RemoveDuplicates(
                                 Utils.Concat(
                                        parser.SearchDirs, //parser.searchDirs may be updated as result of script parsing
                                        Utils.GetAssemblyDirectoryName(Assembly.GetExecutingAssembly())));

            string[] filesToInject = new string[0];

            ICodeCompiler compiler = LoadCompiler(scriptFileName, ref filesToInject);

            CompilerParameters compilerParams = new CompilerParameters();

            foreach (string file in parser.Precompilers)
                if (options.preCompilers == "")
                    options.preCompilers = FileParser.ResolveFile(file, options.searchDirs);
                else
                    options.preCompilers += "," + FileParser.ResolveFile(file, options.searchDirs);

            if (options.compilerOptions != string.Empty)
                Utils.AddCompilerOptions(compilerParams, options.compilerOptions);

            foreach (string option in parser.CompilerOptions)
                Utils.AddCompilerOptions(compilerParams, option);

            if (options.DBG)
                Utils.AddCompilerOptions(compilerParams, "/d:DEBUG /d:TRACE");

            compilerParams.IncludeDebugInformation = options.DBG;
            compilerParams.GenerateExecutable = generateExe;
            compilerParams.GenerateInMemory = false;
            compilerParams.WarningLevel = (options.hideCompilerWarnings ? -1 : 4);

            string[] filesToCompile = Utils.RemoveDuplicates(parser.FilesToCompile);
            PrecompilationContext context = CSSUtils.Precompile(scriptFileName, filesToCompile, options);

            if (context.NewIncludes.Count > 0)
            {
                for (int i = 0; i < context.NewIncludes.Count; i++)
                {
                    context.NewIncludes[i] = FileParser.ResolveFile(context.NewIncludes[i], options.searchDirs);
                }
                filesToCompile = Utils.Concat(filesToCompile, context.NewIncludes.ToArray());
                context.NewDependencies.AddRange(context.NewIncludes);
            }

            string[] additionalDependencies = context.NewDependencies.ToArray();

            AddReferencedAssemblies(compilerParams, scriptFileName, parser);

            //add resources referenced from code
            foreach (string resFile in parser.ReferencedResources)
            {
                string file = null;
                foreach (string dir in options.searchDirs)
                {
                    file = Path.IsPathRooted(resFile) ? Path.GetFullPath(resFile) : Path.Combine(dir, resFile);
                    if (File.Exists(file))
                        break;
                }

                if (file == null)
                    file = resFile;

                Utils.AddCompilerOptions(compilerParams, "\"/res:" + file + "\""); //e.g. /res:C:\\Scripting.Form1.resources";
            }

            if (options.forceOutputAssembly != "")
            {
                assemblyFileName = options.forceOutputAssembly;
            }
            else
            {
                if (generateExe)
                    assemblyFileName = Path.Combine(scriptDir, Path.GetFileNameWithoutExtension(scriptFileName) + ".exe");
                else if (options.useCompiled || options.DLLExtension)
                {
                    if (options.DLLExtension)
                        assemblyFileName = Path.Combine(scriptDir, Path.GetFileNameWithoutExtension(scriptFileName) + ".dll");
                    else if (options.hideTemp != Settings.HideOptions.DoNotHide)
                        assemblyFileName = Path.Combine(CSExecutor.ScriptCacheDir, Path.GetFileName(scriptFileName) + ".compiled");
                    else
                        assemblyFileName = scriptFileName + ".compiled";
                }
                else
                {
                    string tempFile = GetScriptTempFile();
                    assemblyFileName = Path.ChangeExtension(tempFile, ".dll");
                }
            }

            if (generateExe && options.buildWinExecutable)
                Utils.AddCompilerOptions(compilerParams, "/target:winexe");

            if (Path.GetExtension(assemblyFileName).ToLower() == ".pdb")
            {
                throw new ApplicationException("The specified assembly file name cannot have the reserved extension '.pdb'");
            }

            Utils.FileDelete(assemblyFileName, true);

            string dbgSymbols = Path.ChangeExtension(assemblyFileName, ".pdb");
            if (options.DBG && File.Exists(dbgSymbols))
                Utils.FileDelete(dbgSymbols);

            compilerParams.OutputAssembly = assemblyFileName;

            string outDir = Path.GetDirectoryName(Path.GetFullPath(compilerParams.OutputAssembly));
            if (!Directory.Exists(outDir))
                Directory.CreateDirectory(outDir);

            //compilerParams.ReferencedAssemblies.Add(this.GetType().Assembly.Location);

            CompilerResults results;
            if (generateExe)
            {
                results = CompileAssembly(compiler, compilerParams, filesToCompile);
            }
            else
            {
                if (filesToInject.Length != 0)
                {
                    filesToCompile = Utils.Concat(filesToCompile, filesToInject);
                }

                CSSUtils.VerbosePrint("  Output file: \n       " + assemblyFileName, options);
                CSSUtils.VerbosePrint("", options);

                CSSUtils.VerbosePrint("  Files to compile: ", options);
                int i = 0;
                foreach (string file in filesToCompile)
                    CSSUtils.VerbosePrint("   " + i++ + " - " + file, options);
                CSSUtils.VerbosePrint("", options);

                CSSUtils.VerbosePrint("  References: ", options);
                i = 0;
                foreach (string file in compilerParams.ReferencedAssemblies)
                    CSSUtils.VerbosePrint("   " + i++ + " - " + file, options);
                CSSUtils.VerbosePrint("> ----------------", options);

                string originalExtension = Path.GetExtension(compilerParams.OutputAssembly);
                if (originalExtension != ".dll")
                {
                    //Despite the usage of .dll file name is not required for MS C# compiler we need to do this because
                    //some compilers (Mono, VB) accept only dll or exe file extensions.
                    compilerParams.OutputAssembly = Path.ChangeExtension(compilerParams.OutputAssembly, ".dll");

                    Utils.FileDelete(compilerParams.OutputAssembly, true);

                    results = CompileAssembly(compiler, compilerParams, filesToCompile);

                    if (File.Exists(compilerParams.OutputAssembly))
                    {
                        int attempts = 0;
                        while (true)
                        {
                            //There were reports of MS C# compiler (csc.exe) not releasing OutputAssembly file
                            //after compilation finished. Thus wait a little...
                            //BTW. on Mono 1.2.4 it happens all the time
                            try
                            {
                                attempts++;

                                File.Move(compilerParams.OutputAssembly, Path.ChangeExtension(compilerParams.OutputAssembly, originalExtension));

                                break;
                            }
                            catch
                            {
                                if (attempts > 2)
                                {
                                    //yep we can get here as Mono 1.2.4 on Windows never ever releases the assembly
                                    File.Copy(compilerParams.OutputAssembly, Path.ChangeExtension(compilerParams.OutputAssembly, originalExtension), true);
                                    break;
                                }
                                else
                                    Thread.Sleep(100);
                            }
                        }
                    }
                }
                else
                {
                    Utils.FileDelete(compilerParams.OutputAssembly, true);
                    results = CompileAssembly(compiler, compilerParams, filesToCompile);
                }
            }

            if (options.syntaxCheck && File.Exists(compilerParams.OutputAssembly))
                Utils.FileDelete(compilerParams.OutputAssembly, false);

            ProcessCompilingResult(results, compilerParams, parser, scriptFileName, assemblyFileName, additionalDependencies);

            if (options.useSurrogateHostingProcess)
            {
                new ScriptLauncherBuilder().BuildSurrogateLauncher(assemblyFileName, options.TargetFramework, compilerParams, options.apartmentState, options.consoleEncoding);
            }
            return assemblyFileName;
        }
Пример #6
0
        internal string[] AggregateReferencedAssemblies(ScriptParser parser)
        {
            UniqueAssemblyLocations requestedRefAsms = new UniqueAssemblyLocations();

#if net1
            ArrayList refAssemblies = new ArrayList();
#else
            List<string> refAssemblies = new List<string>();
#endif
            if (options.shareHostRefAssemblies)
                foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
                {
                    try
                    {
                        if (CSSUtils.IsDynamic(asm))
                            continue;

                        if (!File.Exists(asm.Location) || asm.Location.Contains("mscorlib"))
                            continue;

                        requestedRefAsms.AddAssembly(asm.Location);
                    }
                    catch
                    {
                        //Under ASP.NET some assemblies do not have location (e.g. dynamically built/emitted assemblies)
                        //in such case NotSupportedException will be raised

                        //In fact ignore all exceptions as we should continue if for whatever reason assembly the location cannot be obtained
                    }
                }

            //add assemblies referenced from command line
            string[] cmdLineAsms = options.refAssemblies;
            if (!options.useSurrogateHostingProcess)
            {
                string[] defaultAsms = options.defaultRefAssemblies.Replace(" ", "").Split(";,".ToCharArray());

                foreach (string asmName in Utils.Concat(defaultAsms, cmdLineAsms))
                {
                    if (asmName == "")
                        continue;

                    string[] files = AssemblyResolver.FindAssembly(asmName, options.searchDirs);
                    if (files.Length > 0)
                    {
                        foreach (string asm in files)
                            requestedRefAsms.AddAssembly(NormalizeGacAssemblyPath(asm));
                    }
                    else
                    {
                        requestedRefAsms.AddAssembly(asmName);
                    }
                }
            }

            AssemblyResolver.ignoreFileName = Path.GetFileNameWithoutExtension(parser.ScriptPath) + ".dll";

            //add assemblies referenced from code
            foreach (string asmName in parser.ResolvePackages())
                requestedRefAsms.AddAssembly(asmName);

            //add assemblies referenced from code
            foreach (string asmName in parser.ReferencedAssemblies)
            {
                string asm = asmName.Replace("\"", "");

                if (Path.IsPathRooted(asm)) //absolute path
                {
                    //not-searchable assemblies
                    if (File.Exists(asm))
                        requestedRefAsms.AddAssembly(NormalizeGacAssemblyPath(asm));
                }
                else
                {
                    string[] files = AssemblyResolver.FindAssembly(asm, options.searchDirs);
                    if (files.Length > 0)
                    {
                        foreach (string asmFile in files)
                            requestedRefAsms.AddAssembly(NormalizeGacAssemblyPath(asmFile));
                    }
                    else
                    {
                        requestedRefAsms.AddAssembly(asm);
                    }
                }
            }

            bool disableNamespaceResolving = false;
            if (parser.IgnoreNamespaces.Length == 1 && parser.IgnoreNamespaces[0] == "*")
                disableNamespaceResolving = true;

            if (!disableNamespaceResolving)
            {
                //add local and global assemblies (if found) that have the same assembly name as a namespace
                foreach (string nmSpace in parser.ReferencedNamespaces)
                {
                    bool ignore = false; //user may nominate namespaces to be excluded fro namespace-to-asm resolving
                    foreach (string ignoreNamespace in parser.IgnoreNamespaces)
                        if (ignoreNamespace == nmSpace)
                            ignore = true;

                    if (!ignore)
                    {
                        bool alreadyFound = requestedRefAsms.ContainsAssembly(nmSpace);
                        if (!alreadyFound)
                            foreach (string asm in AssemblyResolver.FindAssembly(nmSpace, options.searchDirs))
                                requestedRefAsms.AddAssembly(NormalizeGacAssemblyPath(asm));
                    }
                }
            }

            return (string[]) requestedRefAsms;
        }
Пример #7
0
 void AddReferencedAssemblies(CompilerParameters compilerParams, string scriptFileName, ScriptParser parser)
 {
     //scriptFileName is obsolete as it is now can be obtained from parser (ScriptParser.ScriptPath)
     string[] asms = AggregateReferencedAssemblies(parser);
     compilerParams.ReferencedAssemblies.AddRange(asms);
 }
Пример #8
0
		/// <summary>
		/// Compiles C# script file.
		/// </summary>
		private string Compile(string scriptFileName) 
		{
			bool generateExe = options.buildExecutable;
			string scriptDir = Path.GetDirectoryName(scriptFileName);
			string assemblyFileName = "";
			string tempDir = Path.GetDirectoryName(GetScriptTempFile());
			
			//options may be uninitialized in case we are compileng from CSScriptLibrary
			if (options.searchDirs.Length == 0)
				options.searchDirs = new string[]{scriptDir};

			//parse source file in order to find all referenced assemblies
			//ASSUMPTION: assembly name is the same as namespace + ".dll"
			//if script doesn't follow this assumption user will need to 
			//specify assemblies explicitly  

			ScriptParser parser = new ScriptParser(scriptFileName, options.searchDirs);

			ICodeCompiler compiler;
			if (options.altCompiler == "")
			{
				compiler = (new CSharpCodeProvider()).CreateCompiler();
			}
			else
			{
				try
				{
					Assembly asm = Assembly.LoadFrom(Path.IsPathRooted(options.altCompiler) ? options.altCompiler : Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), options.altCompiler));
					Type[] types = asm.GetModules()[0].FindTypes(Module.FilterTypeName, "CSSCodeProvider");
					MethodInfo method = types[0].GetMethod("CreateCompiler");
					compiler = (ICodeCompiler)method.Invoke(null, new object[]{scriptFileName});
				}
				catch (Exception ex)
				{
					throw new Exception("Cannot use alternative compiler", ex); 
				}
			}
		
			CompilerParameters compileParams = new CompilerParameters();
		 	
			if (options.DBG)
				compileParams.CompilerOptions = "/d:DEBUG /d:TRACE ";

			if (options.compilerOptions != string.Empty)
				compileParams.CompilerOptions += options.compilerOptions;

			compileParams.IncludeDebugInformation = options.DBG;
			compileParams.GenerateExecutable = generateExe;
			compileParams.GenerateInMemory = !generateExe;
			
			ArrayList refAssemblies = new ArrayList();

			//add assemblies were referenced from command line
			foreach (string asmName in options.refAssemblies)
				compileParams.ReferencedAssemblies.AddRange(AssemblyResolver.FindAssembly(asmName, options.searchDirs));
		
			AssemblyResolver.ignoreFileName = Path.GetFileNameWithoutExtension(scriptFileName) + ".dll";
			
			//add local and global assemblies (if found) that have the same assembly name as a namespace
			foreach (string nmSpace in parser.ReferencedNamespaces) 
				compileParams.ReferencedAssemblies.AddRange(AssemblyResolver.FindAssembly(nmSpace, options.searchDirs));
			
			//add assemblies referenced from code
			foreach (string asmName in parser.ReferencedAssemblies)
				if (asmName.StartsWith("\"") && asmName.EndsWith("\"")) 
					compileParams.ReferencedAssemblies.Add(asmName.Replace("\"", "")); //not-searchable assemblies
				else
					compileParams.ReferencedAssemblies.AddRange(AssemblyResolver.FindAssembly(asmName, options.searchDirs));
			
			//add resources referenced from code
			foreach (string resFile in parser.ReferencedResources)
			{
				string file = null;
				foreach (string dir in options.searchDirs)
				{
					file = Path.IsPathRooted(resFile) ? Path.GetFullPath(resFile) : Path.Combine(dir, resFile);
					if (File.Exists(file))
						break;
				}

				if (file == null)
					file = resFile;
				
				compileParams.CompilerOptions += "\"/res:" + file + "\" "; //eg. /res:C:\\Scripting.Form1.resources";
			}
				

			if (options.forceOutputAssembly != "")
			{
				assemblyFileName = options.forceOutputAssembly;
			}
			else
			{
				if (generateExe)
					assemblyFileName = Path.Combine(scriptDir, Path.GetFileNameWithoutExtension(scriptFileName) + ".exe");
				else if (options.useCompiled || options.DLLExtension)
				{
					if (options.DLLExtension)
						assemblyFileName = Path.Combine(scriptDir, Path.GetFileNameWithoutExtension(scriptFileName) + ".dll");
					else if (options.hideTemp != Settings.HideOptions.DoNotHide)
						assemblyFileName = Path.Combine(CSExecutor.ScriptCacheDir,  Path.GetFileName(scriptFileName) + "c");
					else
						assemblyFileName = scriptFileName + "c";
				}
				else
				{
					string tempFile = Path.GetTempFileName();
					if (File.Exists(tempFile))
						File.Delete(tempFile);
					assemblyFileName = Path.Combine(tempDir, Path.GetFileNameWithoutExtension(tempFile)+".dll");
				}
			}
			
			if (generateExe && options.buildWinExecutable)
				compileParams.CompilerOptions += "/target:winexe ";

			if (File.Exists(assemblyFileName))
				File.Delete(assemblyFileName);

			compileParams.OutputAssembly = assemblyFileName;

			CompilerResults results;
			if (generateExe)
			{
				results = compiler.CompileAssemblyFromFileBatch(compileParams, parser.FilesToCompile);
			}
			else
			{
				
				string originalExtension = Path.GetExtension(compileParams.OutputAssembly);
				if (originalExtension != ".dll")
				{
					//Despite the usage of .dll file name is not required for MS C# compiler we need to do this because 
					//some compilers (Mono, VB) accept only dll or exe file extensions.
					compileParams.OutputAssembly = Path.ChangeExtension(compileParams.OutputAssembly, ".dll");

					if (File.Exists(compileParams.OutputAssembly))
						File.Delete(compileParams.OutputAssembly);
					results = compiler.CompileAssemblyFromFileBatch(compileParams, parser.FilesToCompile);

					if (File.Exists(compileParams.OutputAssembly))
					{
						while (true)
						{
							//There were reports of MS C# compiler (csc.exe) notr releasing OutputAssembly file
							//after compilation finished. Thus wait a little...
							try
							{
								using (File.Open(compileParams.OutputAssembly, FileMode.Open, FileAccess.Read, FileShare.None))
									break;
							}
							catch
							{
								Thread.Sleep(100);
							}
						}
						File.Move(compileParams.OutputAssembly, Path.ChangeExtension(compileParams.OutputAssembly, originalExtension));
					}
				}
				else
				{
					if (File.Exists(compileParams.OutputAssembly))
						File.Delete(compileParams.OutputAssembly);
					results = compiler.CompileAssemblyFromFileBatch(compileParams, parser.FilesToCompile);
				}
			}

			if (results.Errors.Count != 0) 
			{
				StringBuilder compileErr = new StringBuilder();
				foreach (CompilerError err in results.Errors) 
				{
					if (err.IsWarning && options.hideCompilerWarnings)
						continue;
					
					compileErr.Append(err.ToString());
					compileErr.Append(Environment.NewLine);
					compileErr.Append(Environment.NewLine);
				}
				throw new Exception(compileErr.ToString());				
			}
			else
			{
				if (!options.DBG) //.pdb and imported files might be needed for the debugger
				{
					parser.DeleteImportedFiles();
					string pdbFile = Path.Combine(Path.GetDirectoryName(assemblyFileName), Path.GetFileNameWithoutExtension(assemblyFileName)+".pdb");	
					if (File.Exists(pdbFile))
						File.Delete(pdbFile);
				}

				if (options.useCompiled)
				{
					if (options.useSmartCaching)
					{
						MetaDataItems depInfo = new MetaDataItems();

						//save referenced local assemblies info
						foreach(string assembly in compileParams.ReferencedAssemblies)
						{
							foreach(string dir in options.searchDirs)
								if (string.Compare(dir, Path.GetDirectoryName(assembly), true) == 0)
								{
									FileInfo assemblyInfo = new FileInfo(assembly);
									depInfo.AddItem(Path.GetFileName(assembly), assemblyInfo.LastWriteTimeUtc, true);
									break;
								}
						}
						//save imported scripts info
						foreach(string script in parser.ImportedFiles)
						{
							FileInfo scriptInfo = new FileInfo(script);
							
							bool local = false;
							foreach (string dir in options.searchDirs)
								if ((local = (string.Compare(dir, Path.GetDirectoryName(scriptInfo.FullName), true) == 0)))									break;
							
							if (local)
								depInfo.AddItem(Path.GetFileName(script), scriptInfo.LastWriteTimeUtc, false);
							else 
								depInfo.AddItem(script, scriptInfo.LastWriteTimeUtc, false);

						}

						depInfo.StampFile(assemblyFileName);		
					}

					FileInfo scriptFile = new FileInfo(scriptFileName);
					FileInfo asmFile = new FileInfo(assemblyFileName);
					
					if (scriptFile!= null && asmFile != null)
					{
						//Console.WriteLine("Update LastWriteTime"+assemblyFileName); //temp os
						asmFile.LastWriteTime = scriptFile.LastWriteTime; 
						asmFile.LastWriteTimeUtc = scriptFile.LastWriteTimeUtc;
					}
				}
			}
			return assemblyFileName;
		}
Пример #9
0
        private void ProcessCompilingResult(CompilerResults results, CompilerParameters compilerParams, ScriptParser parser, string scriptFileName, string assemblyFileName, string[] additionalDependencies)
        {
            LastCompileResult = results;

            if (results.Errors.Count != 0)
            {
                throw CompilerException.Create(results.Errors, options.hideCompilerWarnings);
            }
            else
            {
                if (!options.DBG) //.pdb and imported files might be needed for the debugger
                {
                    parser.DeleteImportedFiles();
                    string pdbFile = Path.Combine(Path.GetDirectoryName(assemblyFileName), Path.GetFileNameWithoutExtension(assemblyFileName) + ".pdb");
                    if (File.Exists(pdbFile))
                        File.Delete(pdbFile);
                }

                if (options.useCompiled)
                {
                    if (options.useSmartCaching)
                    {
                        MetaDataItems depInfo = new MetaDataItems();

                        string[] searchDirs = Utils.RemovePathDuplicates(options.searchDirs);

                        //save imported scripts info
                        depInfo.AddItems(parser.ImportedFiles, false, searchDirs);

                        //additionalDependencies (precompilers) are warranted to be as absolute path so no need to pass searchDirs or isAssembly
                        depInfo.AddItems(additionalDependencies, false, new string[0]);

                        //save referenced local assemblies info
                        string[] newProbingDirs = depInfo.AddItems(compilerParams.ReferencedAssemblies, true, searchDirs);
                        foreach (string dir in newProbingDirs)
                            options.AddSearchDir(dir); //needed to be added at Compilation for further resolving during the Invoking stage

                        depInfo.StampFile(assemblyFileName);
                    }

                    FileInfo scriptFile = new FileInfo(scriptFileName);
                    FileInfo asmFile = new FileInfo(assemblyFileName);

                    if (scriptFile != null && asmFile != null)
                    {
                        asmFile.LastWriteTimeUtc = scriptFile.LastWriteTimeUtc;
                    }
                }
            }
        }