예제 #1
0
#pragma warning restore CA1303
        static async Task <int> ProcessAndExecute(CommandLine commandLine)
        {
            var exitCode = 0;

            IEnumerable <string>      remove = new List <string>();
            IEnumerable <ProductInfo> uninstall = new List <ProductInfo>(), install = null;
            var products = await ProductCollection.ReadProducts(commandLine.Arguments.Select((uri, index) => { return(new Uri(uri)); })).ConfigureAwait(false);

            products.MapToLocal(commandLine.StagingFolder);
            if (commandLine.Verbose)
            {
                Console.WriteLine($"Products [{products.Count}]:");
                foreach (var p in products)
                {
                    Console.WriteLine($"  {p.Name}: {p.Uri} => {p.LocalPath}");
                    foreach (var pp in p.Props)
                    {
                        Console.WriteLine($"    {pp.Key} = {pp.Value}");
                    }
                }
            }
            // installed products (cached installer files) we don't need anymore
            remove = products.FindFilesToUninstall(Path.Combine(commandLine.StagingFolder, $"*{Installer.InstallerFileExtension}"));
            if (commandLine.Verbose)
            {
                if (remove.Any())
                {
                    Console.WriteLine($"Remove [{remove.Count()}]:");
                    foreach (var f in remove)
                    {
                        Console.WriteLine($"  {f}");
                    }
                }
            }
            // Prepare a list of files to uninstall for downgrade or props change, and another list of products to install/upgrade
            if (commandLine.ClearStagingFolder)
            {
                commandLine.DeleteStagingFolder();
                install = products;
            }
            else
            {
                (uninstall, install) = products.Separate(localMsiFile =>
                {
                    var localInfoFile    = Path.ChangeExtension(localMsiFile, ProductInfo.LocalInfoFileExtension);
                    var installedProduct = ProductInfo.FindInstalled(localInfoFile).Result;
                    // some backward compatibility in case if was not serialized
                    if (null != installedProduct)
                    {
                        if (string.IsNullOrEmpty(installedProduct.LocalPath))
                        {
                            installedProduct.LocalPath = localMsiFile;
                        }
                    }
                    return(installedProduct);
                },
                                                         commandLine.VersionPrefixes.Split(','));
            }
            if (commandLine.Verbose)
            {
                if (uninstall.Any())
                {
                    Console.WriteLine($"Uninstall [{uninstall.Count()}]:");
                    foreach (var f in uninstall)
                    {
                        Console.WriteLine($"  {f.Uri}");
                    }
                }
                if (install.Any())
                {
                    Console.WriteLine($"Install [{install.Count()}]:");
                    foreach (var f in install)
                    {
                        Console.WriteLine($"  {f.Uri}");
                    }
                }
            }
            // Ok, now we can proceed with changes:
            if (0 == exitCode)
            {
                // 1) Uninstall what's not needed anymore...
                foreach (var f in remove)
                {
                    var err = commandLine.Uninstall(f, !commandLine.DryRun);
                    if (0 == exitCode && 0 != err)
                    {
                        exitCode = err; break;
                    }
                }
                // 2) Uninstall whose to be changed
                foreach (var f in uninstall)
                {
                    var err = commandLine.Uninstall(f.LocalPath, false);
                    if (0 == exitCode && 0 != err)
                    {
                        exitCode = err; break;
                    }
                }
                // 3) Download/cache existing and new
                if (install.Any())
                {
                    var err = commandLine.DownloadProducts(install, commandLine.Timeout);
                    if (0 == err)
                    {
                        // 4) Install changed and new
                        foreach (var p in install)
                        {
                            err = commandLine.Install(p);
                            if (0 == exitCode && 0 != err)
                            {
                                exitCode = err; break;
                            }
                        }
                    }
                }
            }
            return(exitCode);
        }