コード例 #1
0
        private static async Task <InstallationResultViewModel> PerformOperation(IViewModelService viewModelService, IInstallService installService, INotificationService notificationService, InstallerViewModel installerViewModel, InstallationViewModel currentInstallationViewModel, string installerFilePath, bool enableSilentInstallation, bool disableReboot,
                                                                                 bool enableInstallationLogging, string?logFolderPath = null)
        {
            string?installLogFilePath   = null;
            string?uninstallLogFilePath = null;

            if (enableInstallationLogging)
            {
                if (String.IsNullOrEmpty(logFolderPath))
                {
                    Log.Warn("Installation logging is enabled but the logFolderPath is null or empty.");
                }
                else if (!Directory.Exists(logFolderPath))
                {
                    Log.Warn("logFolderPath is set but the directory doesn't exist.");
                }
                else
                {
                    installLogFilePath   = GetLogFilePathForInstaller(logFolderPath !, installerViewModel.Name ?? "unkown", "install");
                    uninstallLogFilePath = GetLogFilePathForInstaller(logFolderPath !, installerViewModel.Name ?? "unkown", "uninstall");
                }
            }

            var installArguments = GetArguments(
                enableSilentInstallation,
                disableReboot,
                enableInstallationLogging,
                installLogFilePath).ToArray();
            var uninstallArguments = GetArguments(
                enableSilentInstallation,
                disableReboot,
                enableInstallationLogging,
                uninstallLogFilePath).ToArray();

            var installationResultViewModel = viewModelService.CreateViewModel <InstallationResultViewModel>(installerViewModel);

            try
            {
                switch (installerViewModel.SelectedOperation)
                {
                case InstallerOperation.Install:
                    if (installerViewModel.IsInstalled != false)
                    {
                        if (installerViewModel.IsInstalled == null)
                        {
                            Log.Warn($"Installation status of file \"{installerViewModel.FileName}\" is unavailable, trying to uninstall.");
                        }
                        else
                        {
                            Log.Info($"The application \"{installerViewModel.Name}\" with ProductCode \"{installerViewModel.ProductCode}\" is already installed. It will now be uninstalled first.");
                        }

                        if (String.IsNullOrWhiteSpace(installerViewModel.ProductCode))
                        {
                            var exception = new Exception($"Uninstalling \"{installerViewModel.FileName}\" failed: ProductCode is not set.");
                            Log.Error(exception);
                            if (installerViewModel.IsInstalled == true)
                            {
                                return(CreateInstallationFailedResult(viewModelService, installerViewModel, exception));
                            }
                        }
                        else
                        {
                            Log.Info($"Uninstalling application of installer \"{installerViewModel.FileName}\" now.");
                            currentInstallationViewModel.CurrentOperation = InstallationOperation.Uninstall;

                            if (enableInstallationLogging && uninstallLogFilePath is string)
                            {
                                installationResultViewModel.InstallationLogFilePaths.Add(uninstallLogFilePath);
                            }

                            try
                            {
                                await installService.PerformAsync(new Operation(installerViewModel.ProductCode, OperationType.Uninstall, uninstallArguments));

                                Log.Info($"Finished uninstalling.");
                            }
                            catch (Exception exception)
                            {
                                // suppress exception if installation status is unknown
                                if (installerViewModel.IsInstalled == true)
                                {
                                    throw;
                                }

                                Log.Warn("Uninstalling failed, but since the installation state is unavailable, the operation will continue", exception);
                            }
                        }
                    }

                    Log.Info($"Installing \"{installerViewModel.FileName}\" now.");
                    currentInstallationViewModel.CurrentOperation = InstallationOperation.Install;
                    if (enableInstallationLogging && installLogFilePath is string)
                    {
                        installationResultViewModel.InstallationLogFilePaths.Add(installLogFilePath);
                    }
                    await installService.PerformAsync(new Operation(installerFilePath, OperationType.Install, installArguments));

                    Log.Info($"Finished installing.");
                    installationResultViewModel.State = InstallationResultState.Success;
                    break;

                case InstallerOperation.Uninstall:
                    if (installerViewModel.IsInstalled == null)
                    {
                        Log.Warn($"Installation status of file \"{installerViewModel.FileName}\" is unavailable, trying to uninstall.");
                    }
                    else if (installerViewModel.IsInstalled == false)
                    {
                        Log.Warn($"The application \"{installerViewModel.Name}\" with ProductCode \"{installerViewModel.ProductCode}\" is not installed. Trying to uninstall anyways but it will likely fail.");
                    }
                    else
                    {
                        Log.Info($"The application \"{installerViewModel.Name}\" with ProductCode \"{installerViewModel.ProductCode}\" will now be uninstalled.");
                    }

                    if (String.IsNullOrWhiteSpace(installerViewModel.ProductCode))
                    {
                        var exception = new Exception($"Uninstalling \"{installerViewModel.FileName}\" failed: ProductCode is not set.");
                        Log.Error(exception);
                        return(CreateInstallationFailedResult(viewModelService, installerViewModel, exception));
                    }

                    Log.Info($"Uninstalling application of installer \"{installerViewModel.FileName}\" now.");
                    currentInstallationViewModel.CurrentOperation = InstallationOperation.Uninstall;
                    if (enableInstallationLogging && uninstallLogFilePath is string)
                    {
                        installationResultViewModel.InstallationLogFilePaths.Add(uninstallLogFilePath);
                    }
                    await installService.PerformAsync(new Operation(installerViewModel.ProductCode, OperationType.Uninstall, uninstallArguments));

                    Log.Info($"Finished uninstalling.");
                    installationResultViewModel.State = InstallationResultState.Success;
                    break;

                default:
                    installationResultViewModel.State = InstallationResultState.Skipped;
                    break;
                }
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception exception)
            {
                Log.Error(exception);
                var errorMessage = installerViewModel.SelectedOperation switch
                {
                    InstallerOperation.Install => Strings.InstallationOfXFailed,
                    InstallerOperation.Uninstall => Strings.UninstallationOfXFailed,
                    _ => Strings.OperationOfXFailed,
                };
                notificationService.ShowError(String.Format(errorMessage, installerViewModel.Name));
                return(CreateInstallationFailedResult(viewModelService, installerViewModel, exception));
            }
#pragma warning restore CA1031 // Do not catch general exception types

            return(installationResultViewModel);
        }