private static int Main(string[] args) { var exeName = Path.GetFileName(Assembly.GetExecutingAssembly().Location); var showHelp = false; var options = new BuilderOptions(Logger.GetLogger("BuildEngine")); var p = new OptionSet { "Copyright (C) 2011-2013 Silicon Studio Corporation. All Rights Reserved", "Paradox Build Tool - Version: " + String.Format( "{0}.{1}.{2}", typeof(Program).Assembly.GetName().Version.Major, typeof(Program).Assembly.GetName().Version.Minor, typeof(Program).Assembly.GetName().Version.Build) + string.Empty, string.Format("Usage: {0} [options]* inputfile -o outputfile", exeName), string.Empty, "=== Options ===", string.Empty, { "h|help", "Show this message and exit", v => showHelp = v != null }, { "v|verbose", "Show more verbose progress logs", v => options.Verbose = v != null }, { "d|debug", "Show debug logs (imply verbose)", v => options.Debug = v != null }, { "c|clean", "Clean the command cache, forcing to rebuild everything at the next build.", v => options.BuilderMode = Builder.Mode.Clean }, { "cd|clean-delete", "Clean the command cache and delete output objects", v => options.BuilderMode = Builder.Mode.CleanAndDelete }, { "b|build-path=", "Build path", v => options.BuildDirectory = v }, { "mdb|metadata-database=", "Optional ; indicate the directory containing the Metadata database, if used.", v => { if (!string.IsNullOrEmpty(v)) options.MetadataDatabaseDirectory = v; } }, { "o|output-path=", "Optional ; indicate an output path to copy the built assets in.", v => options.OutputDirectory = v }, { "cfg|config=", "Configuration name", v => options.Configuration = v }, { "log", "Enable file logging", v => options.EnableFileLogging = v != null }, { "log-file=", "Log build in a custom file.", v => { options.EnableFileLogging = v != null; options.CustomLogFileName = v; } }, { "monitor-pipe=", "Monitor pipe.", v => { if (!string.IsNullOrEmpty(v)) options.MonitorPipeNames.Add(v); } }, { "slave=", "Slave pipe", v => options.SlavePipe = v }, // Benlitz: I don't think this should be documented { "s|sourcebase=", "Optional ; Set the base directory for the source files. Not required if all source paths are absolute", v => options.SourceBaseDirectory = v }, { "a|append", "If set, the existing asset mappings won't be deleted.", v => options.Append = v != null }, { "t|threads=", "Number of threads to create. Default value is the number of hardware threads available.", v => options.ThreadCount = int.Parse(v) }, { "p|plugin=", "Add plugin directory.", v => { if (!string.IsNullOrEmpty(v)) options.Plugins.AddPluginFolder(v); } }, { "test=", "Run a test session.", v => options.TestName = v } }; TextWriterLogListener fileLogListener = null; // Output logs to the console with colored messages if (options.SlavePipe == null) { var consoleLogListener = new ConsoleLogListener { TextFormatter = FormatLog }; GlobalLogger.MessageLogged += consoleLogListener; } // Setting up plugin manager options.Plugins.AddPluginFolder(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) ?? "", "BuildPlugins")); options.Plugins.Register(); BuildResultCode exitCode; try { options.InputFiles = p.Parse(args); // Also write logs from master process into a file if (options.SlavePipe == null) { if (options.EnableFileLogging) { string logFileName = options.CustomLogFileName; if (string.IsNullOrEmpty(logFileName)) { string inputName = "NoInput"; if (options.InputFiles.Count > 0) inputName = Path.GetFileNameWithoutExtension(options.InputFiles[0]); logFileName = "Logs/Build-" + inputName + "-" + DateTime.Now.ToString("yy-MM-dd-HH-mm") + ".txt"; } string dirName = Path.GetDirectoryName(logFileName); if (dirName != null) Directory.CreateDirectory(dirName); fileLogListener = new TextWriterLogListener(new FileStream(logFileName, FileMode.Create)) { TextFormatter = FormatLog }; GlobalLogger.MessageLogged += fileLogListener; } options.Logger.Info("BuildEngine arguments: " + string.Join(" ", args)); options.Logger.Info("Starting builder."); } if (showHelp) { p.WriteOptionDescriptions(Console.Out); exitCode = BuildResultCode.Successful; } else if (!string.IsNullOrEmpty(options.TestName)) { var test = new TestSession(); test.RunTest(options.TestName, options.Logger); exitCode = BuildResultCode.Successful; } else { exitCode = BuildEngineCommands.Build(options); } } catch (OptionException e) { options.Logger.Error("{0}", e); exitCode = BuildResultCode.CommandLineError; } catch (Exception e) { options.Logger.Error("{0}", e); exitCode = BuildResultCode.BuildError; } finally { if (fileLogListener != null) fileLogListener.LogWriter.Close(); } return (int)exitCode; }
public int Run(string[] args) { // This is used by ExecServer to retrieve the logs directly without using the console redirect (which is not working well // in a multi-domain scenario) var redirectLogToAppDomainAction = AppDomain.CurrentDomain.GetData("AppDomainLogToAction") as Action<string, ConsoleColor>; clock = Stopwatch.StartNew(); // TODO this is hardcoded. Check how to make this dynamic instead. RuntimeHelpers.RunModuleConstructor(typeof(IProceduralModel).Module.ModuleHandle); RuntimeHelpers.RunModuleConstructor(typeof(MaterialKeys).Module.ModuleHandle); RuntimeHelpers.RunModuleConstructor(typeof(SpriteFontAsset).Module.ModuleHandle); RuntimeHelpers.RunModuleConstructor(typeof(ModelAsset).Module.ModuleHandle); RuntimeHelpers.RunModuleConstructor(typeof(SpriteStudioAnimationAsset).Module.ModuleHandle); //var project = new Package(); //project.Save("test.pdxpkg"); //Thread.Sleep(10000); //var spriteFontAsset = StaticFontAsset.New(); //Asset.Save("test.pdxfnt", spriteFontAsset); //project.Refresh(); //args = new string[] { "test.pdxpkg", "-o:app_data", "-b:tmp", "-t:1" }; var exeName = Path.GetFileName(Assembly.GetExecutingAssembly().Location); var showHelp = false; var options = new PackageBuilderOptions(new ForwardingLoggerResult(GlobalLogger.GetLogger("BuildEngine"))); var p = new OptionSet { "Copyright (C) 2011-2014 Silicon Studio Corporation. All Rights Reserved", "Paradox Build Tool - Version: " + String.Format( "{0}.{1}.{2}", typeof(Program).Assembly.GetName().Version.Major, typeof(Program).Assembly.GetName().Version.Minor, typeof(Program).Assembly.GetName().Version.Build) + string.Empty, string.Format("Usage: {0} inputPackageFile [options]* -b buildPath", exeName), string.Empty, "=== Options ===", string.Empty, { "h|help", "Show this message and exit", v => showHelp = v != null }, { "v|verbose", "Show more verbose progress logs", v => options.Verbose = v != null }, { "d|debug", "Show debug logs (imply verbose)", v => options.Debug = v != null }, { "log", "Enable file logging", v => options.EnableFileLogging = v != null }, { "disable-auto-compile", "Disable auto-compile of projects", v => options.DisableAutoCompileProjects = v != null}, { "p|profile=", "Profile name", v => options.BuildProfile = v }, { "project-configuration=", "Project configuration", v => options.ProjectConfiguration = v }, { "platform=", "Platform name", v => options.Platform = (PlatformType)Enum.Parse(typeof(PlatformType), v) }, { "graphics-platform=", "Graphics Platform name", v => options.GraphicsPlatform = (GraphicsPlatform)Enum.Parse(typeof(GraphicsPlatform), v) }, { "get-graphics-platform", "Get Graphics Platform name (needs a pdxpkg and a profile)", v => options.GetGraphicsPlatform = v != null }, { "solution-file=", "Solution File Name", v => options.SolutionFile = v }, { "package-id=", "Package Id from the solution file", v => options.PackageId = Guid.Parse(v) }, { "package-file=", "Input Package File Name", v => options.PackageFile = v }, { "o|output-path=", "Output path", v => options.OutputDirectory = v }, { "b|build-path=", "Build path", v => options.BuildDirectory = v }, { "log-file=", "Log build in a custom file.", v => { options.EnableFileLogging = v != null; options.CustomLogFileName = v; } }, { "log-pipe=", "Log pipe.", v => { if (!string.IsNullOrEmpty(v)) options.LogPipeNames.Add(v); } }, { "monitor-pipe=", "Monitor pipe.", v => { if (!string.IsNullOrEmpty(v)) options.MonitorPipeNames.Add(v); } }, { "slave=", "Slave pipe", v => options.SlavePipe = v }, // Benlitz: I don't think this should be documented { "server=", "This Compiler is launched as a server", v => { } }, { "t|threads=", "Number of threads to create. Default value is the number of hardware threads available.", v => options.ThreadCount = int.Parse(v) }, { "test=", "Run a test session.", v => options.TestName = v }, { "property:", "Properties. Format is name1=value1;name2=value2", v => { if (!string.IsNullOrEmpty(v)) { foreach (var nameValue in v.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { var equalIndex = nameValue.IndexOf('='); if (equalIndex == -1) throw new OptionException("Expect name1=value1;name2=value2 format.", "property"); options.Properties.Add(nameValue.Substring(0, equalIndex), nameValue.Substring(equalIndex + 1)); } } } }, { "compile-property:", "Compile properties. Format is name1=value1;name2=value2", v => { if (!string.IsNullOrEmpty(v)) { if (options.ExtraCompileProperties == null) options.ExtraCompileProperties = new Dictionary<string, string>(); foreach (var nameValue in v.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { var equalIndex = nameValue.IndexOf('='); if (equalIndex == -1) throw new OptionException("Expect name1=value1;name2=value2 format.", "property"); options.ExtraCompileProperties.Add(nameValue.Substring(0, equalIndex), nameValue.Substring(equalIndex + 1)); } } } }, }; TextWriterLogListener fileLogListener = null; // Output logs to the console with colored messages if (options.SlavePipe == null) { if (redirectLogToAppDomainAction != null) { globalLoggerOnGlobalMessageLogged = new LogListenerRedirectToAction(redirectLogToAppDomainAction); } else { globalLoggerOnGlobalMessageLogged = new ConsoleLogListener { LogMode = ConsoleLogMode.Always }; } globalLoggerOnGlobalMessageLogged.TextFormatter = FormatLog; GlobalLogger.GlobalMessageLogged += globalLoggerOnGlobalMessageLogged; } BuildResultCode exitCode; try { var unexpectedArgs = p.Parse(args); if (unexpectedArgs.Any()) { throw new OptionException("Unexpected arguments [{0}]".ToFormat(string.Join(", ", unexpectedArgs)), "args"); } try { options.ValidateOptions(); } catch (ArgumentException ex) { throw new OptionException(ex.Message, ex.ParamName); } // Also write logs from master process into a file if (options.SlavePipe == null) { if (options.EnableFileLogging) { string logFileName = options.CustomLogFileName; if (string.IsNullOrEmpty(logFileName)) { string inputName = Path.GetFileNameWithoutExtension(options.PackageFile); logFileName = "Logs/Build-" + inputName + "-" + DateTime.Now.ToString("yy-MM-dd-HH-mm") + ".txt"; } string dirName = Path.GetDirectoryName(logFileName); if (dirName != null) Directory.CreateDirectory(dirName); fileLogListener = new TextWriterLogListener(new FileStream(logFileName, FileMode.Create)) { TextFormatter = FormatLog }; GlobalLogger.GlobalMessageLogged += fileLogListener; } if (!options.GetGraphicsPlatform) { options.Logger.Info("BuildEngine arguments: " + string.Join(" ", args)); options.Logger.Info("Starting builder."); } } else { IsSlave = true; } if (showHelp) { p.WriteOptionDescriptions(Console.Out); exitCode = BuildResultCode.Successful; } else if (!string.IsNullOrEmpty(options.TestName)) { var test = new TestSession(); test.RunTest(options.TestName, options.Logger); exitCode = BuildResultCode.Successful; } else { builder = new PackageBuilder(options); if (!IsSlave && redirectLogToAppDomainAction == null) { Console.CancelKeyPress += OnConsoleOnCancelKeyPress; } exitCode = builder.Build(); } } catch (OptionException e) { options.Logger.Error("Command option '{0}': {1}", e.OptionName, e.Message); exitCode = BuildResultCode.CommandLineError; } catch (Exception e) { options.Logger.Error("Unhandled exception: {0}", e, e.Message); exitCode = BuildResultCode.BuildError; } finally { if (fileLogListener != null) { GlobalLogger.GlobalMessageLogged -= fileLogListener; fileLogListener.LogWriter.Close(); } // Output logs to the console with colored messages if (globalLoggerOnGlobalMessageLogged != null) { GlobalLogger.GlobalMessageLogged -= globalLoggerOnGlobalMessageLogged; } if (builder != null && !IsSlave && redirectLogToAppDomainAction == null) { Console.CancelKeyPress -= OnConsoleOnCancelKeyPress; } // Make sure that MSBuild doesn't hold anything else VSProjectHelper.Reset(); // Reset cache hold by YamlSerializer YamlSerializer.ResetCache(); } return (int)exitCode; }
static int Main(string[] args) { var exeName = Path.GetFileName(Assembly.GetExecutingAssembly().Location); var showHelp = false; var windowsPhonePortMapping = false; int exitCode = 0; string logFileName = "routerlog.txt"; var p = new OptionSet { "Copyright (C) 2011-2015 Silicon Studio Corporation. All Rights Reserved", "Paradox Router Server - Version: " + String.Format( "{0}.{1}.{2}", typeof(Program).Assembly.GetName().Version.Major, typeof(Program).Assembly.GetName().Version.Minor, typeof(Program).Assembly.GetName().Version.Build) + string.Empty, string.Format("Usage: {0} command [options]*", exeName), string.Empty, "=== Options ===", string.Empty, { "h|help", "Show this message and exit", v => showHelp = v != null }, { "log-file=", "Log build in a custom file (default: routerlog.txt).", v => logFileName = v }, { "register-windowsphone-portmapping", "Register Windows Phone IpOverUsb port mapping", v => windowsPhonePortMapping = true }, }; try { var commandArgs = p.Parse(args); if (showHelp) { p.WriteOptionDescriptions(Console.Out); return 0; } // Make sure path exists if (commandArgs.Count > 0) throw new OptionException("This command expect no additional arguments", ""); if (windowsPhonePortMapping) { WindowsPhoneTracker.RegisterWindowsPhonePortMapping(); return 0; } SetupTrayIcon(logFileName); // Enable file logging if (!string.IsNullOrEmpty(logFileName)) { var fileLogListener = new TextWriterLogListener(File.Open(logFileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)); GlobalLogger.GlobalMessageLogged += fileLogListener; } try { if (!RouterHelper.RouterMutex.WaitOne(TimeSpan.Zero, true)) { Console.WriteLine("Another instance of Paradox Router is already running"); return -1; } } catch (AbandonedMutexException) { // Previous instance of this application was not closed properly. // However, receiving this exception means we could capture the mutex. } var router = new Router(); // Start router (in listen server mode) router.Listen(RouterClient.DefaultPort); // Start Android management thread new Thread(() => AndroidTracker.TrackDevices(router)) { IsBackground = true }.Start(); // Start Windows Phone management thread new Thread(() => WindowsPhoneTracker.TrackDevices(router)) { IsBackground = true }.Start(); // Start WinForms loop System.Windows.Forms.Application.Run(); } catch (Exception e) { Console.WriteLine("{0}: {1}", exeName, e); if (e is OptionException) p.WriteOptionDescriptions(Console.Out); exitCode = 1; } return exitCode; }
static int Main(string[] args) { var exeName = Path.GetFileName(Assembly.GetExecutingAssembly().Location); var showHelp = false; var windowsPhonePortMapping = false; int exitCode = 0; string logFileName = "routerlog.txt"; var p = new OptionSet { "Copyright (C) 2011-2015 Silicon Studio Corporation. All Rights Reserved", "Xenko Router Server - Version: " + String.Format( "{0}.{1}.{2}", typeof(Program).Assembly.GetName().Version.Major, typeof(Program).Assembly.GetName().Version.Minor, typeof(Program).Assembly.GetName().Version.Build) + string.Empty, string.Format("Usage: {0} command [options]*", exeName), string.Empty, "=== Options ===", string.Empty, { "h|help", "Show this message and exit", v => showHelp = v != null }, { "log-file=", "Log build in a custom file (default: routerlog.txt).", v => logFileName = v }, { "register-windowsphone-portmapping", "Register Windows Phone IpOverUsb port mapping", v => windowsPhonePortMapping = true }, }; try { var commandArgs = p.Parse(args); if (showHelp) { p.WriteOptionDescriptions(Console.Out); return 0; } // Make sure path exists if (commandArgs.Count > 0) throw new OptionException("This command expect no additional arguments", ""); if (windowsPhonePortMapping) { WindowsPhoneTracker.RegisterWindowsPhonePortMapping(); return 0; } SetupTrayIcon(logFileName); // Enable file logging if (!string.IsNullOrEmpty(logFileName)) { var fileLogListener = new TextWriterLogListener(File.Open(logFileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)); GlobalLogger.GlobalMessageLogged += fileLogListener; } // TODO: Lock will be only for this folder but it should be shared across OS (should we resolve SiliconStudioXenkoDir?) using (var mutex = FileLock.TryLock("connectionrouter.lock")) { if (mutex == null) { Console.WriteLine("Another instance of Xenko Router is already running"); return -1; } var router = new Router(); // Start router (in listen server mode) router.Listen(RouterClient.DefaultPort).Wait(); // Start Android management thread new Thread(() => AndroidTracker.TrackDevices(router)) { IsBackground = true }.Start(); // Start Windows Phone management thread new Thread(() => WindowsPhoneTracker.TrackDevices(router)) { IsBackground = true }.Start(); //Start iOS device discovery and proxy launcher //Currently this is used only internally for QA testing... as we cannot attach the debugger from windows for normal usages.. if (IosTracker.CanProxy()) { new Thread(async () => { var iosTracker = new IosTracker(router); await iosTracker.TrackDevices(); }) { IsBackground = true }.Start(); } // Start WinForms loop System.Windows.Forms.Application.Run(); } } catch (Exception e) { Console.WriteLine("{0}: {1}", exeName, e); if (e is OptionException) p.WriteOptionDescriptions(Console.Out); exitCode = 1; } return exitCode; }