void EnsureBuildPackagingNugetInstalled(IProjectNode project)
        {
            var dteProject = project.As <EnvDTE.Project>();

            if (!packageInstallerServices.IsBuildPackagingNuGetInstalled(dteProject))
            {
                packageInstaller.InstallBuildPackagingNuget(dteProject);
            }
        }
Exemple #2
0
        /// <summary>
        /// Gets the referenced assemblies from the given project.
        /// </summary>
        /// <param name="project">The project containing references.</param>
        public static IEnumerable <Assembly> GetReferencedAssemblies(this IProjectNode project)
        {
            var vsProject      = project.As <IVsHierarchy>();
            var vsLangProject  = project.As <VSProject>();
            var localServices  = project.As <IServiceProvider>();
            var globalServices = GlobalServiceProvider.Instance;

            if (vsProject == null ||
                localServices == null ||
                globalServices == null)
            {
                tracer.Warn(Strings.IProjectNodeExtensions.InvalidVsContext);
                return(Enumerable.Empty <Assembly>());
            }

            var openScope = globalServices.GetService <SVsSmartOpenScope, IVsSmartOpenScope>();
            var dtar      = localServices.GetService <SVsDesignTimeAssemblyResolution, IVsDesignTimeAssemblyResolution>();

            // As suggested by Christy Henriksson, we reuse the type discovery service
            // but just for the IDesignTimeAssemblyLoader interface. The actual
            // assembly reading is done by the TFP using metadata only :)
            var dts  = globalServices.GetService <DynamicTypeService>();
            var ds   = dts.GetTypeDiscoveryService(vsProject);
            var dtal = ds as IDesignTimeAssemblyLoader;

            if (openScope == null || dtar == null || dts == null || ds == null || dtal == null)
            {
                tracer.Warn(Strings.IProjectNodeExtensions.InvalidTypeContext);
                return(Enumerable.Empty <Assembly>());
            }

            var provider = new VsTargetFrameworkProvider(dtar, dtal, openScope);

            return(vsLangProject.References
                   .OfType <Reference>()
                   .Select(x => TryLoad(provider, x))
                   .Where(x => x != null));
        }
        public IServiceProvider Adapt(IProjectNode from)
        {
            var vsProject = from.As <IVsProject>();

            Ole.IServiceProvider oleSp;

            // local service provider for the project
            if (vsProject != null && vsProject.GetItemContext(VSConstants.VSITEMID_ROOT, out oleSp) == VSConstants.S_OK)
            {
                return(new ServiceProvider(oleSp));
            }

            return(GlobalServiceProvider.Instance);
        }
Exemple #4
0
        public static GraphNodeId GetId(this IProjectNode node)
        {
            var project = node.As <Project>();

            if (project.Kind == EnvDTE.Constants.vsProjectKindUnmodeled)
            {
                return(null);
            }

            var fileName = GetProjectFileUri(project);

            if (fileName == null)
            {
                return(null);
            }

            return(GraphNodeId.GetNested(CodeGraphNodeIdName.Assembly, fileName));
        }
Exemple #5
0
 /// <summary>
 /// Adapts a <see cref="IProjectNode"/> to an <see cref="IVsHierarchyItem"/>.
 /// </summary>
 /// <returns>The <see cref="IVsHierarchyItem"/> or <see langword="null"/> if conversion is not possible.</returns>
 public static IVsHierarchyItem AsVsHierarchyItem(this IProjectNode project) => project.As <IVsHierarchyItem>();
Exemple #6
0
 /// <summary>
 /// Adapts a <see cref="IProjectNode"/> to a <see cref="Microsoft.Build.Evaluation.Project"/>.
 /// </summary>
 /// <returns>The <see cref="Microsoft.Build.Evaluation.Project"/> or <see langword="null"/> if conversion is not possible.</returns>
 public static Microsoft.Build.Evaluation.Project AsMsBuildProject(this IProjectNode project) =>
 project.As <Microsoft.Build.Evaluation.Project>();
Exemple #7
0
 /// <summary>
 /// Adapts a <see cref="IProjectNode"/> to a <see cref="VSProject"/>.
 /// </summary>
 /// <returns>The <see cref="VSProject"/> or <see langword="null"/> if conversion is not possible.</returns>
 public static VSProject AsVsLangProject(this IProjectNode project) => project.As <VSProject>();
Exemple #8
0
 /// <summary>
 /// Adapts a <see cref="IProjectNode"/> to an <see cref="IVsBuildPropertyStorage"/>.
 /// </summary>
 /// <returns>The <see cref="IVsBuildPropertyStorage"/> or <see langword="null"/> if conversion is not possible.</returns>
 public static IVsBuildPropertyStorage AsVsBuildPropertyStorage(this IProjectNode project) => project.As <IVsBuildPropertyStorage>();
Exemple #9
0
 /// <summary>
 /// Adapts a <see cref="IProjectNode"/> to an <see cref="IVsProject"/>.
 /// </summary>
 /// <returns>The <see cref="IVsProject"/> or <see langword="null"/> if conversion is not possible.</returns>
 public static IVsProject AsVsProject(this IProjectNode project) => project.As <IVsProject>();
Exemple #10
0
 /// <summary>
 /// Adapts a <see cref="IProjectNode"/> to an <see cref="IVsHierarchy"/>.
 /// </summary>
 /// <returns>The <see cref="IVsHierarchy"/> or <see langword="null"/> if conversion is not possible.</returns>
 public static IVsHierarchy AsVsHierarchy(this IProjectNode project) => project.As <IVsHierarchy>();
Exemple #11
0
 internal static IProjectItemContainerNode AsContainerNode(this IProjectNode project) =>
 project.As <IProjectItemContainerNode>();
Exemple #12
0
 internal static IReferenceContainerNode AsReferenceContainerNode(this IProjectNode project) =>
 project.As <IReferenceContainerNode>();
Exemple #13
0
        /// <summary>
        /// Builds the specified project.
        /// </summary>
        /// <param name="project">The project to build.</param>
        /// <param name="cancellation">Cancellation token to cancel the wait for the build to finish.</param>
        /// <param name="timeout">A maximum time to wait for the build to finish.</param>
        /// <exception cref="System.ArgumentException">The project has no <see cref="ISolutionExplorerNode.OwningSolution"/>.</exception>
        /// <returns><see langword="true"/> if the build succeeded; <see langword="false"/> otherwise.</returns>
        public static Task <bool> Build(this IProjectNode project, CancellationToken cancellation, TimeSpan timeout)
        {
            Guard.NotNull(() => project, project);
            Guard.NotNull(() => cancellation, cancellation);

            var solution = project.OwningSolution;

            if (solution == null)
            {
                throw new ArgumentException(Strings.IProjectNodeExtensions.BuildNoSolution(project.DisplayName));
            }

            var sln = solution.As <EnvDTE.Solution>();

            if (sln == null)
            {
                throw new ArgumentException(Strings.IProjectNodeExtensions.BuildNoSolution(project.DisplayName));
            }

            return(System.Threading.Tasks.Task.Factory.StartNew <bool>(() =>
            {
                try
                {
                    // Let build run async.
                    sln.SolutionBuild.BuildProject(sln.SolutionBuild.ActiveConfiguration.Name, project.As <EnvDTE.Project>().UniqueName, false);

                    // First wait until it becomes in progress. We give it
                    // a maximum of 2 seconds for VS to start building. If this doesn't
                    // happen in that time, something really weird must be going on.
                    var inProgress = SpinWait.SpinUntil(() =>
                                                        cancellation.IsCancellationRequested ||
                                                        sln.SolutionBuild.BuildState == EnvDTE.vsBuildState.vsBuildStateInProgress,
                                                        2000);

                    // If the build did not start in under 2 seconds, something weird happened,
                    // so return quickly and with false.
                    // Note that this may be the case when the token is cancelled.
                    if (!inProgress)
                    {
                        return false;
                    }

                    // Next wait until it's done.
                    // This could be a remote build, complex one, etc., so we specify 10 minutes as a
                    // conservative wait.
                    var isDone = SpinWait.SpinUntil(() =>
                                                    cancellation.IsCancellationRequested ||
                                                    sln.SolutionBuild.BuildState == EnvDTE.vsBuildState.vsBuildStateDone,
                                                    timeout);

                    // LastBuildInfo == # of projects that failed to build.
                    // We'll return false if the build wait was cancelled.
                    return !cancellation.IsCancellationRequested && isDone && sln.SolutionBuild.LastBuildInfo == 0;
                }
                catch (Exception ex)
                {
                    tracer.Error(ex, Strings.IProjectNodeExtensions.BuildException);
                    return false;
                }
            }, cancellation, TaskCreationOptions.None, TaskScheduler.Default));
        }
Exemple #14
0
        /// <summary>
        /// Gets the output assembly of the given project. If the project
        /// was never built before, it's built before returning the output
        /// assembly.
        /// </summary>
        /// <param name="project">The project to get the output assembly from.</param>
        /// <param name="buildIfMissing">Whether to build the project if the output assembly is missing.</param>
        public static Task <Assembly> GetOutputAssembly(this IProjectNode project, bool buildIfMissing = true)
        {
            var fileName = (string)project.Properties.TargetFileName;
            var msBuild  = project.Adapt().AsMsBuildProject();

            if (msBuild == null)
            {
                throw new ArgumentException(Strings.IProjectNodeExtensions.NotMsBuildProject(project.DisplayName));
            }

            // NOTE: we load from the obj/Debug|Release folder, which is
            // the one built in the background by VS continuously.
            var intermediateDir = msBuild.AllEvaluatedProperties
                                  .Where(p => p.Name == "IntermediateOutputPath")
                                  // If we grab the EvaluatedValue, it won't have the current
                                  // global properties overrides, like Configuration and Debug.
                                  .Select(p => msBuild.ExpandString(p.UnevaluatedValue))
                                  .FirstOrDefault();

            if (string.IsNullOrEmpty(fileName) ||
                string.IsNullOrEmpty(intermediateDir) ||
                string.IsNullOrEmpty(project.Properties.MSBuildProjectDirectory))
            {
                tracer.Warn(Strings.IProjectNodeExtensions.NoTargetAssemblyName(project.DisplayName));
                return(TaskHelpers.FromResult <Assembly>(null));
            }

            var outDir       = (string)Path.Combine(project.Properties.MSBuildProjectDirectory, intermediateDir);
            var assemblyFile = Path.Combine(outDir, fileName);

            if (!File.Exists(assemblyFile) && !buildIfMissing)
            {
                return(TaskHelpers.FromResult <Assembly>(null));
            }

            return(Task.Factory.StartNew <Assembly>(() =>
            {
                if (!File.Exists(assemblyFile))
                {
                    var success = project.Build().Result;
                    if (success)
                    {
                        // Let the build finish writing the file
                        for (int i = 0; i < 5; i++)
                        {
                            if (File.Exists(assemblyFile))
                            {
                                break;
                            }

                            Thread.Sleep(200);
                        }
                    }

                    if (!File.Exists(assemblyFile))
                    {
                        tracer.Warn(Strings.IProjectNodeExtensions.NoBuildOutput(project.DisplayName, assemblyFile));
                        return null;
                    }
                }

                var assemblyName = AssemblyName.GetAssemblyName(assemblyFile);
                var vsProject = project.As <IVsHierarchy>();
                var localServices = project.As <IServiceProvider>();
                var globalServices = GlobalServiceProvider.Instance;

                if (vsProject == null ||
                    localServices == null ||
                    globalServices == null)
                {
                    tracer.Warn(Strings.IProjectNodeExtensions.InvalidVsContext);
                    return null;
                }

                var openScope = globalServices.GetService <SVsSmartOpenScope, IVsSmartOpenScope>();
                var dtar = localServices.GetService <SVsDesignTimeAssemblyResolution, IVsDesignTimeAssemblyResolution>();

                // As suggested by Christy Henriksson, we reuse the type discovery service
                // but just for the IDesignTimeAssemblyLoader interface. The actual
                // assembly reading is done by the TFP using metadata only :)
                var dts = globalServices.GetService <DynamicTypeService>();
                var ds = dts.GetTypeDiscoveryService(vsProject);
                var dtal = ds as IDesignTimeAssemblyLoader;

                if (openScope == null || dtar == null || dts == null || ds == null || dtal == null)
                {
                    tracer.Warn(Strings.IProjectNodeExtensions.InvalidTypeContext);
                    return null;
                }

                var provider = new VsTargetFrameworkProvider(dtar, dtal, openScope);

                return provider.GetReflectionAssembly(assemblyName);
            }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default));
        }