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;
}