private string GetReferencedProjectOutputPath()

in vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectReferenceNode.cs [349:451]


        private string GetReferencedProjectOutputPath()
        {
            // Make sure that the referenced project implements the automation object.
            if (null == this.ReferencedProject)
            {
                return null;
            }

            // Get the configuration manager from the project.
            EnvDTE.ConfigurationManager confManager = this.ReferencedProject.ConfigurationManager;
            if (null == confManager)
            {
                return null;
            }


            // Get the active configuration.
            EnvDTE.Configuration config = null;
            try
            {
                config = confManager.ActiveConfiguration;
            }
            catch (ArgumentException)
            {
                // 4951: exeception happens sometimes when ToolBox queries references on worker thread 
                // (apparently hitting a race or bad state of referenced project's ConfigurationManager)
                return null;
            }
            if (null == config)
            {
                return null;
            }

            // Get the output path for the current configuration.
            string outputPath = null;
            try
            {
                EnvDTE.Property outputPathProperty = config.Properties.Item("OutputPath");
                if (null == outputPathProperty)
                {
                    return null;
                }
                outputPath = outputPathProperty.Value.ToString();
            }
            catch (System.Runtime.InteropServices.COMException)
            {
                // just catch the exception and return null, which means the user will see an empty 'FullPath' field of a ProjectReference property.
                return null;
            }

            // Ususally the output path is relative to the project path, but it is possible
            // to set it as an absolute path. If it is not absolute, then evaluate its value
            // based on the project directory.
            if (!System.IO.Path.IsPathRooted(outputPath))
            {
                string projectDir = System.IO.Path.GetDirectoryName(referencedProjectFullPath);
                outputPath = System.IO.Path.Combine(projectDir, outputPath);
            }

            // Now get the name of the assembly from the project.
            // Some project system throw if the property does not exist. We expect an ArgumentException.
            string assemblyName = null;
            try
            {
                assemblyName = this.ReferencedProject.Properties.Item("OutputFileName").Value.ToString();
            }
            catch (ArgumentException)
            {
            }
            catch (NullReferenceException)
            {
            }

            if (null == assemblyName)
            {
                try
                {
                    var group = config.OutputGroups.Item("Built");
                    var files = (object[])group.FileNames;
                    if (files.Length > 0)
                    {
                        assemblyName = (string)files[0];
                    }
                }
                catch (InvalidCastException)
                {
                    return null;
                }
                catch (ArgumentException)
                {
                    return null;
                }
                catch (NullReferenceException)
                {
                    return null;
                }
            }
            // build the full path adding the name of the assembly to the output path.
            outputPath = System.IO.Path.Combine(outputPath, assemblyName);

            return outputPath;

        }