Example #1
0
        private static ToolInfo GetToolInfo(DirectoryInfo toolInf, UnzipToolReturnAccumulator accumulator)
        {
            var    toolInfo = new ToolInfo();
            string infoFile = Path.Combine(toolInf.FullName, INFO_PROPERTIES);

            if (File.Exists(infoFile))
            {
                ExternalToolProperties readin;
                try
                {
                    readin = new ExternalToolProperties(infoFile);
                }
                catch (Exception)
                {
                    // Failed to read the .properties file
                    throw new ToolExecutionException(string.Format(Resources.ToolInstaller_GetToolInfo_Failed_to_process_the__0__file, INFO_PROPERTIES));
                }

                toolInfo.SetPackageVersion(readin.Version);
                toolInfo.SetPackageIdentifier(readin.Identifier);
                toolInfo.SetPackageName(readin.Name);

                //Check for Package Installation specified in info.properties
                var ppc = ToolMacros.GetProgramPathContainer(readin.Command);
                if (ppc != null)
                {
                    FindPackagesToInstall(readin, accumulator, ppc);
                }
            }
            else //No info.properties file in the tool-inf directory.
            {
                throw new ToolExecutionException(TextUtil.LineSeparate(
                                                     Resources.ToolInstaller_UnpackZipTool_The_selected_zip_file_is_not_a_valid_installable_tool_,
                                                     string.Format(Resources.ToolInstaller_GetToolInfo_Error__It_does_not_contain_the_required__0__in_the__1__directory_,
                                                                   INFO_PROPERTIES, TOOL_INF)));
            }
            return(toolInfo);
        }
Example #2
0
        private static void FindPackagesToInstall(ExternalToolProperties readin,
                                                  UnzipToolReturnAccumulator accumulator,
                                                  ProgramPathContainer programPathContainer)
        {
            var packages = new List <ToolPackage>();
            int i        = 1;
            var package  = readin.GetPackageWithVersion(i);

            while (package != null)
            {
                // if the package is not a uri, it is stored locally in the tool-inf directory
                //if (!package.StartsWith("http"))
                //    package = Path.Combine(tempToolPath, TOOL_INF, package);

                packages.Add(package);
                package = readin.GetPackageWithVersion(++i);
            }

            if (!Settings.Default.ToolFilePaths.ContainsKey(programPathContainer) || packages.Count > 0)
            {
                accumulator.AddInstallation(programPathContainer, packages);
            }
        }
Example #3
0
        private static string ProcessCommand(ExternalToolProperties readin, string tempToolPath, UnzipToolReturnAccumulator accumulator)
        {
            string command = readin.Command.Trim();
            var    programPathContainer = ToolMacros.GetProgramPathContainer(command);

            if (!ToolDescription.IsWebPageCommand(command) && programPathContainer == null)
            {
                // ReSharper disable once LocalizableElement
                if (command.StartsWith(ToolMacros.TOOL_DIR + "\\"))
                {
                    command = command.Substring(ToolMacros.TOOL_DIR.Length + 1);
                }
                if (!File.Exists(Path.Combine(tempToolPath, command)))
                {
                    accumulator.AddMessage(string.Format(Resources.ToolInstaller_AddToolFromProperties_Missing_the_file__0___Tool__1__import_failed, command, readin.Title));
                    return(null);
                }
                command = Path.Combine(ToolMacros.TOOL_DIR, command);
            }
            else if (programPathContainer != null) // If it is a ProgramPath macro
            {
                FindPackagesToInstall(readin, accumulator, programPathContainer);
            }
            return(command);
        }
Example #4
0
        private static void AddToolFromProperties(FileInfo file,
                                                  UnzipToolReturnAccumulator accumulator,
                                                  ToolInfo toolInfo,
                                                  string placeHolderToolPath,
                                                  string tempToolPath,
                                                  IDictionary <string, string> reportRenameMapping)
        {
            if (file.Name == INFO_PROPERTIES)
            {
                return;
            }

            ExternalToolProperties readin;

            try
            {
                readin = new ExternalToolProperties(file.FullName);
            }
            catch (Exception)
            {
                //Failed to read the .properties file
                accumulator.AddMessage(string.Format(Resources.ConfigureToolsDlg_unpackZipTool_Failed_to_process_file_0_The_tool_described_failed_to_import,
                                                     file.Name));
                return;
            }
            if (readin.Title == null || readin.Command == null)
            {
                accumulator.AddMessage(string.Format(TextUtil.LineSeparate(
                                                         Resources.ConfigureToolsDlg_unpackZipTool_Invalid_Tool_Description_in_file__0__,
                                                         Resources.ConfigureToolsDlg_unpackZipTool_Title_and_Command_are_required,
                                                         Resources.ConfigureToolsDlg_unpackZipTool_skipping_that_tool_), file.Name));
                return;
            }

            string command = ProcessCommand(readin, tempToolPath, accumulator);

            if (string.IsNullOrEmpty(command))
            {
                return;
            }

            string reportTitle = readin.Input_Report_Name;
            List <AnnotationDef> annotations = new List <AnnotationDef>();

            // Check we have the relevant report
            if (!string.IsNullOrWhiteSpace(reportTitle))
            {
                if (reportRenameMapping.ContainsKey(reportTitle))
                {
                    //Apply report renaming if install in parallel was selectedd
                    reportTitle = reportRenameMapping[reportTitle];
                }
                // Check if they are still missing the report they want
                if (!ReportSharing.GetExistingReports().ContainsKey(PersistedViews.ExternalToolsGroup.Id.ViewName(reportTitle)))
                {
                    accumulator.AddMessage(string.Format(Resources.UnpackZipToolHelper_UnpackZipTool_The_tool___0___requires_report_type_titled___1___and_it_is_not_provided__Import_canceled_,
                                                         readin.Title, reportTitle));
                    return;
                }
                // Get annotations for this specific tool
                GetAnotations(readin, annotations);
            }
            //Check the ArgsCollector Dll exists.
            string dllPath = readin.Args_Collector_Dll;

            if (!string.IsNullOrEmpty(dllPath))
            {
                // Handle case where they prepended the DllPath with $(ToolDir)\\.
                // ReSharper disable once LocalizableElement
                if (dllPath.StartsWith(ToolMacros.TOOL_DIR + "\\"))
                {
                    dllPath = dllPath.Substring(ToolMacros.TOOL_DIR.Length + 1);
                }
                if (!File.Exists(Path.Combine(tempToolPath, dllPath)))
                {
                    accumulator.AddMessage(string.Format(Resources.ToolInstaller_AddToolFromProperties_Missing_the_file__0___Tool__1__import_failed, dllPath,
                                                         readin.Title));
                    return;
                }
                // Path to the dll gets renamed at the end of the UnpackZipTools Function when we
                // finally decide the directory for the $(ToolDir)
            }

            //Make sure tools get a unique title.
            string uniqueTitle = GetUniqueToolTitle(readin.Title);

            //Append each tool to the return value
            accumulator.AddTool(new ToolDescription(uniqueTitle,
                                                    command,
                                                    readin.Arguments,
                                                    readin.Initial_Directory,
                                                    readin.Output_to_Immediate_Window.Contains(@"True"),
                                                    reportTitle,
                                                    dllPath,
                                                    readin.Args_Collector_Type,
                                                    placeHolderToolPath,
                                                    annotations,
                                                    toolInfo.PackageVersion,
                                                    toolInfo.PackageIdentifier,
                                                    toolInfo.PackageName));
        }
Example #5
0
        /// <summary>
        /// Function for unpacking zipped External tools.
        /// </summary>
        /// <param name="pathToZip">Path to the zipped file that contains the tool and all its assicaited files.</param>
        /// <param name="unpackSupport"> Interface that implements required functions that are dependent on context.</param>
        /// <returns></returns>
        public static UnzipToolReturnAccumulator UnpackZipTool(string pathToZip, IUnpackZipToolSupport unpackSupport)
        {
            if (!Directory.Exists(pathToZip) && !File.Exists(pathToZip))
            {
                throw new FileNotFoundException(pathToZip);
            }

            //Removes any old folders that dont have Tools associated with them
            CheckToolDirConsistency();

            var    retval = new UnzipToolReturnAccumulator();
            string name   = Path.GetFileNameWithoutExtension(pathToZip);

            if (name == null)
            {
                throw new ToolExecutionException(Resources.ConfigureToolsDlg_unpackZipTool_Invalid_file_selected__No_tools_added_);
            }
            // This helps with zipfiles that have spaces in the titles.
            // Consider: We may want to add quotes around usages of the $(ToolDir) macro incase the Tool directory has spaces in one of its directory names.
            name = name.Replace(' ', '_');

            string outerToolsFolderPath = ToolDescriptionHelpers.GetToolsDirectory();

            if (string.IsNullOrEmpty(outerToolsFolderPath))
            {
                throw new ToolExecutionException(Resources.ConfigureToolsDlg_unpackZipTool_Error_unpacking_zipped_tools);
            }
            string tempFolderPath = Path.Combine(outerToolsFolderPath, @"Temp");

            var toolDir = new DirectoryInfo(tempFolderPath);

            if (!toolDir.Exists)
            {
                toolDir.Create();
            }

            // This naming conflict shouldn't happen. The temp file should be empty.
            // Consider: Try to delete the existing directory in the temp directory.
            string tempToolPath = Path.Combine(tempFolderPath, name);

            if (Directory.Exists(tempToolPath))
            {
                tempToolPath = DirectoryEx.GetUniqueName(tempToolPath);
            }

            using (new TemporaryDirectory(tempToolPath))
            {
                if (Directory.Exists(pathToZip))
                {
                    DirectoryCopy(pathToZip, tempToolPath);
                }
                else
                {
                    using (var zipFile = new ZipFile(pathToZip))
                    {
                        try
                        {
                            zipFile.ExtractAll(tempToolPath, ExtractExistingFileAction.OverwriteSilently);
                        }
                        catch (Exception)
                        {
                            throw new ToolExecutionException(Resources.ConfigureToolsDlg_unpackZipTool_There_is_a_naming_conflict_in_unpacking_the_zip__Tool_importing_canceled_);
                        }
                    }
                }

                var dirInfo = new DirectoryInfo(tempToolPath);
                if (!dirInfo.Exists)
                {
                    // Case where they try to load tools from an empty zipfile then the folder is never created.
                    dirInfo.Create();
                }

                var toolInfDir = new DirectoryInfo(Path.Combine(tempToolPath, TOOL_INF));
                if (!toolInfDir.Exists)
                {
                    throw new ToolExecutionException(TextUtil.LineSeparate(
                                                         Resources.ToolInstaller_UnpackZipTool_The_selected_zip_file_is_not_an_installable_tool_,
                                                         string.Format(Resources.ToolInstaller_UnpackZipTool_Error__It_does_not_contain_the_required__0__directory_, TOOL_INF)));
                }

                // Handle info.properties
                var toolInfo = GetToolInfo(toolInfDir, retval);

                if (!HandleAnnotations(unpackSupport.ShouldOverwriteAnnotations, toolInfDir))
                {
                    return(null);
                }

                HandleLegacyQuaSAR(toolInfo);

                var toolsToBeOverwritten = GetToolsToBeOverwritten(toolInfo.PackageIdentifier);

                List <ReportOrViewSpec> newReports;
                var existingReports = FindReportConflicts(toolInfDir, tempToolPath, out newReports);

                bool?overwrite = IsOverwrite(unpackSupport.ShouldOverwrite, toolsToBeOverwritten, existingReports, toolInfo);
                if (!overwrite.HasValue)
                {
                    // User canceled installation.
                    return(null);
                }
                string DirectoryToRemove = null;
                if (overwrite.Value)
                {
                    // Delete the tools and their containing folder
                    if (toolsToBeOverwritten.Count > 0)
                    {
                        foreach (var tool in toolsToBeOverwritten)
                        {
                            Settings.Default.ToolList.Remove(tool);
                        }
                        // The tools are all guarenteed to be from the same directory by GetToolsToBeOverwritten
                        // and all toolDescriptions in a directory come from the same installation
                        DirectoryToRemove = toolsToBeOverwritten.First().ToolDirPath;
                    }

                    // Overwrite all existing reports.
                    foreach (ReportOrViewSpec item in existingReports)
                    {
                        ReportSharing.SaveReport(PersistedViews.ExternalToolsGroup, item);
                    }
                }

                // Add all new reports.
                foreach (ReportOrViewSpec item in newReports)
                {
                    ReportSharing.SaveReport(PersistedViews.ExternalToolsGroup, item);
                }
                var reportRenameMapping = new Dictionary <string, string>();
                if (overwrite == false) // Dont overwrite so rename reports.
                {
                    // Deal with renaming reports!
                    foreach (ReportOrViewSpec item in existingReports)
                    {
                        string oldname = item.GetKey();
                        string newname = GetUniqueReportName(oldname);
                        reportRenameMapping.Add(oldname, newname);
                        ReportSharing.SaveReportAs(PersistedViews.ExternalToolsGroup, item, newname);
                    }
                }

                foreach (FileInfo file in toolInfDir.GetFiles(@"*.properties"))
                {
                    // We will replace the tool Directory value (null below) later when we know the import is sucessful.
                    AddToolFromProperties(file, retval, toolInfo, null, tempToolPath, reportRenameMapping);
                }

                // Check if we need to install a program
                if (retval.Installations.Count > 0)
                {
                    foreach (var ppc in retval.Installations.Keys)
                    {
                        string pathToPackageInstallScript = null;
                        if (ppc.ProgramName.Equals(@"R") && retval.Installations[ppc].Count != 0)
                        {
                            pathToPackageInstallScript = Path.Combine(tempToolPath, TOOL_INF, INSTALL_R_PACKAGES);
                            if (!File.Exists(pathToPackageInstallScript))
                            {
                                throw new ToolExecutionException(TextUtil.LineSeparate(string.Format(Resources.ToolInstaller_UnpackZipTool_Error__There_is_a_file_missing_the__0__zip, name),
                                                                                       string.Empty,
                                                                                       string.Format(Resources.ToolInstaller_UnpackZipTool_Tool_Uses_R_and_specifies_Packages_without_an__0__file_in_the_tool_inf_directory_, INSTALL_R_PACKAGES)));
                            }
                        }

                        string path = unpackSupport.InstallProgram(ppc, retval.Installations[ppc], pathToPackageInstallScript);
                        if (path == null)
                        {
                            // Cancel installation
                            return(null);
                        }
                        else if (path != string.Empty)
                        {
                            if (Settings.Default.ToolFilePaths.ContainsKey(ppc))
                            {
                                Settings.Default.ToolFilePaths.Remove(ppc);
                            }
                            Settings.Default.ToolFilePaths.Add(ppc, path);
                        }
                    }
                }
                // We don't decide the final toolDirPath until we make it to here.
                // This will require some fixing of the tooldir and path to dll in each of the tools in retval.validtoolsfound
                // It also enables us to not delete the tools from the tool list unless we have a sucessful installation.

                // Decide the permToolPath.
                if (DirectoryToRemove != null)
                {
                    DirectoryEx.SafeDelete(DirectoryToRemove);
                }

                // Final Directory Location.
                string permToolPath = DirectoryEx.GetUniqueName(Path.Combine(outerToolsFolderPath, name));

                foreach (var tool in retval.ValidToolsFound)
                {
                    tool.ToolDirPath = permToolPath;
                    if (!string.IsNullOrEmpty(tool.ArgsCollectorDllPath))
                    {
                        tool.ArgsCollectorDllPath = Path.Combine(permToolPath, tool.ArgsCollectorDllPath);
                    }
                    Settings.Default.ToolList.Add(tool);
                }

                if (retval.ValidToolsFound.Count != 0)
                {
                    Helpers.TryTwice(() => Directory.Move(tempToolPath, permToolPath));
                }
            }
            return(retval);
        }
Example #6
0
 private static string ProcessCommand(ExternalToolProperties readin, string tempToolPath, UnzipToolReturnAccumulator accumulator)
 {
     string command = readin.Command.Trim();
     var programPathContainer = ToolMacros.GetProgramPathContainer(command);
     if (!ToolDescription.IsWebPageCommand(command) && programPathContainer == null)
     {
         if (command.StartsWith(ToolMacros.TOOL_DIR + "\\")) // Not L10N
         {
             command = command.Substring(ToolMacros.TOOL_DIR.Length + 1);
         }
         if (!File.Exists(Path.Combine(tempToolPath, command)))
         {
             accumulator.AddMessage(string.Format(Resources.ToolInstaller_AddToolFromProperties_Missing_the_file__0___Tool__1__import_failed, command, readin.Title));
             return null;
         }
         command = Path.Combine(ToolMacros.TOOL_DIR, command);
     }
     else if (programPathContainer != null) // If it is a ProgramPath macro
     {
         FindPackagesToInstall(readin, accumulator, programPathContainer);
     }
     return command;
 }
Example #7
0
        private static ToolInfo GetToolInfo(DirectoryInfo toolInf, UnzipToolReturnAccumulator accumulator)
        {
            var toolInfo = new ToolInfo();
            string infoFile = Path.Combine(toolInf.FullName, INFO_PROPERTIES);
            if (File.Exists(infoFile))
            {
                ExternalToolProperties readin;
                try
                {
                    readin = new ExternalToolProperties(infoFile);
                }
                catch (Exception)
                {
                    // Failed to read the .properties file
                    throw new ToolExecutionException(string.Format(Resources.ToolInstaller_GetToolInfo_Failed_to_process_the__0__file, INFO_PROPERTIES));
                }

                toolInfo.SetPackageVersion(readin.Version);
                toolInfo.SetPackageIdentifier(readin.Identifier);
                toolInfo.SetPackageName(readin.Name);

                //Check for Package Installation specified in info.properties
                var ppc = ToolMacros.GetProgramPathContainer(readin.Command);
                if (ppc != null)
                {
                    FindPackagesToInstall(readin, accumulator, ppc);
                }

            }
            else //No info.properties file in the tool-inf directory.
            {
                throw new ToolExecutionException(TextUtil.LineSeparate(
                    Resources.ToolInstaller_UnpackZipTool_The_selected_zip_file_is_not_a_valid_installable_tool_,
                    string.Format(Resources.ToolInstaller_GetToolInfo_Error__It_does_not_contain_the_required__0__in_the__1__directory_,
                                  INFO_PROPERTIES, TOOL_INF)));
            }
            return toolInfo;
        }
Example #8
0
        private static void FindPackagesToInstall(ExternalToolProperties readin,
            UnzipToolReturnAccumulator accumulator,
            ProgramPathContainer programPathContainer)
        {
            var packages = new List<ToolPackage>();
            int i = 1;
            var package = readin.GetPackageWithVersion(i);
            while (package != null)
            {
                // if the package is not a uri, it is stored locally in the tool-inf directory
                //if (!package.StartsWith("http")) // Not L10N
                //    package = Path.Combine(tempToolPath, TOOL_INF, package);

                packages.Add(package);
                package = readin.GetPackageWithVersion(++i);
            }

            if (!Settings.Default.ToolFilePaths.ContainsKey(programPathContainer) || packages.Count > 0)
                accumulator.AddInstallation(programPathContainer, packages);
        }
Example #9
0
        private static void AddToolFromProperties(FileInfo file,
            UnzipToolReturnAccumulator accumulator,
            ToolInfo toolInfo,
            string placeHolderToolPath,
            string tempToolPath,
            IDictionary<string, string> reportRenameMapping)
        {
            if (file.Name == INFO_PROPERTIES)
                return;

            ExternalToolProperties readin;
            try
            {
                readin = new ExternalToolProperties(file.FullName);
            }
            catch (Exception)
            {
                //Failed to read the .properties file
                accumulator.AddMessage(string.Format(Resources.ConfigureToolsDlg_unpackZipTool_Failed_to_process_file_0_The_tool_described_failed_to_import,
                                                     file.Name));
                return;
            }
            if (readin.Title == null || readin.Command == null)
            {
                accumulator.AddMessage(string.Format(TextUtil.LineSeparate(
                    Resources.ConfigureToolsDlg_unpackZipTool_Invalid_Tool_Description_in_file__0__,
                    Resources.ConfigureToolsDlg_unpackZipTool_Title_and_Command_are_required,
                    Resources.ConfigureToolsDlg_unpackZipTool_skipping_that_tool_), file.Name));
                return;
            }

            string command = ProcessCommand(readin, tempToolPath, accumulator);
            if (string.IsNullOrEmpty(command))
                return;

            string reportTitle = readin.Input_Report_Name;
            List<AnnotationDef> annotations = new List<AnnotationDef>();
            // Check we have the relevant report
            if (!string.IsNullOrWhiteSpace(reportTitle))
            {
                if (reportRenameMapping.ContainsKey(reportTitle))
                {
                    //Apply report renaming if install in parallel was selectedd
                    reportTitle = reportRenameMapping[reportTitle];
                }
                // Check if they are still missing the report they want
                if (!ReportSharing.GetExistingReports().ContainsKey(PersistedViews.ExternalToolsGroup.Id.ViewName(reportTitle)))
                {
                    accumulator.AddMessage(string.Format(Resources.UnpackZipToolHelper_UnpackZipTool_The_tool___0___requires_report_type_titled___1___and_it_is_not_provided__Import_canceled_,
                                                         readin.Title, reportTitle));
                    return;
                }
                // Get annotations for this specific tool
                GetAnotations(readin, annotations);
            }
            //Check the ArgsCollector Dll exists.
            string dllPath = readin.Args_Collector_Dll;
            if (!string.IsNullOrEmpty(dllPath))
            {
                // Handle case where they prepended the DllPath with $(ToolDir)\\.
                if (dllPath.StartsWith(ToolMacros.TOOL_DIR + "\\")) // Not L10N
                {
                    dllPath = dllPath.Substring(ToolMacros.TOOL_DIR.Length + 1);
                }
                if (!File.Exists(Path.Combine(tempToolPath, dllPath)))
                {
                    accumulator.AddMessage(string.Format(Resources.ToolInstaller_AddToolFromProperties_Missing_the_file__0___Tool__1__import_failed, dllPath,
                                                         readin.Title));
                    return;
                }
                // Path to the dll gets renamed at the end of the UnpackZipTools Function when we
                // finally decide the directory for the $(ToolDir)
            }

            //Make sure tools get a unique title.
            string uniqueTitle = GetUniqueToolTitle(readin.Title);

            //Append each tool to the return value
            accumulator.AddTool(new ToolDescription(uniqueTitle,
                                               command,
                                               readin.Arguments,
                                               readin.Initial_Directory,
                                               readin.Output_to_Immediate_Window.Contains("True"), // Not L10N
                                               reportTitle,
                                               dllPath,
                                               readin.Args_Collector_Type,
                                               placeHolderToolPath,
                                               annotations,
                                               toolInfo.PackageVersion,
                                               toolInfo.PackageIdentifier,
                                               toolInfo.PackageName));
        }
Example #10
0
        /// <summary>
        /// Function for unpacking zipped External tools.
        /// </summary>
        /// <param name="pathToZip">Path to the zipped file that contains the tool and all its assicaited files.</param>        
        /// <param name="unpackSupport"> Interface that implements required functions that are dependent on context.</param>
        /// <returns></returns>
        public static UnzipToolReturnAccumulator UnpackZipTool(string pathToZip, IUnpackZipToolSupport unpackSupport)
        {
            if (!Directory.Exists(pathToZip) && !File.Exists(pathToZip))
                throw new FileNotFoundException(pathToZip);

            //Removes any old folders that dont have Tools associated with them
            CheckToolDirConsistency();

            var retval = new UnzipToolReturnAccumulator();
            string name = Path.GetFileNameWithoutExtension(pathToZip);
            if (name == null)
            {
                throw new ToolExecutionException(Resources.ConfigureToolsDlg_unpackZipTool_Invalid_file_selected__No_tools_added_);
            }
            // This helps with zipfiles that have spaces in the titles.
            // Consider: We may want to add quotes around usages of the $(ToolDir) macro incase the Tool directory has spaces in one of its directory names.
            name = name.Replace(' ', '_');

            string outerToolsFolderPath = ToolDescriptionHelpers.GetToolsDirectory();
            if (string.IsNullOrEmpty(outerToolsFolderPath))
            {
                throw new ToolExecutionException(Resources.ConfigureToolsDlg_unpackZipTool_Error_unpacking_zipped_tools);
            }
            string tempFolderPath = Path.Combine(outerToolsFolderPath, "Temp"); // Not L10N

            var toolDir = new DirectoryInfo(tempFolderPath);
            if (!toolDir.Exists)
                toolDir.Create();

            // This naming conflict shouldn't happen. The temp file should be empty.
            // Consider: Try to delete the existing directory in the temp directory.
            string tempToolPath = Path.Combine(tempFolderPath, name);
            if (Directory.Exists(tempToolPath))
                tempToolPath = DirectoryEx.GetUniqueName(tempToolPath);

            using (new TemporaryDirectory(tempToolPath))
            {
                if (Directory.Exists(pathToZip))
                {
                    DirectoryCopy(pathToZip, tempToolPath);
                }
                else using (var zipFile = new ZipFile(pathToZip))
                {
                    try
                    {
                        zipFile.ExtractAll(tempToolPath, ExtractExistingFileAction.OverwriteSilently);
                    }
                    catch (Exception)
                    {
                        throw new ToolExecutionException(Resources.ConfigureToolsDlg_unpackZipTool_There_is_a_naming_conflict_in_unpacking_the_zip__Tool_importing_canceled_);
                    }
                }

                var dirInfo = new DirectoryInfo(tempToolPath);
                if (!dirInfo.Exists)
                    // Case where they try to load tools from an empty zipfile then the folder is never created.
                    dirInfo.Create();

                var toolInfDir = new DirectoryInfo(Path.Combine(tempToolPath, TOOL_INF));
                if (!toolInfDir.Exists)
                {
                    throw new ToolExecutionException(TextUtil.LineSeparate(
                            Resources.ToolInstaller_UnpackZipTool_The_selected_zip_file_is_not_an_installable_tool_,
                            string.Format(Resources.ToolInstaller_UnpackZipTool_Error__It_does_not_contain_the_required__0__directory_, TOOL_INF)));
                }

                // Handle info.properties
                var toolInfo = GetToolInfo(toolInfDir, retval);

                if (!HandleAnnotations(unpackSupport.ShouldOverwriteAnnotations, toolInfDir))
                    return null;

                HandleLegacyQuaSAR(toolInfo);

                var toolsToBeOverwritten = GetToolsToBeOverwritten(toolInfo.PackageIdentifier);

                List<ReportOrViewSpec> newReports;
                var existingReports = FindReportConflicts(toolInfDir, tempToolPath, out newReports);

                bool? overwrite = IsOverwrite(unpackSupport.ShouldOverwrite, toolsToBeOverwritten, existingReports, toolInfo);
                if (!overwrite.HasValue)
                {
                    // User canceled installation.
                    return null;
                }
                string DirectoryToRemove = null;
                if (overwrite.Value)
                {
                    // Delete the tools and their containing folder
                    if (toolsToBeOverwritten.Count > 0)
                    {
                        foreach (var tool in toolsToBeOverwritten)
                        {
                            Settings.Default.ToolList.Remove(tool);
                        }
                        // The tools are all guarenteed to be from the same directory by GetToolsToBeOverwritten
                        // and all toolDescriptions in a directory come from the same installation
                        DirectoryToRemove = toolsToBeOverwritten.First().ToolDirPath;
                    }

                    // Overwrite all existing reports.
                    foreach (ReportOrViewSpec item in existingReports)
                    {
                        ReportSharing.SaveReport(PersistedViews.ExternalToolsGroup, item);
                    }
                }

                // Add all new reports.
                foreach (ReportOrViewSpec item in newReports)
                {
                    ReportSharing.SaveReport(PersistedViews.ExternalToolsGroup, item);
                }
                var reportRenameMapping = new Dictionary<string, string>();
                if (overwrite == false) // Dont overwrite so rename reports.
                {
                    // Deal with renaming reports!
                    foreach (ReportOrViewSpec item in existingReports)
                    {
                        string oldname = item.GetKey();
                        string newname = GetUniqueReportName(oldname);
                        reportRenameMapping.Add(oldname, newname);
                        ReportSharing.SaveReportAs(PersistedViews.ExternalToolsGroup, item, newname);
                    }
                }

                foreach (FileInfo file in toolInfDir.GetFiles("*.properties")) // Not L10N
                {
                    // We will replace the tool Directory value (null below) later when we know the import is sucessful.
                    AddToolFromProperties(file, retval, toolInfo, null, tempToolPath, reportRenameMapping);
                }

                // Check if we need to install a program
                if (retval.Installations.Count > 0)
                {
                    foreach (var ppc in retval.Installations.Keys)
                    {
                        string pathToPackageInstallScript = null;
                        if (ppc.ProgramName.Equals("R") && retval.Installations[ppc].Count != 0) // Not L10N
                        {
                            pathToPackageInstallScript = Path.Combine(tempToolPath, TOOL_INF, INSTALL_R_PACKAGES);
                            if (!File.Exists(pathToPackageInstallScript))
                            {
                                throw new ToolExecutionException(TextUtil.LineSeparate(string.Format(Resources.ToolInstaller_UnpackZipTool_Error__There_is_a_file_missing_the__0__zip, name),
                                                                        string.Empty,
                                                                        string.Format(Resources.ToolInstaller_UnpackZipTool_Tool_Uses_R_and_specifies_Packages_without_an__0__file_in_the_tool_inf_directory_, INSTALL_R_PACKAGES)));
                            }
                        }

                        string path = unpackSupport.InstallProgram(ppc, retval.Installations[ppc], pathToPackageInstallScript);
                        if (path == null)
                        {
                            // Cancel installation
                            return null;
                        }
                        else if (path != string.Empty)
                        {
                            if (Settings.Default.ToolFilePaths.ContainsKey(ppc))
                                Settings.Default.ToolFilePaths.Remove(ppc);
                            Settings.Default.ToolFilePaths.Add(ppc, path);
                        }
                    }
                }
                // We don't decide the final toolDirPath until we make it to here.
                // This will require some fixing of the tooldir and path to dll in each of the tools in retval.validtoolsfound
                // It also enables us to not delete the tools from the tool list unless we have a sucessful installation.

                // Decide the permToolPath.
                if (DirectoryToRemove != null)
                    DirectoryEx.SafeDelete(DirectoryToRemove);

                // Final Directory Location.
                string permToolPath = DirectoryEx.GetUniqueName(Path.Combine(outerToolsFolderPath, name));

                foreach (var tool in retval.ValidToolsFound)
                {
                    tool.ToolDirPath = permToolPath;
                    if (!string.IsNullOrEmpty(tool.ArgsCollectorDllPath))
                        tool.ArgsCollectorDllPath = Path.Combine(permToolPath, tool.ArgsCollectorDllPath);
                    Settings.Default.ToolList.Add(tool);
                }

                if (retval.ValidToolsFound.Count != 0)
                {
                    Helpers.TryTwice(() => Directory.Move(tempToolPath, permToolPath));
                }
            }
            return retval;
        }