예제 #1
0
        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);
        }
예제 #2
0
        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);
        }