private bool RunExternalCommand(string Command, DocumentInfo CommandDocument) { m_LastReceivedOutputTime = System.DateTime.Now; string fullCommand = Command; string args = ""; if (Command.StartsWith("\"")) { int nextQuote = Command.IndexOf('"', 1); if (nextQuote == -1) { // invalid file Core.AddToOutput("Invalid command specified (" + Command + ")"); return(false); } fullCommand = Command.Substring(1, nextQuote - 1); args = Command.Substring(nextQuote + 1).Trim(); } else if (Command.IndexOf(' ') != -1) { int spacePos = Command.IndexOf(' '); fullCommand = Command.Substring(0, spacePos); args = Command.Substring(spacePos + 1).Trim(); } fullCommand = "cmd.exe"; bool error = false; bool errorAtArgs = false; string command = Core.MainForm.FillParameters(Command, CommandDocument, false, out error); if (error) { return(false); } args = "/C \"" + command + "\""; args = Core.MainForm.FillParameters(args, CommandDocument, false, out errorAtArgs); if ((error) || (errorAtArgs)) { return(false); } Core.AddToOutput(command + System.Environment.NewLine); m_ExternalProcess = new System.Diagnostics.Process(); m_ExternalProcess.StartInfo.FileName = fullCommand; m_ExternalProcess.StartInfo.WorkingDirectory = Core.MainForm.FillParameters("$(BuildTargetPath)", CommandDocument, false, out error); if (error) { return(false); } if (!System.IO.Directory.Exists(m_ExternalProcess.StartInfo.WorkingDirectory + "/")) { Core.AddToOutput("The determined working directory \"" + m_ExternalProcess.StartInfo.WorkingDirectory + "\" does not exist" + System.Environment.NewLine); return(false); } m_ExternalProcess.StartInfo.CreateNoWindow = true; m_ExternalProcess.EnableRaisingEvents = true; m_ExternalProcess.StartInfo.Arguments = args; m_ExternalProcess.StartInfo.UseShellExecute = false; m_ExternalProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(ExternalProcessOutputReceived); m_ExternalProcess.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(ExternalProcessOutputReceived); m_ExternalProcess.StartInfo.RedirectStandardError = true; m_ExternalProcess.StartInfo.RedirectStandardOutput = true; try { if (!m_ExternalProcess.Start()) { m_ExternalProcess.Close(); return(false); } m_ExternalProcess.BeginOutputReadLine(); m_ExternalProcess.BeginErrorReadLine(); } catch (Win32Exception ex) { m_ExternalProcess.Close(); Core.AddToOutput(ex.Message + System.Environment.NewLine); return(false); } while (!m_ExternalProcess.WaitForExit(5)) { Application.DoEvents(); } // DO NOT REMOVE: final DoEvents to let the app clear its invoke queue to the output display, plus WaitForExit is required so all output is received Application.DoEvents(); m_ExternalProcess.WaitForExit(); bool success = (m_ExternalProcess.ExitCode == 0); if (!success) { Core.AddToOutput("External Command " + command + " exited with result code " + m_ExternalProcess.ExitCode.ToString() + System.Environment.NewLine); } m_ExternalProcess.Close(); return(success); }
public bool NeedsRebuild(DocumentInfo DocInfo, string ConfigSetting) { if (DocInfo == null) { return(false); } lock (DocInfo.DeducedDependency) { // actual parsing and deducing dependencies if a rebuild is necessary! foreach (IDockContent dockContent in Core.MainForm.panelMain.Documents) { BaseDocument baseDoc = (BaseDocument)dockContent; if (baseDoc.Modified) { Core.AddToOutput("Component '" + baseDoc.DocumentInfo.DocumentFilename + "' needs rebuilding." + System.Environment.NewLine); return(true); } } if (DocInfo.Element != null) { foreach (var dependency in DocInfo.Element.ForcedDependency.DependentOnFile) { var project = Core.Navigating.Solution.GetProjectByName(dependency.Project); if (project == null) { Core.AddToOutput("Could not find dependency project " + dependency.Project + " for " + dependency + System.Environment.NewLine); return(true); } ProjectElement elementDependency = project.GetElementByFilename(dependency.Filename); if (elementDependency == null) { Core.AddToOutput("Could not find dependency " + dependency.Filename + " in project " + dependency.Project + " for " + dependency + System.Environment.NewLine); return(true); } if (NeedsRebuild(elementDependency.DocumentInfo, ConfigSetting)) { Core.AddToOutput("Dependency '" + elementDependency.DocumentInfo.DocumentFilename + "' needs rebuilding." + System.Environment.NewLine); return(true); } foreach (var rebuildFile in m_RebuiltFiles) { if (GR.Path.IsPathEqual(elementDependency.DocumentInfo.DocumentFilename, rebuildFile)) { Core.AddToOutput("Dependency " + elementDependency.DocumentInfo.DocumentFilename + " was rebuilt in this cycle, need to rebuild dependent element " + DocInfo.DocumentFilename + System.Environment.NewLine); return(true); } } } if (DocInfo.DeducedDependency[ConfigSetting] != null) { // custom build overrides output file -> always rebuild if ((DocInfo.Element.Settings.ContainsKey(ConfigSetting)) && (!string.IsNullOrEmpty(DocInfo.Element.Settings[ConfigSetting].CustomBuild)) && (!string.IsNullOrEmpty(DocInfo.Element.TargetFilename))) { Core.AddToOutput("Custom build always requires a rebuild" + System.Environment.NewLine); return(true); } foreach (var dependency in DocInfo.Element.ExternalDependencies.DependentOnFile) { string fullPath = BuildFullPath(DocInfo.Project.Settings.BasePath, dependency.Filename); var dependencyBuildInfo = DocInfo.LastBuildInfo;// DocInfo.DeducedDependency[ConfigSetting].BuildState[fullPath]; if ((dependencyBuildInfo != null) && (!string.IsNullOrEmpty(dependencyBuildInfo.TargetFile)) && (!System.IO.File.Exists(dependencyBuildInfo.TargetFile))) { Core.AddToOutput($"Dependency target {dependencyBuildInfo.TargetFile} is missing, need to rebuild dependent element " + DocInfo.DocumentFilename + System.Environment.NewLine); return(true); } var fileTime = FileLastWriteTime(fullPath); if (fileTime != DocInfo.DeducedDependency[ConfigSetting].BuildState[fullPath].TimeStampOfTargetFile) { Core.AddToOutput("External Dependency " + fullPath + " was modified, need to rebuild dependent element " + DocInfo.DocumentFilename + System.Environment.NewLine); return(true); } } } else { // no build time stored yet, needs rebuild DocInfo.DeducedDependency[ConfigSetting] = new DependencyBuildState(); Core.AddToOutput("No last build time found for configuration '" + ConfigSetting + "', need rebuilding." + System.Environment.NewLine); return(true); } // check indirect dependencies from pre build chains if (!DocInfo.Element.Settings.ContainsKey(ConfigSetting)) { DocInfo.Element.Settings.Add(ConfigSetting, new ProjectElement.PerConfigSettings()); } var configSettingInner = DocInfo.Element.Settings[ConfigSetting]; if (configSettingInner.PreBuildChain.Active) { foreach (var chainEntry in configSettingInner.PreBuildChain.Entries) { var chainProject = Core.Navigating.Solution.GetProjectByName(chainEntry.ProjectName); if (chainProject != null) { string fullPath = BuildFullPath(chainProject.Settings.BasePath, chainEntry.DocumentFilename); var prebuildDoc = chainProject.GetElementByFilename(fullPath); if (prebuildDoc != null) { if (NeedsRebuild(prebuildDoc.DocumentInfo)) { return(true); } } var fileTime = FileLastWriteTime(fullPath); if (fileTime != DocInfo.DeducedDependency[ConfigSetting].BuildState[fullPath].TimeStampOfSourceFile) { if (DocInfo.DeducedDependency[ConfigSetting].BuildState[fullPath].TimeStampOfSourceFile == default(DateTime)) { Core.AddToOutput($"PreBuild chain entry {fullPath} was modified {fileTime} , need to rebuild dependent element {DocInfo.DocumentFilename}" + System.Environment.NewLine); } else { Core.AddToOutput($"PreBuild chain entry {fullPath} was modified {fileTime} != {DocInfo.DeducedDependency[ConfigSetting].BuildState[fullPath]}, need to rebuild dependent element {DocInfo.DocumentFilename}" + System.Environment.NewLine); } return(true); } } } } if (configSettingInner.PostBuildChain.Active) { foreach (var chainEntry in configSettingInner.PostBuildChain.Entries) { var chainProject = Core.Navigating.Solution.GetProjectByName(chainEntry.ProjectName); if (chainProject != null) { string fullPath = BuildFullPath(chainProject.Settings.BasePath, chainEntry.DocumentFilename); var fileTime = FileLastWriteTime(fullPath); if (fileTime != DocInfo.DeducedDependency[ConfigSetting].BuildState[fullPath].TimeStampOfSourceFile) { if (DocInfo.DeducedDependency[ConfigSetting].BuildState[fullPath].TimeStampOfSourceFile == default(DateTime)) { Core.AddToOutput($"PostBuild chain entry {fullPath} was modified {fileTime} , need to rebuild dependent element {DocInfo.DocumentFilename}" + System.Environment.NewLine); } else { Core.AddToOutput($"PostBuild chain entry {fullPath} was modified {fileTime} != {DocInfo.DeducedDependency[ConfigSetting].BuildState[fullPath]}, need to rebuild dependent element {DocInfo.DocumentFilename}" + System.Environment.NewLine); } return(true); } } } } } if (DocInfo.Compilable) { if (!DocInfo.HasBeenSuccessfullyBuilt) { Core.AddToOutput("Element '" + DocInfo.DocumentFilename + "' was not built successfully last time." + System.Environment.NewLine); return(true); } } if (DocInfo.Project == null) { Core.AddToOutput("Element '" + DocInfo.DocumentFilename + "' has no project, therefor needs rebuilding." + System.Environment.NewLine); return(true); } if (DocInfo.DeducedDependency[ConfigSetting] == null) { // no build time stored yet, needs rebuild DocInfo.DeducedDependency[ConfigSetting] = new DependencyBuildState(); Core.AddToOutput("No build time stored for '" + ConfigSetting + "' yet, therefor needs rebuilding." + System.Environment.NewLine); return(true); } foreach (var dependency in DocInfo.DeducedDependency[ConfigSetting].BuildState) { var fileTime = FileLastWriteTime(dependency.Key); if (fileTime != dependency.Value.TimeStampOfSourceFile) { //Debug.Log( "File time differs for " + dependency.Key ); Core.AddToOutput("File '" + dependency.Key + "' was modified, therefor needs rebuilding." + System.Environment.NewLine); return(true); } } var buildInfo = DocInfo.LastBuildInfo; if ((buildInfo != null) && (!string.IsNullOrEmpty(buildInfo.TargetFile)) && (!System.IO.File.Exists(buildInfo.TargetFile))) { Core.AddToOutput($"Dependency target {buildInfo.TargetFile} is missing, need to rebuild dependent element " + DocInfo.DocumentFilename + System.Environment.NewLine); return(true); } } return(false); }