/// <summary> /// Save the report to a temp file /// </summary> /// <returns>The path to the saved temp file.</returns> private static string GetReportTempPath(ToolMacroInfo toolMacroInfo) { SrmDocument doc = toolMacroInfo.Doc; string reportName = toolMacroInfo.ReportName; string toolTitle = toolMacroInfo.ToolTitle; if (String.IsNullOrEmpty(reportName)) { throw new Exception(string.Format(Resources.ToolMacros_GetReportTempPath_The_selected_tool_0_requires_a_selected_report_Please_select_a_report_for_this_tool_, toolTitle)); } var tempFilePath = GetReportTempPath(reportName, toolTitle); try { using (var saver = new FileSaver(tempFilePath)) { if (!saver.CanSave()) { throw new IOException(); } using (var writer = new StreamWriter(saver.SafeName)) { ToolDescriptionHelpers.GetReport(doc, reportName, toolTitle, toolMacroInfo.ProgressMonitor, writer); } saver.Commit(); return(tempFilePath); } } catch (Exception) { throw new IOException(Resources.ToolMacros_GetReportTempPath_Error_exporting_the_report__tool_execution_canceled_); } }
private void PostToLinkBackground(string url, SrmDocument doc, IProgressMonitor progressMonitor, IWebHelpers webHelpers) { StringWriter report = new StringWriter(); ToolDescriptionHelpers.GetReport(doc, ReportTitle, Title, progressMonitor, report); webHelpers.PostToLink(url, report.ToString()); }
private void PostToLinkBackground(string url, SrmDocument doc, IProgressMonitor progressMonitor, IWebHelpers webHelpers) { string report = ToolDescriptionHelpers.GetReport(doc, ReportTitle, Title, progressMonitor); if (report != null) { webHelpers.PostToLink(url, report); } }
/// <summary> /// Removes any old folders in the ToolDir that dont have tools associated with them /// For the case where we have used a dll and couldn't delete it in some past instance of Skyline. /// </summary> public static void CheckToolDirConsistency() { var referencedPaths = Settings.Default.ToolList.Where(t => !string.IsNullOrEmpty(t.ToolDirPath)) .Select(t => t.ToolDirPath).ToArray(); string toolsDir = ToolDescriptionHelpers.GetToolsDirectory(); if (string.IsNullOrEmpty(toolsDir) || !Directory.Exists(toolsDir)) { return; } foreach (var folder in Directory.EnumerateDirectories(toolsDir)) { if (!referencedPaths.Contains(folder)) { DirectoryEx.SafeDelete(folder); } } }
/// <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); }
/// <summary> /// Method used to encapsulate the running of a executable for threading. /// </summary> /// <param name="document"> Contains the document to base reports off of, as well as to serve as the parent for args collector forms. </param> /// <param name="toolMacroProvider"> Interface for determining what to replace macros with. </param> /// <param name="textWriter"> A textWriter to write to if outputting to the immediate window. </param> /// <param name="progressMonitor"> Progress monitor. </param> /// <param name="parent">If there is an Args Collector form, it will be showed on this control. Can be null. </param> private void RunExecutableBackground(SrmDocument document, IToolMacroProvider toolMacroProvider, TextWriter textWriter, IProgressMonitor progressMonitor, Control parent) { // Need to know if $(InputReportTempPath) is an argument to determine if a report should be piped to stdin or not. bool containsInputReportTempPath = Arguments.Contains(ToolMacros.INPUT_REPORT_TEMP_PATH); string command = GetCommand(document, toolMacroProvider, progressMonitor); if (command == null) // Has already thrown the error. { return; } string args = GetArguments(document, toolMacroProvider, progressMonitor); string initDir = GetInitialDirectory(document, toolMacroProvider, progressMonitor); // If either of these fails an Exception is thrown. if (args != null && initDir != null) { ProcessStartInfo startInfo = new ProcessStartInfo(command, args) { WorkingDirectory = initDir }; if (OutputToImmediateWindow) { startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.StandardOutputEncoding = Encoding.UTF8; startInfo.StandardErrorEncoding = Encoding.UTF8; } // if it has a selected report title and its doesn't have a InputReportTempPath macro then the report needs to be piped to stdin. string reportCsv = null; if (!string.IsNullOrEmpty(ReportTitle) && !containsInputReportTempPath) // Then pipe to stdin. { reportCsv = ToolDescriptionHelpers.GetReport(document, ReportTitle, Title, progressMonitor); startInfo.RedirectStandardInput = true; } //Consider: Maybe throw an error if one is not null but the other is? //If there is an IToolArgsCollector run it! if (!string.IsNullOrEmpty(ArgsCollectorDllPath) && !string.IsNullOrEmpty(ArgsCollectorClassName)) { string pathReportCsv = !string.IsNullOrEmpty(ReportTitle) && containsInputReportTempPath ? ToolMacros.GetReportTempPath(ReportTitle, Title) : null; if (!CallArgsCollector(parent, args, reportCsv, pathReportCsv, startInfo)) { return; } } Process p = new Process { StartInfo = startInfo }; if (OutputToImmediateWindow) { p.EnableRaisingEvents = true; TextBoxStreamWriterHelper boxStreamWriterHelper = textWriter as TextBoxStreamWriterHelper; if (boxStreamWriterHelper == null) { p.OutputDataReceived += (sender, dataReceivedEventArgs) => textWriter.WriteLine(p.Id + ">" + dataReceivedEventArgs.Data); // Not L10N p.ErrorDataReceived += (sender, dataReceivedEventArgs) => textWriter.WriteLine(p.Id + ">" + dataReceivedEventArgs.Data); // Not L10N } else { p.OutputDataReceived += (sender, dataReceivedEventArgs) => boxStreamWriterHelper.WriteLineWithIdentifier(p.Id, dataReceivedEventArgs.Data); p.ErrorDataReceived += (sender, dataReceivedEventArgs) => boxStreamWriterHelper.WriteLineWithIdentifier(p.Id, dataReceivedEventArgs.Data); //p.Refresh(); p.Exited += (sender, processExitedEventArgs) => boxStreamWriterHelper.HandleProcessExit(p.Id); } } // else // { // startInfo.RedirectStandardOutput = true; // startInfo.RedirectStandardError = true; // startInfo.CreateNoWindow = true; // startInfo.UseShellExecute = false; // p.EnableRaisingEvents = true; // p.OutputDataReceived += // (sender, dataReceivedEventArgs) => Console.WriteLine(dataReceivedEventArgs.Data); // p.ErrorDataReceived += // (sender, dataReceivedEventArgs) => Console.WriteLine(dataReceivedEventArgs.Data); // } try { p.StartInfo.UseShellExecute = false; p.Start(); if (OutputToImmediateWindow) { p.BeginOutputReadLine(); p.BeginErrorReadLine(); } // write the reportCsv string to stdin. // need to only check one of these conditions. if (startInfo.RedirectStandardInput && (reportCsv != null)) { StreamWriter streamWriter = p.StandardInput; streamWriter.Write(reportCsv); streamWriter.Flush(); streamWriter.Close(); } } catch (Exception ex) { if (ex is Win32Exception) { throw new ToolExecutionException( TextUtil.LineSeparate( Resources.ToolDescription_RunTool_File_not_found_, Resources.ToolDescription_RunTool_Please_check_the_command_location_is_correct_for_this_tool_), ex); } else { throw new ToolExecutionException( TextUtil.LineSeparate( Resources.ToolDescription_RunTool_Please_reconfigure_that_tool__it_failed_to_execute__, ex.Message), ex); } } // CONSIDER: We don't delete the temp path here, because the file may be open // in a long running application like Excel. // if (ReportTempPath_toDelete != null) // { // FileEx.SafeDelete(ReportTempPath_toDelete, true); // ReportTempPath_toDelete = null; // } } }