Example #1
0
        public static void Main(string[] args)
        {
            if (PlaynitePaths.ProgramPath.Contains(@"temp\rar$", StringComparison.OrdinalIgnoreCase))
            {
                MessageBox.Show(
                    "Playnite is not allowed to run from temporary extracted archive.\rInstall/Extract application properly before starting it.",
                    "Startup Error",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return;
            }

            var cmdLine = new CmdLineOptions();
            var parsed  = Parser.Default.ParseArguments <CmdLineOptions>(Environment.GetCommandLineArgs());

            if (parsed is Parsed <CmdLineOptions> options)
            {
                cmdLine = options.Value;
            }

            SplashScreen splash    = null;
            var          procCount = Process.GetProcesses().Where(a => a.ProcessName.StartsWith("Playnite.")).Count();

            if (cmdLine.Start.IsNullOrEmpty() && !cmdLine.HideSplashScreen && procCount == 1)
            {
                splash = new SplashScreen("SplashScreen.png");
                splash.Show(false);
            }

            PlayniteSettings.ConfigureLogger();
            var app = new DesktopApplication(new App(), splash, cmdLine);

            app.Run();
        }
Example #2
0
 public PostBag(ITaskHelper th, ITime time, CmdLineOptions options)
 {
     _th      = th;
     _time    = time;
     _initTcs = new TaskCompletionSource <int>();
     th.Run(() => InitAsync(new SystemDirectory(th, options.BlogRootDirectory)));
 }
Example #3
0
    IEnumerable <Type> GetPuzzleTypes(CmdLineOptions options)
    {
        var puzzleTypes = Assembly.GetEntryAssembly()
                          .GetTypes()
                          .Where(t => typeof(PuzzleBase).IsAssignableFrom(t));

        // All puzzles?
        if (options.RunAll)
        {
            return(puzzleTypes);
        }

        // only the last puzzle?
        if (options.PuzzleDays.Count() == 0)
        {
            return(puzzleTypes
                   .OrderByDescending(t => t.Name)
                   .Take(1));
        }

        // all specified puzzles
        var puzzleNames = options.PuzzleDays.Select(d => $"Day{d:00}").ToList();

        return(puzzleTypes
               .Where(t => puzzleNames.Any(p => t.Name.StartsWith(p))));
    }
        /// <summary>
        /// Ensure that the command line options are valid and within bounds.
        /// </summary>
        /// <param name="opts"><see cref="CmdLineOptions"/> object that contains the parsed command line args.</param>
        public void IsCmdLineValid(CmdLineOptions opts)
        {
            if (opts == null)
            {
                throw new ArgumentNullException(nameof(opts));
            }

            IsLengthValid(opts.Length);
        }
Example #5
0
        public static void Main(string[] args)
        {
            FileSystem.CreateDirectory(PlaynitePaths.JitProfilesPath);
            ProfileOptimization.SetProfileRoot(PlaynitePaths.JitProfilesPath);
            ProfileOptimization.StartProfile("desktop");

            if (PlaynitePaths.ProgramPath.Contains(@"temp\rar$", StringComparison.OrdinalIgnoreCase))
            {
                MessageBox.Show(
                    "Playnite is not allowed to run from temporary extracted archive.\rInstall/Extract application properly before starting it.",
                    "Startup Error",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return;
            }
            else if (PlaynitePaths.ProgramPath.Contains("#"))
            {
                MessageBox.Show(
                    "Playnite is unable to run from current directory due to illegal character '#' in the path. Please use different directory.",
                    "Startup Error",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return;
            }

            var cmdLine = new CmdLineOptions();
            var parsed  = Parser.Default.ParseArguments <CmdLineOptions>(Environment.GetCommandLineArgs());

            if (parsed is Parsed <CmdLineOptions> options)
            {
                cmdLine = options.Value;
            }

            SplashScreen splash    = null;
            var          procCount = Process.GetProcesses().Where(a => a.ProcessName.StartsWith("Playnite.")).Count();

            if (cmdLine.Start.IsNullOrEmpty() && !cmdLine.HideSplashScreen && procCount == 1)
            {
                splash = new SplashScreen("SplashScreen.png");
                splash.Show(false);
            }

            PlayniteSettings.ConfigureLogger();
            LogManager.GetLogger().Info($"App arguments: '{string.Join(",", args)}'");
            var app = new DesktopApplication(new App(), splash, cmdLine);

            app.Run();
        }
Example #6
0
    void SolvePuzzles(CmdLineOptions options)
    {
        var puzzleTypes = GetPuzzleTypes(options).ToList();

        for (var i = 0; i < puzzleTypes.Count; i++)
        {
            var puzzle = (PuzzleBase)Activator.CreateInstance(puzzleTypes[i]);
            puzzle.SetOptions(options.RunBenchmark, options.RunExamples);

            puzzle.SolvePuzzle()
            .Where(t => t != null)
            .ForEach(Console.WriteLine);

            WriteSectionSeperator();
        }
    }
Example #7
0
        /// <summary>
        /// Manager that will handle running the game cmdline options and return a status code to the caller.
        /// </summary>
        /// <param name="opts">CmdLineOptions object that contains the parsed command line args.</param>
        /// <returns>Error Code.  0 = Success, 1 = Failure.</returns>
        public static async Task<int> RunAndReturnExitCodeAsync(CmdLineOptions opts)
        {
            if (opts == null)
            {
                throw new ArgumentNullException(nameof(opts));
            }

            RuntimeTimer.RegisterAppStart();

            m_cmdLineOpts = opts;

            // Validate Input
            ValidateCmdLine val = new ValidateCmdLine();
            val.IsCmdLineValid(opts);

            // Load the dictionary from disk
            await LoadDictFromDiskAsync();

            await Task.Run(() =>
            {
                BoardMaker maker = new BoardMaker();
                maker.LoadRandomBoard(opts.SideLength);
                Board board = maker.GetBoard();

                IGameSolver solver = null;
                if (m_cmdLineOpts.Singlethreaded)
                {
                    solver = new SinglethreadedGameSolverService();
                }
                else
                {
                    solver = new AsyncGameSolverService();
                }
                var foundWords = solver.Solve(m_wordDict, board);

                // This is a little odd.  I want to stop timing before I write all the words, which takes a long time
                RuntimeTimer.RegisterAppEnd();

                var totalOperations = solver.GetTotalOperations();
                PrintFoundWordsToConsole(foundWords, totalOperations, opts.ForceWriteFoundWords);
            });



            return Utils.Consts.c_exitCodeSuccess;
        }
Example #8
0
        /// <summary>
        /// Manager that will handle running the list cmdline options and return a status code to the caller.
        /// </summary>
        /// <param name="opts"><see cref="CmdLineOptions"/> object that contains the parsed command line args.</param>
        /// <returns>Error Code.  0 = Success, 1 = Failure.</returns>
        public static async Task <int> RunAndReturnExitCodeAsync(CmdLineOptions opts)
        {
            if (opts == null)
            {
                throw new ArgumentNullException(nameof(opts));
            }

            // Validate Input
            ValidateCmdLine val = new ValidateCmdLine();

            val.IsCmdLineValid(opts);

            await Task.Run(() =>
            {
                Node rootNode = Helpers.CreateRandomList(opts.Length);
                Node dupNode  = Node.DuplicateList(rootNode);
                Helpers.PrintLists(rootNode, dupNode);
            });

            return(Consts.c_exitCodeSuccess);
        }
Example #9
0
        public static void Main(string[] args)
        {
            var cmdLine = new CmdLineOptions();
            var parsed  = Parser.Default.ParseArguments <CmdLineOptions>(Environment.GetCommandLineArgs());

            if (parsed is Parsed <CmdLineOptions> options)
            {
                cmdLine = options.Value;
            }

            SplashScreen splash = null;

            if (cmdLine.Start.IsNullOrEmpty())
            {
                splash = new SplashScreen("SplashScreen.png");
                splash.Show(false);
            }

            PlayniteSettings.ConfigureLogger();
            var app = new FullscreenApplication(new App(), splash, cmdLine);

            app.Run();
        }
Example #10
0
        public static void Main(string[] args)
        {
            var cmdLine = new CmdLineOptions();
            var parsed  = Parser.Default.ParseArguments <CmdLineOptions>(Environment.GetCommandLineArgs());

            if (parsed is Parsed <CmdLineOptions> options)
            {
                cmdLine = options.Value;
            }

            SplashScreen splash    = null;
            var          procCount = Process.GetProcesses().Where(a => a.ProcessName.StartsWith("Playnite.")).Count();

            if (cmdLine.Start.IsNullOrEmpty() && !cmdLine.HideSplashScreen && procCount == 1)
            {
                splash = new SplashScreen("SplashScreen.png");
                splash.Show(false);
            }

            PlayniteSettings.ConfigureLogger();
            var app = new FullscreenApplication(new App(), splash, cmdLine);

            app.Run();
        }
Example #11
0
        public void ParseQueryStringTest()
        {
            var options = new CmdLineOptions();

            Assert.That.Throws <ArgumentNullException>(() => { BaCon.QueryStringToArgs(null, null); }, (ex) => ex.ParamName == "options");

            // No arguments.
            var args = BaCon.QueryStringToArgs(null, options);

            Assert.AreEqual(0, args.Length);

            // No arguments.
            args = BaCon.QueryStringToArgs("", options);
            Assert.AreEqual(0, args.Length);

            // No arguments.
            args = BaCon.QueryStringToArgs("&&&", options);
            Assert.AreEqual(0, args.Length);

            // Single argument.
            var qs = "hello=world";

            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(2, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("world", args[1]);

            // Single argument.
            qs   = "&&&hello=world&&&";
            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(2, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("world", args[1]);

            // Multiple arguments.
            qs   = "hello=world&adios=mundo";
            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(4, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("world", args[1]);
            Assert.AreEqual("/adios", args[2]);
            Assert.AreEqual("mundo", args[3]);

            // Arguments and flag.
            qs   = "hello=world&goodbye";
            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(3, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("world", args[1]);
            Assert.AreEqual("/goodbye", args[2]);

            // Arguments and negative flag.
            qs   = "hello=world&goodbye-";
            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(3, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("world", args[1]);
            Assert.AreEqual("/goodbye-", args[2]);

            // Full URL.
            qs   = "http://www.theworld.com/?hello=world&adios=mundo";
            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(4, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("world", args[1]);
            Assert.AreEqual("/adios", args[2]);
            Assert.AreEqual("mundo", args[3]);

            // Shouldn't include fragment.
            qs   = "http://www.theworld.com/?hello=world&adios=mundo#something";
            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(4, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("world", args[1]);
            Assert.AreEqual("/adios", args[2]);
            Assert.AreEqual("mundo", args[3]);

            // Encoded value.
            qs   = "hello=the+world";
            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(2, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("the world", args[1]);

            // Encoded value.
            qs   = "hello=the%20world";
            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(2, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("the world", args[1]);

            // Encoded value.
            qs   = "hello=%22Aardvarks+lurk%2C+OK%3F%22";
            args = BaCon.QueryStringToArgs(qs, options);
            Assert.AreEqual(2, args.Length);
            Assert.AreEqual("/hello", args[0]);
            Assert.AreEqual("\"Aardvarks lurk, OK?\"", args[1]);

            qs = "Name=Bob&Age=35";
            var results = BaCon.ParseArgs <TestCmdLineObj>(qs);

            Assert.AreEqual("Bob", results.Args.Name);
            Assert.AreEqual(35, results.Args.Age);
        }
Example #12
0
 /// <summary>
 /// Creates a new instance of CmdLineParseResults.
 /// </summary>
 /// <param name="options"></param>
 protected CmdLineParseResults(CmdLineOptions options)
 {
     Options = options;
 }
 public override void Restart(CmdLineOptions options)
 {
     throw new NotImplementedException();
 }
        static void Main(string[] args)
        {
            var opts = CmdLineOptions.Parse(args);

            var config = BuildConfiguration.Read(
                Path.Combine(opts.ConfigDir, MagicStrings.Files.ConfigYaml));

            Directory.CreateDirectory(opts.PackageOutDir);

            var ap = new ArtifactPackage()
            {
                TargetName          = "lsbeat",
                CanonicalTargetName = "lsbeat",
                Architecture        = MagicStrings.Arch.x86,
                Version             = Environment.GetEnvironmentVariable("GITHUB_VERSION").Trim('v'),
            };

            Console.WriteLine(ap.ToString());

            var pc = config.GetProductConfig(ap.TargetName);

            var companyName    = "Mirero";
            var productSetName = MagicStrings.Beats.Name;
            var displayName    = companyName + " " + MagicStrings.Beats.Name + " " + ap.TargetName;
            var exeName        = ap.CanonicalTargetName + MagicStrings.Ext.DotExe;

            // Generate UUID v5 from product properties.
            // This UUID *must* be stable and unique between Beats.
            var upgradeCode = Uuid5.FromString(ap.CanonicalTargetName);

            var project = new Project(displayName)
            {
                InstallerVersion = 500,

                GUID = upgradeCode,

                Name = $"{displayName} {ap.SemVer} ({ap.Architecture})",

                Description = pc.Description,

                OutFileName = Path.Combine(opts.PackageOutDir, opts.ShortPackageName),
                Version     = new Version(ap.Version),

                Platform = ap.Is32Bit ? Platform.x86 : Platform.x64,

                InstallScope = InstallScope.perMachine,

                UI = WUI.WixUI_Minimal,

                // TODO: Custom images?
                BannerImage     = Path.Combine(opts.ResDir, MagicStrings.Files.TopBannerBmp),
                BackgroundImage = Path.Combine(opts.ResDir, MagicStrings.Files.LeftBannerBmp),

                MajorUpgrade = new MajorUpgrade
                {
                    AllowDowngrades          = false,
                    AllowSameVersionUpgrades = false,
                    DowngradeErrorMessage    = MagicStrings.Errors.NewerVersionInstalled,
                },
            };

            project.Include(WixExtension.UI);
            project.Include(WixExtension.Util);

            project.ControlPanelInfo = new ProductInfo
            {
                Contact      = companyName,
                Manufacturer = companyName,
                UrlInfoAbout = "https://www.mirero.co.kr",

                Comments = pc.Description + ". " + MagicStrings.Beats.Description,

                ProductIcon = Path.Combine(
                    opts.ResDir,
                    Path.GetFileNameWithoutExtension(exeName) + MagicStrings.Ext.DotIco),

                NoRepair = true,
            };


            var beatConfigPath = "[CommonAppDataFolder]" + Path.Combine(companyName, productSetName, ap.CanonicalTargetName);
            var beatDataPath   = Path.Combine(beatConfigPath, "data");
            var beatLogsPath   = Path.Combine(beatConfigPath, "logs");

            var textInfo           = new CultureInfo("en-US", false).TextInfo;
            var serviceDisplayName = $"{companyName} {textInfo.ToTitleCase(ap.TargetName)} {ap.SemVer}";

            WixSharp.File service = null;
            if (pc.IsWindowsService)
            {
                service = new WixSharp.File(Path.Combine(opts.PackageInDir, exeName));

                // TODO: CNDL1150 : ServiceConfig functionality is documented in the Windows Installer SDK to
                //                  "not [work] as expected." Consider replacing ServiceConfig with the
                //                  WixUtilExtension ServiceConfig element.

                service.ServiceInstaller = new ServiceInstaller
                {
                    Interactive = false,

                    Name        = ap.CanonicalTargetName,
                    DisplayName = serviceDisplayName,
                    Description = pc.Description,

                    DependsOn = new[]
                    {
                        new ServiceDependency(MagicStrings.Services.Tcpip),
                        new ServiceDependency(MagicStrings.Services.Dnscache),
                    },

                    Arguments =
                        " --path.home " + ("[INSTALLDIR]" + Path.Combine(ap.Version, ap.CanonicalTargetName)).Quote() +
                        " --path.config " + beatConfigPath.Quote() +
                        " --path.data " + beatDataPath.Quote() +
                        " --path.logs " + beatLogsPath.Quote() +
                        " -E logging.files.redirect_stderr=true",

                    DelayedAutoStart = false,
                    Start            = SvcStartType.auto,

                    StartOn  = SvcEvent.Install,
                    StopOn   = SvcEvent.InstallUninstall_Wait,
                    RemoveOn = SvcEvent.InstallUninstall_Wait,
                };
            }

            var packageContents = new List <WixEntity>
            {
                new DirFiles(Path.Combine(opts.PackageInDir, MagicStrings.Files.All), path =>
                {
                    var itm = path.ToLower();

                    bool exclude =

                        // configuration will go into mutable location
                        itm.EndsWith(MagicStrings.Ext.DotYml, StringComparison.OrdinalIgnoreCase) ||

                        // we install/remove service ourselves
                        itm.EndsWith(MagicStrings.Ext.DotPs1, StringComparison.OrdinalIgnoreCase) ||

                        itm.EndsWith(MagicStrings.Ext.DotTxt, StringComparison.OrdinalIgnoreCase) ||

                        itm.EndsWith(MagicStrings.Ext.DotMd, StringComparison.OrdinalIgnoreCase) ||

                        // .exe must be excluded for service configuration to work
                        (pc.IsWindowsService && itm.EndsWith(exeName, StringComparison.OrdinalIgnoreCase))
                    ;

                    // this is an "include" filter
                    return(!exclude);
                })
            };

            packageContents.AddRange(
                new DirectoryInfo(opts.PackageInDir)
                .GetDirectories()
                .Select(dir => dir.Name)
                .Except(pc.MutableDirs)
                .Select(dirName =>
                        new Dir(
                            dirName,
                            new Files(Path.Combine(
                                          opts.PackageInDir,
                                          dirName,
                                          MagicStrings.Files.All)))));

            packageContents.Add(pc.IsWindowsService ? service : null);
            project.AddProperty(new Property("WIXUI_EXITDIALOGOPTIONALTEXT",
                                             $"NOTE: {serviceDisplayName} Windows service.\n"));

            var dataContents = new List <WixEntity>();
            var extraDir     = Path.Combine(opts.ExtraDir, ap.TargetName);

            dataContents.AddRange(
                new DirectoryInfo(extraDir)
                .GetFiles(MagicStrings.Files.AllDotYml, SearchOption.TopDirectoryOnly)
                .Select(fi =>
            {
                var wf = new WixSharp.File(fi.FullName);
                return(wf);
            }));

            dataContents.AddRange(
                new DirectoryInfo(extraDir)
                .GetDirectories()
                .Select(dir => dir.Name)
                .Select(dirName =>
                        new Dir(
                            dirName,
                            new Files(Path.Combine(
                                          extraDir,
                                          dirName,
                                          MagicStrings.Files.All)))));

            // Drop CLI shim on disk
            var cliShimScriptPath = Path.Combine(
                opts.PackageOutDir,
                MagicStrings.Files.ProductCliShim(ap.CanonicalTargetName));

            System.IO.File.WriteAllText(cliShimScriptPath, Resources.GenericCliShim);

            var beatsInstallPath =
                $"[ProgramFiles{(ap.Is64Bit ? "64" : string.Empty)}Folder]" +
                Path.Combine(companyName, productSetName);

            project.Dirs = new[]
            {
                // Binaries
                new InstallDir(
                    // Wix# directory parsing needs forward slash
                    beatsInstallPath.Replace("Folder]", "Folder]\\"),
                    new Dir(
                        ap.Version,
                        new Dir(ap.CanonicalTargetName, packageContents.ToArray()),
                        new WixSharp.File(cliShimScriptPath))),

                // Configration and logs
                new Dir("[CommonAppDataFolder]",
                        new Dir(companyName,
                                new Dir(productSetName,
                                        new Dir(ap.CanonicalTargetName, dataContents.ToArray())
                                        , new DirPermission("Users", "[MachineName]", GenericPermission.All)
                                        )))
            };

            // CLI Shim path
            project.Add(new EnvironmentVariable("PATH", Path.Combine(beatsInstallPath, ap.Version))
            {
                Part = EnvVarPart.last
            });

            // We hard-link Wix Toolset to a known location
            Compiler.WixLocation = Path.Combine(opts.BinDir, "WixToolset", "bin");

#if !DEBUG
            if (opts.KeepTempFiles)
#endif
            {
                Compiler.PreserveTempFiles = true;
            }

            if (opts.Verbose)
            {
                Compiler.CandleOptions += " -v";
                Compiler.LightOptions  += " -v";
            }

            project.ResolveWildCards();

            if (opts.WxsOnly)
            {
                project.BuildWxs();
            }
            else if (opts.CmdOnly)
            {
                Compiler.BuildMsiCmd(project, Path.Combine(opts.SrcDir, opts.PackageName) + ".cmd");
            }
            else
            {
                Compiler.BuildMsi(project);
            }
        }
Example #15
0
 /// <summary>
 /// Creates an instance of CmdLinePropertyBag.
 /// </summary>
 /// <param name="options"></param>
 internal CmdLinePropertyBag(CmdLineOptions options)
 {
     Options = options;
 }
Example #16
0
        static void Main(string[] args)
        {
            var opts = CmdLineOptions.Parse(args);

            var config = BuildConfiguration.Read(
                Path.Combine(opts.ConfigDir, MagicStrings.Files.ConfigYaml));

            Directory.CreateDirectory(opts.PackageOutDir);

            if (!ArtifactPackage.FromFilename(opts.PackageName, out var ap))
            {
                throw new Exception("Unable to parse file name: " + opts.PackageName);
            }

            var pc = config.GetProductConfig(ap.TargetName);

            var companyName    = MagicStrings.Elastic;
            var productSetName = MagicStrings.Beats.Name;
            var displayName    = MagicStrings.Beats.Name + " " + ap.TargetName;
            var exeName        = ap.CanonicalTargetName + MagicStrings.Ext.DotExe;

            // Generate UUID v5 from product properties.
            // This UUID *must* be stable and unique between Beats.
            var upgradeCode = Uuid5.FromString(ap.CanonicalTargetName);

            var project = new Project(displayName)
            {
                InstallerVersion = 500,

                GUID = upgradeCode,

                Name = $"{displayName} {ap.SemVer} ({ap.Architecture})",

                Description = pc.Description,

                OutFileName = Path.Combine(opts.PackageOutDir, opts.PackageName),
                Version     = new Version(ap.Version),

                // We massage LICENSE.txt into .rtf below
                LicenceFile = Path.Combine(
                    opts.PackageOutDir,
                    MagicStrings.Files.PackageLicenseRtf(opts.PackageName)),

                Platform = ap.Is32Bit ? Platform.x86 : Platform.x64,

                InstallScope = InstallScope.perMachine,

                UI = WUI.WixUI_Minimal,

                // TODO: Custom images?
                BannerImage     = Path.Combine(opts.ResDir, MagicStrings.Files.TopBannerBmp),
                BackgroundImage = Path.Combine(opts.ResDir, MagicStrings.Files.LeftBannerBmp),

                MajorUpgrade = new MajorUpgrade
                {
                    AllowDowngrades          = false,
                    AllowSameVersionUpgrades = false,
                    DowngradeErrorMessage    = MagicStrings.Errors.NewerVersionInstalled,
                },
            };

            project.Include(WixExtension.UI);
            project.Include(WixExtension.Util);

            project.ControlPanelInfo = new ProductInfo
            {
                Contact      = companyName,
                Manufacturer = companyName,
                UrlInfoAbout = "https://www.elastic.co",

                Comments = pc.Description + ". " + MagicStrings.Beats.Description,

                ProductIcon = Path.Combine(
                    opts.ResDir,
                    Path.GetFileNameWithoutExtension(exeName) + MagicStrings.Ext.DotIco),

                NoRepair = true,
            };

            // Convert LICENSE.txt to something richedit control can render
            System.IO.File.WriteAllText(
                Path.Combine(
                    opts.PackageOutDir,
                    MagicStrings.Files.PackageLicenseRtf(opts.PackageName)),
                MagicStrings.Content.WrapWithRtf(
                    System.IO.File.ReadAllText(
                        Path.Combine(opts.PackageInDir, MagicStrings.Files.LicenseTxt))));

            var beatConfigPath = "[CommonAppDataFolder]" + Path.Combine(companyName, productSetName, ap.CanonicalTargetName);
            var beatDataPath   = Path.Combine(beatConfigPath, "data");
            var beatLogsPath   = Path.Combine(beatConfigPath, "logs");

            var textInfo           = new CultureInfo("en-US", false).TextInfo;
            var serviceDisplayName = $"{companyName} {textInfo.ToTitleCase(ap.TargetName)} {ap.SemVer}";

            WixSharp.File service = null;
            if (pc.IsWindowsService)
            {
                service = new WixSharp.File(Path.Combine(opts.PackageInDir, exeName));

                // TODO: CNDL1150 : ServiceConfig functionality is documented in the Windows Installer SDK to
                //                  "not [work] as expected." Consider replacing ServiceConfig with the
                //                  WixUtilExtension ServiceConfig element.

                service.ServiceInstaller = new ServiceInstaller
                {
                    Interactive = false,

                    Name        = ap.CanonicalTargetName,
                    DisplayName = serviceDisplayName,
                    Description = pc.Description,

                    DependsOn = new[]
                    {
                        new ServiceDependency(MagicStrings.Services.Tcpip),
                        new ServiceDependency(MagicStrings.Services.Dnscache),
                    },

                    Arguments =
                        " --path.home " + ("[INSTALLDIR]" + Path.Combine(ap.Version, ap.CanonicalTargetName)).Quote() +
                        " --path.config " + beatConfigPath.Quote() +
                        " --path.data " + beatDataPath.Quote() +
                        " --path.logs " + beatLogsPath.Quote() +
                        " -E logging.files.redirect_stderr=true",

                    DelayedAutoStart = false,
                    Start            = SvcStartType.auto,

                    // Don't start on install, config file is likely not ready yet
                    //StartOn = SvcEvent.Install,

                    StopOn   = SvcEvent.InstallUninstall_Wait,
                    RemoveOn = SvcEvent.InstallUninstall_Wait,
                };
            }

            var packageContents = new List <WixEntity>
            {
                new DirFiles(Path.Combine(opts.PackageInDir, MagicStrings.Files.All), path =>
                {
                    var itm = path.ToLower();

                    bool exclude =

                        // configuration will go into mutable location
                        itm.EndsWith(MagicStrings.Ext.DotYml, StringComparison.OrdinalIgnoreCase) ||

                        // we install/remove service ourselves
                        itm.EndsWith(MagicStrings.Ext.DotPs1, StringComparison.OrdinalIgnoreCase) ||

                        // .exe must be excluded for service configuration to work
                        (pc.IsWindowsService && itm.EndsWith(exeName, StringComparison.OrdinalIgnoreCase))
                    ;

                    // this is an "include" filter
                    return(!exclude);
                })
            };

            packageContents.AddRange(
                new DirectoryInfo(opts.PackageInDir)
                .GetDirectories()
                .Select(dir => dir.Name)
                .Except(pc.MutableDirs)
                .Select(dirName =>
                        new Dir(
                            dirName,
                            new Files(Path.Combine(
                                          opts.PackageInDir,
                                          dirName,
                                          MagicStrings.Files.All)))));

            packageContents.Add(pc.IsWindowsService ? service : null);

            // Add a note to the final screen and a checkbox to open the directory of .example.yml file
            var beatConfigExampleFileName = ap.CanonicalTargetName + ".example" + MagicStrings.Ext.DotYml;
            var beatConfigExampleFileId   = beatConfigExampleFileName + "_" + (uint)beatConfigExampleFileName.GetHashCode32();

            project.AddProperty(new Property("WIXUI_EXITDIALOGOPTIONALTEXT",
                                             $"NOTE: Only Administrators can modify configuration files! We put an example configuration file " +
                                             $"in the data directory caled {ap.CanonicalTargetName}.example.yml. Please copy this example file to " +
                                             $"{ap.CanonicalTargetName}.yml and make changes according to your environment. Once {ap.CanonicalTargetName}.yml " +
                                             $"is created, you can configure {ap.CanonicalTargetName} from your favorite shell (in an elevated prompt) " +
                                             $"and then start {serviceDisplayName} Windows service.\r\n"));

            project.AddProperty(new Property("WIXUI_EXITDIALOGOPTIONALCHECKBOX", "1"));
            project.AddProperty(new Property("WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT",
                                             $"Open {ap.CanonicalTargetName} data directory in Windows Explorer"));

            // We'll open the folder for now
            // TODO: select file in explorer window
            project.AddProperty(new Property(
                                    "WixShellExecTarget",
                                    $"[$Component.{beatConfigExampleFileId}]"));

            project.AddWixFragment("Wix/Product",
                                   XElement.Parse(@"
<CustomAction
    Id=""CA_SelectExampleYamlInExplorer""
    BinaryKey = ""WixCA""
    DllEntry = ""WixShellExec""
    Impersonate = ""yes""
/>"),
                                   XElement.Parse(@"
<UI>
    <Publish
        Dialog=""ExitDialog""
        Control=""Finish""
        Event=""DoAction"" 
        Value=""CA_SelectExampleYamlInExplorer"">WIXUI_EXITDIALOGOPTIONALCHECKBOX=1 and NOT Installed
    </Publish>
</UI>"));

            var dataContents = new DirectoryInfo(opts.PackageInDir)
                               .GetFiles(MagicStrings.Files.AllDotYml, SearchOption.TopDirectoryOnly)
                               .Select(fi =>
            {
                var wf = new WixSharp.File(fi.FullName);

                // rename main config file to hide it from MSI engine and keep customizations
                if (string.Compare(
                        fi.Name,
                        ap.CanonicalTargetName + MagicStrings.Ext.DotYml,
                        StringComparison.OrdinalIgnoreCase) == 0)
                {
                    wf.Attributes.Add("Name", beatConfigExampleFileName);
                    wf.Id = new Id(beatConfigExampleFileId);
                }

                return(wf);
            })
                               .ToList <WixEntity>();

            dataContents.AddRange(
                pc.MutableDirs
                .Select(dirName =>
            {
                var dirPath = Path.Combine(opts.PackageInDir, dirName);

                return(Directory.Exists(dirPath)
                            ? new Dir(dirName, new Files(Path.Combine(dirPath, MagicStrings.Files.All)))
                            : null);
            })
                .Where(dir => dir != null));

            // Drop CLI shim on disk
            var cliShimScriptPath = Path.Combine(
                opts.PackageOutDir,
                MagicStrings.Files.ProductCliShim(ap.CanonicalTargetName));

            System.IO.File.WriteAllText(cliShimScriptPath, Resources.GenericCliShim);

            var beatsInstallPath =
                $"[ProgramFiles{(ap.Is64Bit ? "64" : string.Empty)}Folder]" +
                Path.Combine(companyName, productSetName);

            project.Dirs = new[]
            {
                // Binaries
                new InstallDir(
                    // Wix# directory parsing needs forward slash
                    beatsInstallPath.Replace("Folder]", "Folder]\\"),
                    new Dir(
                        ap.Version,
                        new Dir(ap.CanonicalTargetName, packageContents.ToArray()),
                        new WixSharp.File(cliShimScriptPath))),

                // Configration and logs
                new Dir("[CommonAppDataFolder]",
                        new Dir(companyName,
                                new Dir(productSetName,
                                        new Dir(ap.CanonicalTargetName, dataContents.ToArray())
                {
                    GenericItems = new []
                    {
                        /*
                         * This will *replace* ACL on the {beatname} directory:
                         *
                         * Directory tree:
                         *  NT AUTHORITY\SYSTEM:(OI)(CI)F
                         *  BUILTIN\Administrators:(OI)(CI)F
                         *  BUILTIN\Users:(CI)R
                         *
                         * Files:
                         *  NT AUTHORITY\SYSTEM:(ID)F
                         *  BUILTIN\Administrators:(ID)F
                         */

                        new MsiLockPermissionEx(
                            "D:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;CI;0x1200a9;;;BU)",
                            ap.Is64Bit)
                    }
                })))
            };

            // CLI Shim path
            project.Add(new EnvironmentVariable("PATH", Path.Combine(beatsInstallPath, ap.Version))
            {
                Part = EnvVarPart.last
            });

            // We hard-link Wix Toolset to a known location
            Compiler.WixLocation = Path.Combine(opts.BinDir, "WixToolset", "bin");

#if !DEBUG
            if (opts.KeepTempFiles)
#endif
            {
                Compiler.PreserveTempFiles = true;
            }

            if (opts.Verbose)
            {
                Compiler.CandleOptions += " -v";
                Compiler.LightOptions  += " -v";
            }

            project.ResolveWildCards();

            if (opts.WxsOnly)
            {
                project.BuildWxs();
            }
            else if (opts.CmdOnly)
            {
                Compiler.BuildMsiCmd(project, Path.Combine(opts.SrcDir, opts.PackageName) + ".cmd");
            }
            else
            {
                Compiler.BuildMsi(project);
            }
        }
Example #17
0
 /// <summary>
 /// Creates an instance of CmdLineParser.
 /// </summary>
 /// <param name="options"></param>
 public CmdLineParser(CmdLineOptions options = null)
 {
     Options = options ?? CmdLineOptions.GetOptions <T>();            // We must have options for parsing.
 }
Example #18
0
        private static void Main(string[] args)
        {
            CmdLineOptions cmdLineOptions    = new CmdLineOptions();
            var            commandLineParser = new Parser();

            if (!commandLineParser.ParseArguments(args, cmdLineOptions))
            {
                Console.WriteLine("Enter Slack WebHook url:");
                cmdLineOptions.WebHookUrl = Console.ReadLine();
                Console.WriteLine("Enter Slack channel:");
                cmdLineOptions.Channel = Console.ReadLine();
                Console.WriteLine("Enter Slack user:"******"Message has been successfully published!");
                            autoResetEvent.Set();
                        };

                        mySlackGateway.Api.SlackProxy_Component.PublishMessage_StateMachine.Error_State.InstanceUpdated +=
                            instance =>
                        {
                            Console.WriteLine("Error while publishing message: " + instance.PublicMember.Message);
                            autoResetEvent.Set();
                        };

                        SendMessage slackMessage = new SendMessage()
                        {
                            SlackChannel      = cmdLineOptions.Channel,
                            SlackUrlWithToken = cmdLineOptions.WebHookUrl,
                            SlackUser         = cmdLineOptions.User,
                            // MessageTitle = "My first slack message",
                            // Text = "Hello from slack",
                            //  MessageImage = "https://raw.githubusercontent.com/xcomponent/xcomponent/master/Examples/xcomponent.slack/images/XCChristmasLogo.png",
                            // IconEmoji = ":tv:" // http://www.emoji-cheat-sheet.com/
                        };

                        mySlackGateway.Api.SlackProxy_Component.SlackProxy_StateMachine.SendEvent(slackMessage);

                        autoResetEvent.WaitOne();
                    }

                    Console.WriteLine("Press any key to leave...");
                    Console.ReadKey();
                }
                else
                {
                    Console.WriteLine("Can't initialize client Api !");
                }
            }
        }