예제 #1
0
        public static MSBuildInstance GetBestInstance(this IMSBuildLocator msbuildLocator, Version minimumMSBuildVersion, ILogger logger, out bool invalidVSFound, out bool vsWithoutSdkResolver)
        {
            invalidVSFound       = false;
            vsWithoutSdkResolver = false;
            MSBuildInstance bestMatchInstance = null;
            var             bestMatchScore    = 0;

            foreach (var instance in msbuildLocator.GetInstances())
            {
                var score = GetInstanceFeatureScore(instance, minimumMSBuildVersion);

                logger.LogDebug($"MSBuild instance {instance.Name} {instance.Version} scored at {score}");

                invalidVSFound       = invalidVSFound || instance.IsInvalidVisualStudio();
                vsWithoutSdkResolver = vsWithoutSdkResolver || (!instance.IsInvalidVisualStudio() && !instance.HasDotNetSdksResolvers());

                if (bestMatchInstance == null ||
                    score > bestMatchScore ||
                    score == bestMatchScore && instance.Version > bestMatchInstance.Version)
                {
                    bestMatchInstance = instance;
                    bestMatchScore    = score;
                }
            }

            return(bestMatchInstance);
        }
예제 #2
0
 protected override void DisposeCore(bool disposing)
 {
     if (RegisteredInstance != null)
     {
         RegisteredInstance = null;
     }
 }
예제 #3
0
        private static int GetInstanceFeatureScore(MSBuildInstance i, Version minimumMSBuildVersion)
        {
            var score = 0;

            // user override gets highest priority
            if (i.DiscoveryType == DiscoveryType.UserOverride)
            {
                return(int.MaxValue);
            }

            if (i.IsInvalidVisualStudio())
            {
                return(int.MinValue);
            }
            else
            {
                score++;
            }

            // dotnet SDK resolvers are mandatory to use a VS instance
            if (i.HasDotNetSdksResolvers())
            {
                score++;
            }
            else
            {
                return(int.MinValue);
            }

            return(score);
        }
예제 #4
0
        public static MSBuildInstance GetBestInstance(this IMSBuildLocator msbuildLocator, ILogger logger, out bool invalidVSFound)
        {
            invalidVSFound = false;
            MSBuildInstance bestMatchInstance = null;
            var             bestMatchScore    = 0;

            foreach (var instance in msbuildLocator.GetInstances())
            {
                var score = GetInstanceFeatureScore(instance);

                logger.LogDebug($"MSBuild instance {instance.Name} {instance.Version} scored at {score}");

                invalidVSFound = invalidVSFound || instance.IsInvalidVisualStudio();

                if (bestMatchInstance == null ||
                    score > bestMatchScore ||
                    score == bestMatchScore && instance.Version > bestMatchInstance.Version)
                {
                    bestMatchInstance = instance;
                    bestMatchScore    = score;
                }
            }

            return(bestMatchInstance);
        }
예제 #5
0
        private static int GetInstanceFeatureScore(MSBuildInstance i)
        {
            var score = 0;

            if (i.HasDotNetSdksResolvers())
            {
                score++;
            }

            if (i.IsInvalidVisualStudio())
            {
                return(int.MinValue);
            }
            else
            {
                score++;
            }

            if (i.DiscoveryType == DiscoveryType.StandAlone)
            {
                score--;
            }

            return(score);
        }
 protected override void DisposeCore(bool disposing)
 {
     if (_registeredInstance != null)
     {
         AppDomain.CurrentDomain.AssemblyResolve -= Resolve;
         _registeredInstance = null;
     }
 }
예제 #7
0
        public void RegisterInstance(MSBuildInstance instance)
        {
            if (RegisteredInstance != null)
            {
                throw new InvalidOperationException("An MSBuild instance is already registered.");
            }

            RegisteredInstance = instance ?? throw new ArgumentNullException(nameof(instance));

            foreach (var assemblyName in s_msbuildAssemblies)
            {
                LoadAssemblyByNameOnly(assemblyName);
            }

            AppDomain.CurrentDomain.AssemblyResolve += Resolve;

            if (instance.SetMSBuildExePathVariable)
            {
                var msbuildExePath = Path.Combine(instance.MSBuildPath, "MSBuild.exe");
                var msbuildDllPath = Path.Combine(instance.MSBuildPath, "MSBuild.dll");

                string msbuildPath = null;
                if (File.Exists(msbuildExePath))
                {
                    msbuildPath = msbuildExePath;
                }
                else if (File.Exists(msbuildDllPath))
                {
                    msbuildPath = msbuildDllPath;
                }

                if (!string.IsNullOrEmpty(msbuildPath))
                {
                    Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildPath);
                    _logger.LogInformation($"MSBUILD_EXE_PATH environment variable set to '{msbuildPath}'");
                }
                else
                {
                    _logger.LogError("Could not find MSBuild executable path.");
                }
            }

            var builder = new StringBuilder();

            builder.Append($"Registered MSBuild instance: {instance}");

            foreach (var kvp in instance.PropertyOverrides)
            {
                builder.Append($"{Environment.NewLine}            {kvp.Key} = {kvp.Value}");
            }

            _logger.LogInformation(builder.ToString());
        }
예제 #8
0
 protected override void DisposeCore(bool disposing)
 {
     if (RegisteredInstance != null)
     {
         try
         {
             AppDomain.CurrentDomain.AssemblyResolve -= Resolve;
         }
         catch (AppDomainUnloadedException) { } // Ignore if the AppDomain is going away (like during a test in xunit)
         RegisteredInstance = null;
     }
 }
예제 #9
0
        public static bool HasDotNetSdksResolvers(this MSBuildInstance instance)
        {
            const string dotnetSdkResolver = "Microsoft.DotNet.MSBuildSdkResolver";

            return(File.Exists(
                       Path.Combine(
                           instance.MSBuildPath,
                           "SdkResolvers",
                           dotnetSdkResolver,
                           dotnetSdkResolver + ".dll"
                           )
                       ));
        }
예제 #10
0
        private static int GetInstanceFeatureScore(MSBuildInstance i)
        {
            var score = 0;

            // user override gets highest priority
            if (i.DiscoveryType == DiscoveryType.UserOverride)
            {
                return(int.MaxValue);
            }

            if (i.HasDotNetSdksResolvers())
            {
                score++;
            }

            if (i.IsInvalidVisualStudio())
            {
                return(int.MinValue);
            }
            else
            {
                score++;
            }

            if (i.DiscoveryType == DiscoveryType.StandAlone)
            {
                score--;
            }

            // VS 2019 should be preferred
            if (i.Version.Major >= 16)
            {
                score++;
            }
            else
            {
                score--;
            }

            return(score);
        }
예제 #11
0
        public static MSBuildInstance GetBestInstance(this IMSBuildLocator msbuildLocator, out bool invalidVSFound)
        {
            invalidVSFound = false;
            MSBuildInstance bestMatchInstance = null;
            var             bestMatchScore    = 0;

            foreach (var instance in msbuildLocator.GetInstances())
            {
                var score = GetInstanceFeatureScore(instance);

                invalidVSFound = invalidVSFound || instance.IsInvalidVisualStudio();

                if (score > bestMatchScore ||
                    (score == bestMatchScore && instance.Version.Major > (bestMatchInstance?.Version.Major ?? 0)))
                {
                    bestMatchInstance = instance;
                    bestMatchScore    = score;
                }
            }

            return(bestMatchInstance);
        }
예제 #12
0
        public static void RegisterDefaultInstance(this IMSBuildLocator msbuildLocator, ILogger logger)
        {
            MSBuildInstance instanceToRegister = null;
            var             invalidVSFound     = false;

            foreach (var instance in msbuildLocator.GetInstances())
            {
                if (instance.IsInvalidVisualStudio())
                {
                    invalidVSFound = true;
                }
                else
                {
                    instanceToRegister = instance;
                    break;
                }
            }


            if (instanceToRegister != null)
            {
                // Did we end up choosing the standalone MSBuild because there was an invalid Visual Studio?
                // If so, provide a helpful message to the user.
                if (invalidVSFound && instanceToRegister.DiscoveryType == DiscoveryType.StandAlone)
                {
                    logger.LogWarning(@"It looks like you have Visual Studio 2017 RTM installed.
Try updating Visual Studio 2017 to the most recent release to enable better MSBuild support.");
                }

                msbuildLocator.RegisterInstance(instanceToRegister);
            }
            else
            {
                logger.LogError("Could not locate MSBuild instance to register with OmniSharp");
            }
        }
예제 #13
0
 /// <summary>
 /// Checks if the discovered Visual Studio instance includes a version of MSBuild lower than our minimum supported version.
 /// </summary>
 public static bool IsInvalidVisualStudio(this MSBuildInstance instance)
 => (instance.Version.Major < s_minimumMSBuildVersion.Major ||
     (instance.Version.Major == s_minimumMSBuildVersion.Major && instance.Version.Minor < s_minimumMSBuildVersion.Minor)) &&
 (instance.DiscoveryType == DiscoveryType.DeveloperConsole ||
  instance.DiscoveryType == DiscoveryType.VisualStudioSetup);
예제 #14
0
 /// <summary>
 /// Checks if it is MSBuild from Visual Studio 2017 RTM that cannot be used.
 /// </summary>
 public static bool IsInvalidVisualStudio(this MSBuildInstance instance)
 => instance.Version.Major == 15 &&
 instance.Version.Minor == 0 &&
 (instance.DiscoveryType == DiscoveryType.DeveloperConsole ||
  instance.DiscoveryType == DiscoveryType.VisualStudioSetup);