/// <summary>
        /// Analyses the script code and returns set of locations for the assemblies referenced from the code with CS-Script directives (//css_ref).
        /// </summary>
        /// <param name="code">The script code.</param>
        /// <param name="searchDirs">The assembly search/probing directories.</param>
        /// <returns>Array of the referenced assemblies</returns>
        public string[] GetReferencedAssemblies(string code, params string[] searchDirs)
        {
            var retval = new List <string>();

            var parser = new csscript.CSharpParser(code);

            var globalProbingDirs = Environment.ExpandEnvironmentVariables(CSScript.GlobalSettings.SearchDirs).Split(",;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            var dirs = searchDirs.Concat(new string[] { Path.GetDirectoryName(Assembly.GetCallingAssembly().Location) })
                       .Concat(parser.ExtraSearchDirs)
                       .Concat(globalProbingDirs)
                       .ToArray();

            dirs = CSScript.RemovePathDuplicates(dirs);

            var asms = new List <string>(parser.RefAssemblies);

            if (!parser.IgnoreNamespaces.Any(x => x == "*"))
            {
                asms.AddRange(parser.RefNamespaces.Except(parser.IgnoreNamespaces));
            }

            foreach (var asm in asms)
            {
                foreach (string asmFile in AssemblyResolver.FindAssembly(asm, dirs))
                {
                    retval.Add(asmFile);
                }
            }

            return(retval.Distinct().ToArray());
        }
Exemple #2
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;
            }
Exemple #3
0
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		public void Execute(string[] args, PrintDelegate printDelg, string primaryScript)
		{
			try
			{
				print = printDelg != null ? printDelg : new PrintDelegate(VoidPrint);

				if (args.Length > 0) 
				{
					#region Parse command-line arguments...
					
					//Here we need to separate application arguments from script ones.
					//Script engine arguments are always followed by script arguments
					//[appArgs][scriptFile][scriptArgs][//x]
					ArrayList appArgs = new ArrayList();

					int firstScriptArg = ParseAppArgs(args); 
					if (args.Length <= firstScriptArg)
					{
						Environment.ExitCode = 1;
						return; //no script, no script arguments
					}

					//read persistent settings from configuration file
					Settings settings = null;
				
					if (options.noConfig)
					{
						if (options.altConfig != "")
							settings = Settings.Load(Path.GetFullPath(options.altConfig));
					}
					else
						settings = Settings.Load(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "css_config.xml"));

					if (settings != null)
					{
						options.hideTemp = settings.HideAutoGeneratedFiles;
						options.altCompiler = settings.ExpandUseAlternativeCompiler();
						options.apartmentState = settings.DefaultApartmentState;
						options.reportDetailedErrorInfo = settings.ReportDetailedErrorInfo;
						options.cleanupShellCommand = settings.ExpandCleanupShellCommand();
						options.doCleanupAfterNumberOfRuns = settings.DoCleanupAfterNumberOfRuns;
						options.hideCompilerWarnings = settings.HideCompilerWarnings;

						//process default command-line arguments
						string[] defaultCmdArgs = settings.DefaultArguments.Split(" ".ToCharArray());
						int firstDefaultScriptArg = ParseAppArgs(defaultCmdArgs);
						if (firstDefaultScriptArg != defaultCmdArgs.Length)
						{
							options.scriptFileName = defaultCmdArgs[firstDefaultScriptArg];
							for (int i = firstDefaultScriptArg+1; i < defaultCmdArgs.Length; i++)
								if (defaultCmdArgs[i].Trim().Length != 0) 
									appArgs.Add(defaultCmdArgs[i]);
						}	
					}

					//process original command-line arguments
					if (options.scriptFileName == "")
					{
						options.scriptFileName = args[firstScriptArg];	
						firstScriptArg++;
					}

					for (int i = firstScriptArg; i < args.Length; i++)
					{
						if (args[i].Trim().Length != 0)
						{
							if (i == args.Length - 1 && string.Compare(args[args.Length - 1], "//x", true, CultureInfo.InvariantCulture) == 0)
							{
								options.startDebugger = true;
								options.DBG = true;
							}
							else
								appArgs.Add(args[i]);
						}
					}
					scriptArgs = (string[])appArgs.ToArray(typeof(string));

					//searchDirs[0] is the script file directory. Set it only after 
					//the script file resolved because it can be:
					//	CurrentDir 
					//	dir defined by the absolute/ralative script file path 
					//	%CSSCRIPT_DIR%
					//	ExtraLibDirectory
					//  CacheDir
					options.searchDirs = new string[]{	"",
														Environment.ExpandEnvironmentVariables(@"%CSSCRIPT_DIR%\lib"),
														settings == null ? "" : settings.ExpandExtraLibDirectory(),
														""};
					
					options.scriptFileName = FileParser.ResolveFile(options.scriptFileName, options.searchDirs);
					

					if (primaryScript != null)
						options.scriptFileNamePrimary = primaryScript;
					else
						options.scriptFileNamePrimary = options.scriptFileName;

					if (CSExecutor.ScriptCacheDir == "")
						CSExecutor.SetScriptCacheDir(options.scriptFileName); 

					options.searchDirs[0] = Path.GetDirectoryName(Path.GetFullPath(options.scriptFileName)); 
					if (settings != null && settings.HideAutoGeneratedFiles != Settings.HideOptions.DoNotHide)
						options.searchDirs[3] = CSExecutor.ScriptCacheDir; 
					
					CSharpParser.CmdScriptInfo[] cmdScripts = new CSharpParser.CmdScriptInfo[0];
					//analyse ThreadingModel to use it whith execution thread 
					if (File.Exists(options.scriptFileName))
					{
						//do quick parsing for pre/post scripts, ThreadingModel and embedded script arguments
						CSharpParser parser = new CSharpParser(options.scriptFileName, true); 
						
						if (parser.ThreadingModel != ApartmentState.Unknown)
							options.apartmentState = parser.ThreadingModel;
							
						cmdScripts = parser.CmdScripts;
						
						if (primaryScript == null)//this is a primary script
						{
							int firstEmbeddedScriptArg = ParseAppArgs(parser.Args);
							if (firstEmbeddedScriptArg != -1)
							{
								for (int i = firstEmbeddedScriptArg; i < parser.Args.Length; i++ )
									appArgs.Add(parser.Args[i]);
							}
							scriptArgs = (string[])appArgs.ToArray(typeof(string));
						}
					}
					#endregion

					ExecuteOptions originalOptions = (ExecuteOptions)options.Clone(); //preserve master script options
					string originalCurrDir = Environment.CurrentDirectory;

					//run prescripts		
					//Note: during the secondary script execution static options will be modified (this is required for 
					//browsing in CSSEnvironment with reflection). So reset it back with originalOptions after the execution is completed
					foreach (CSharpParser.CmdScriptInfo info in cmdScripts)
						if (info.preScript)
						{
							Environment.CurrentDirectory = originalCurrDir;
							info.args[1] = FileParser.ResolveFile(info.args[1], originalOptions.searchDirs);

							CSExecutor exec = new CSExecutor(info.abortOnError, originalOptions);

							if (originalOptions.DBG)
							{
								ArrayList newArgs = new ArrayList();
								newArgs.AddRange(info.args);
								newArgs.Insert(0, "/dbg");
								info.args = (string[])newArgs.ToArray(typeof(string));
							}
							if (info.abortOnError)
								exec.Execute(info.args, printDelg, originalOptions.scriptFileName);
							else
								exec.Execute(info.args, null, originalOptions.scriptFileName);
						}

					options = originalOptions;
					ExecuteOptions.options = originalOptions; //update static members as well
					Environment.CurrentDirectory = originalCurrDir;

					//Run main script
					//We need to start the execution in a new thread as it is the only way 
					//to set desired ApartmentState under .NET 2.0
					Thread newThread = new Thread(new ThreadStart(this.ExecuteImpl));
					newThread.ApartmentState = options.apartmentState;
					newThread.Start();
					newThread.Join();
					if (lastException != null)
						throw new Exception("Script "+options.scriptFileName+" cannot be executed.", lastException);
					
					//run postscripts		
					foreach (CSharpParser.CmdScriptInfo info in cmdScripts)
						if (!info.preScript)
						{
							Environment.CurrentDirectory = originalCurrDir;
							info.args[1] = FileParser.ResolveFile(info.args[1], originalOptions.searchDirs);

							CSExecutor exec = new CSExecutor(info.abortOnError, originalOptions);

							if (originalOptions.DBG)
							{
								ArrayList newArgs = new ArrayList();
								newArgs.AddRange(info.args);
								newArgs.Insert(0, "/dbg");
								info.args = (string[])newArgs.ToArray(typeof(string));
							}
							if (info.abortOnError)
							{
								exec.Rethrow = true;
								exec.Execute(info.args, printDelg, originalOptions.scriptFileName);
							}
							else
								exec.Execute(info.args, null, originalOptions.scriptFileName);
						}
				}
				else 
				{
					ShowHelp();
				}
			}
			catch (Exception e) 
			{
				if (rethrow)
				{
					throw;
				}
				else
				{
					Environment.ExitCode = 1;
					if (options.reportDetailedErrorInfo)
						print(e.ToString());
					else	
						print(e.Message); //Mono friendly
				}
			}
		}
Exemple #4
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        public void Execute(string[] args, PrintDelegate printDelg, string primaryScript)
        {
            try
            {
                print = printDelg != null ? printDelg : new PrintDelegate(VoidPrint);

                if (args.Length > 0)
                {
                    #region Parse command-line arguments...

                    //Here we need to separate application arguments from script ones.
                    //Script engine arguments are always followed by script arguments
                    //[appArgs][scriptFile][scriptArgs][//x]
#if net1
                    ArrayList appArgs = new ArrayList();
#else
                    List<string> appArgs = new List<string>();
#endif
                    //The following will also update corresponding "options" members from "settings" data
                    Settings settings = GetPersistedSettings(appArgs);

                    int firstScriptArg = CSSUtils.ParseAppArgs(args, this);

                    if (!options.processFile)
                        return; //no further processing is required (e.g. print help)

                    if (args.Length <= firstScriptArg)
                    {
                        Environment.ExitCode = 1;
                        print("No script file was specified.");
                        return; //no script, no script arguments
                    }


                    //process original command-line arguments
                    if (options.scriptFileName == "")
                    {
                        options.scriptFileName = args[firstScriptArg];
                        firstScriptArg++;
                    }

                    for (int i = firstScriptArg; i < args.Length; i++)
                    {
                        if (i == args.Length - 1 && string.Compare(args[args.Length - 1], "//x", true, CultureInfo.InvariantCulture) == 0)
                        {
                            options.startDebugger = true;
                            options.DBG = true;
                        }
                        else
                            appArgs.Add(args[i]);
                    }
#if net1
                    scriptArgs = (string[])appArgs.ToArray(typeof(string));
#else
                    scriptArgs = appArgs.ToArray();
#endif

                    //searchDirs[0] is the script file directory. Set it only after
                    //the script file resolved because it can be:
                    //	dir defined by the absolute/relative script file path
                    //	"%CSSCRIPT_DIR%\lib
                    //	settings.SearchDirs
                    //  CacheDir
#if net1
                    ArrayList dirs = new ArrayList();
#else
                    List<string> dirs = new List<string>();
#endif

                    using (IDisposable currDir = new CurrentDirGuard())
                    {
                        if (options.local)
                            Environment.CurrentDirectory = Path.GetDirectoryName(Path.GetFullPath(options.scriptFileName));

                        foreach (string dir in options.searchDirs) //some directories may be already set from command-line
                            dirs.Add(Path.GetFullPath(dir));

                        if (settings != null)
                            foreach (string dir in Environment.ExpandEnvironmentVariables(settings.SearchDirs).Split(",;".ToCharArray()))
                                if (dir.Trim() != "")
                                    dirs.Add(Path.GetFullPath(dir));
                    }

                    dirs.Add(Utils.GetAssemblyDirectoryName(this.GetType().Assembly));
#if net1
                    options.scriptFileName = FileParser.ResolveFile(options.scriptFileName, (string[])dirs.ToArray(typeof(string)));
#else
                    options.scriptFileName = FileParser.ResolveFile(options.scriptFileName, dirs.ToArray());
#endif
                    if (primaryScript != null)
                        options.scriptFileNamePrimary = primaryScript;
                    else
                        options.scriptFileNamePrimary = options.scriptFileName;

                    if (CSExecutor.ScriptCacheDir == "")
                        CSExecutor.SetScriptCacheDir(options.scriptFileName);

                    dirs.Insert(0, Path.GetDirectoryName(Path.GetFullPath(options.scriptFileName)));

                    if (settings != null && settings.HideAutoGeneratedFiles != Settings.HideOptions.DoNotHide)
                        dirs.Add(CSExecutor.ScriptCacheDir);

#if net1
                    options.searchDirs = (string[])dirs.ToArray(typeof(string));
#else
                    options.searchDirs = dirs.ToArray();
#endif
                    CSharpParser.CmdScriptInfo[] cmdScripts = new CSharpParser.CmdScriptInfo[0];

                    //do quick parsing for pre/post scripts, ThreadingModel and embedded script arguments
                    CSharpParser parser = new CSharpParser(options.scriptFileName, true, null, options.searchDirs);

                    if (parser.Inits.Length != 0)
                        options.initContext = parser.Inits[0];

                    if (parser.HostOptions.Length != 0)
                    {
                        if (Environment.Version.Major >= 4)
                        {
                            foreach (string optionsSet in parser.HostOptions)
                                foreach (string option in optionsSet.Split(' '))
                                    if (option == "/platform:x86")
                                        options.compilerOptions += " " + option;
                                    else if (option.StartsWith("/version:"))
                                        options.TargetFramework = option.Replace("/version:", "");

                            options.useSurrogateHostingProcess = true;
                        }
                    }

                    //analyses ThreadingModel to use it with execution thread
                    if (File.Exists(options.scriptFileName))
                    {
                        if (parser.ThreadingModel != ApartmentState.Unknown)
                            options.apartmentState = parser.ThreadingModel;
#if net1

                        ArrayList preScripts = new ArrayList(parser.CmdScripts);
                        foreach (CSharpParser.ImportInfo info in parser.Imports)
                        {
                            try
                            {
                                string file = FileParser.ResolveFile(info.file, options.searchDirs);
                                if (file.IndexOf(".g.cs") == -1) //non auto-generated file
                                    preScripts.AddRange(new CSharpParser(file, true, options.searchDirs).CmdScripts);
                            }
                            catch { } //some files may not be generated yet
                        }

                        cmdScripts = (CSharpParser.CmdScriptInfo[])preScripts.ToArray(typeof(CSharpParser.CmdScriptInfo));
#else
                        List<string> newSearchDirs = new List<string>(options.searchDirs);

                        using (IDisposable currDir = new CurrentDirGuard())
                        {
                            Environment.CurrentDirectory = Path.GetDirectoryName(Path.GetFullPath(options.scriptFileName));

                            foreach (string dir in parser.ExtraSearchDirs)
                                newSearchDirs.Add(Path.GetFullPath(dir));

                            foreach (string file in parser.RefAssemblies)
                            {
                                string path = file.Replace("\"", "");
                                string dir = Path.GetDirectoryName(path);
                                if (dir != "")
                                    newSearchDirs.Add(Path.GetFullPath(dir));
                            }
                            options.searchDirs = newSearchDirs.ToArray();
                        }

                        List<CSharpParser.CmdScriptInfo> preScripts = new List<CSharpParser.CmdScriptInfo>(parser.CmdScripts);
                        foreach (CSharpParser.ImportInfo info in parser.Imports)
                        {
                            try
                            {
                                string[] files = FileParser.ResolveFiles(info.file, options.searchDirs);
                                foreach (string file in files)
                                    if (file.IndexOf(".g.cs") == -1) //non auto-generated file
                                    {
                                        using (IDisposable currDir = new CurrentDirGuard())
                                        {
                                            CSharpParser impParser = new CSharpParser(file, true, null, options.searchDirs);
                                            Environment.CurrentDirectory = Path.GetDirectoryName(file);

                                            string[] packageAsms = NuGet.Resolve(impParser.NuGets, true, file);
                                            foreach (string asmName in packageAsms)
                                            {
                                                var packageDir = Path.GetDirectoryName(asmName);
                                                newSearchDirs.Add(packageDir);
                                            }

                                            foreach (string dir in impParser.ExtraSearchDirs)
                                                newSearchDirs.Add(Path.GetFullPath(dir));

                                            options.searchDirs = newSearchDirs.ToArray();
                                        }
                                        preScripts.AddRange(new CSharpParser(file, true, null, options.searchDirs).CmdScripts);
                                    }
                            }
                            catch { } //some files may not be generated yet
                        }

                        cmdScripts = preScripts.ToArray();
#endif
                        if (primaryScript == null)//this is a primary script
                        {
                            int firstEmbeddedScriptArg = CSSUtils.ParseAppArgs(parser.Args, this);
                            if (firstEmbeddedScriptArg != -1)
                            {
                                for (int i = firstEmbeddedScriptArg; i < parser.Args.Length; i++)
                                    appArgs.Add(parser.Args[i]);
                            }
#if net1
                            scriptArgs = (string[])appArgs.ToArray(typeof(string));
#else
                            scriptArgs = appArgs.ToArray();
#endif
                        }
                    }

                    #endregion Parse command-line arguments...

                    ExecuteOptions originalOptions = (ExecuteOptions) options.Clone(); //preserve master script options
                    string originalCurrDir = Environment.CurrentDirectory;

                    //run prescripts
                    //Note: during the secondary script execution static options will be modified (this is required for
                    //browsing in CSSEnvironment with reflection). So reset it back with originalOptions after the execution is completed
                    foreach (CSharpParser.CmdScriptInfo info in cmdScripts)
                        if (info.preScript)
                        {
                            Environment.CurrentDirectory = originalCurrDir;
                            info.args[1] = FileParser.ResolveFile(info.args[1], originalOptions.searchDirs);

                            CSExecutor exec = new CSExecutor(info.abortOnError, originalOptions);

                            if (originalOptions.DBG)
                            {
#if net1
                                ArrayList newArgs = new ArrayList();
                                newArgs.AddRange(info.args);
                                newArgs.Insert(0, CSSUtils.Args.DefaultPrefix + "dbg");
                                info.args = (string[])newArgs.ToArray(typeof(string));
#else
                                List<string> newArgs = new List<string>();
                                newArgs.AddRange(info.args);
                                newArgs.Insert(0, CSSUtils.Args.DefaultPrefix + "dbg");
                                info.args = newArgs.ToArray();
#endif
                            }
                            if (originalOptions.verbose)
                            {
#if net1
                                ArrayList newArgs = new ArrayList();
                                newArgs.AddRange(info.args);
                                newArgs.Insert(0, CSSUtils.Args.DefaultPrefix + "verbose");
                                info.args = (string[])newArgs.ToArray(typeof(string));
#else
                                List<string> newArgs = new List<string>();
                                newArgs.AddRange(info.args);
                                newArgs.Insert(0, CSSUtils.Args.DefaultPrefix + "verbose");
                                info.args = newArgs.ToArray();
#endif
                            }
                            if (info.abortOnError)
                                exec.Execute(info.args, printDelg, originalOptions.scriptFileName);
                            else
                                exec.Execute(info.args, null, originalOptions.scriptFileName);
                        }

                    options = originalOptions;
                    ExecuteOptions.options = originalOptions; //update static members as well
                    Environment.CurrentDirectory = originalCurrDir;

                    options.compilationContext = CSSUtils.GenerateCompilationContext(parser, options);

                    //Run main script
                    //We need to start the execution in a new thread as it is the only way
                    //to set desired ApartmentState under .NET 2.0
                    Thread newThread = new Thread(new ThreadStart(this.ExecuteImpl));
#if net1
                    newThread.ApartmentState = options.apartmentState;
#else
                    newThread.SetApartmentState(options.apartmentState);
#endif
                    newThread.Start();
                    newThread.Join();
                    if (lastException != null)
                        if (lastException is SurrogateHostProcessRequiredException)
                            throw lastException;
                        else
                            throw new ApplicationException("Script " + options.scriptFileName + " cannot be executed.", lastException);

                    //run postscripts
                    foreach (CSharpParser.CmdScriptInfo info in cmdScripts)
                        if (!info.preScript)
                        {
                            Environment.CurrentDirectory = originalCurrDir;
                            info.args[1] = FileParser.ResolveFile(info.args[1], originalOptions.searchDirs);

                            CSExecutor exec = new CSExecutor(info.abortOnError, originalOptions);

                            if (originalOptions.DBG)
                            {
#if net1
                                ArrayList newArgs = new ArrayList();
                                newArgs.AddRange(info.args);
                                newArgs.Insert(0, CSSUtils.Args.DefaultPrefix + "dbg");
                                info.args = (string[])newArgs.ToArray(typeof(string));
#else

                                List<string> newArgs = new List<string>();
                                newArgs.AddRange(info.args);
                                newArgs.Insert(0, CSSUtils.Args.DefaultPrefix + "dbg");
                                info.args = newArgs.ToArray();
#endif
                            }
                            if (originalOptions.verbose)
                            {
#if net1
                                ArrayList newArgs = new ArrayList();
                                newArgs.AddRange(info.args);
                                newArgs.Insert(0, CSSUtils.Args.DefaultPrefix + "verbose");
                                info.args = (string[])newArgs.ToArray(typeof(string));
#else

                                List<string> newArgs = new List<string>();
                                newArgs.AddRange(info.args);
                                newArgs.Insert(0, CSSUtils.Args.DefaultPrefix + "verbose");
                                info.args = newArgs.ToArray();
#endif
                            }
                            if (info.abortOnError)
                            {
                                exec.Rethrow = true;
                                exec.Execute(info.args, printDelg, originalOptions.scriptFileName);
                            }
                            else
                                exec.Execute(info.args, null, originalOptions.scriptFileName);
                        }
                }
                else
                {
                    ShowHelp();
                }
            }
            catch (Surrogate86ProcessRequiredException)
            {
                throw;
            }
            catch (SurrogateHostProcessRequiredException)
            {
                throw;
            }
            catch (Exception e)
            {
                Exception ex = e;
                if (e is System.Reflection.TargetInvocationException)
                    ex = e.InnerException;

                if (rethrow)
                {
                    throw ex;
                }
                else
                {
                    Environment.ExitCode = 1;

                    if (!CSSUtils.IsRuntimeErrorReportingSupressed)
                    {
                        if (options.reportDetailedErrorInfo && !(ex is FileNotFoundException))
                            print(ex.ToString());
                        else
                            print(ex.Message); //Mono friendly
                    }
                }
            }
        }
Exemple #5
0
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="info">ImportInfo object containing the information how the script file should be parsed.</param>
		public ScriptInfo(CSharpParser.ImportInfo info)
		{
			this.fileName = info.file;
			parseParams.AddRenameNamespaceMap(info.renaming);
			parseParams.preserveMain = info.preserveMain ;
		}