public void Initalize(IConfiguration configuration)
        {
            _options = new MSBuildOptions();
            ConfigurationBinder.Bind(configuration, _options);

            if (_environment.LogLevel < LogLevel.Information)
            {
                var buildEnvironmentInfo = MSBuildHelpers.GetBuildEnvironmentInfo();
                _logger.LogDebug($"MSBuild environment: {Environment.NewLine}{buildEnvironmentInfo}");
            }

            _packageDependencyChecker = new PackageDependencyChecker(_loggerFactory, _eventEmitter, _dotNetCli, _options);
            _loader  = new ProjectLoader(_options, _environment.TargetDirectory, _propertyOverrides, _loggerFactory, _sdksPathResolver);
            _manager = new ProjectManager(_loggerFactory, _eventEmitter, _fileSystemWatcher, _metadataFileReferenceCache, _packageDependencyChecker, _loader, _workspace);

            var initialProjectPaths = GetInitialProjectPaths();

            foreach (var projectFilePath in initialProjectPaths)
            {
                if (!File.Exists(projectFilePath))
                {
                    _logger.LogWarning($"Found project that doesn't exist on disk: {projectFilePath}");
                    continue;
                }

                _manager.QueueProjectUpdate(projectFilePath, allowAutoRestore: true);
            }
        }
예제 #2
0
 public MSBuildOptions(MSBuildOptions incoming)
 {
     OutputFolder  = incoming.OutputFolder;
     Configuration = incoming.Configuration;
     Platform      = incoming.Platform;
     BuildTargets  = incoming.BuildTargets;
 }
예제 #3
0
 public ProjectLoader(MSBuildOptions options, string solutionDirectory, ImmutableDictionary <string, string> propertyOverrides, ILoggerFactory loggerFactory, SdksPathResolver sdksPathResolver)
 {
     _logger           = loggerFactory.CreateLogger <ProjectLoader>();
     _options          = options ?? new MSBuildOptions();
     _sdksPathResolver = sdksPathResolver ?? throw new ArgumentNullException(nameof(sdksPathResolver));
     _globalProperties = CreateGlobalProperties(_options, solutionDirectory, propertyOverrides, _logger);
 }
 public PackageDependencyChecker(ILoggerFactory loggerFactory, IEventEmitter eventEmitter, IDotNetCliService dotNetCli, MSBuildOptions options)
 {
     _logger       = loggerFactory.CreateLogger <PackageDependencyChecker>();
     _eventEmitter = eventEmitter;
     _dotNetCli    = dotNetCli;
     _options      = options;
 }
예제 #5
0
        private static Dictionary <string, string> CreateGlobalProperties(
            MSBuildOptions options, string solutionDirectory, ImmutableDictionary <string, string> propertyOverrides, ILogger logger)
        {
            var globalProperties = new Dictionary <string, string>
            {
                { PropertyNames.DesignTimeBuild, "true" },
                { PropertyNames.BuildingInsideVisualStudio, "true" },
                { PropertyNames.BuildProjectReferences, "false" },
                { PropertyNames._ResolveReferenceDependencies, "true" },
                { PropertyNames.SolutionDir, solutionDirectory + Path.DirectorySeparatorChar },

                // This properties allow the design-time build to handle the Compile target without actually invoking the compiler.
                // See https://github.com/dotnet/roslyn/pull/4604 for details.
                { PropertyNames.ProvideCommandLineArgs, "true" },
                { PropertyNames.SkipCompilerExecution, "true" }
            };

            globalProperties.AddPropertyOverride(PropertyNames.MSBuildExtensionsPath, options.MSBuildExtensionsPath, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.TargetFrameworkRootPath, options.TargetFrameworkRootPath, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.RoslynTargetsPath, options.RoslynTargetsPath, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.CscToolPath, options.CscToolPath, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.CscToolExe, options.CscToolExe, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.VisualStudioVersion, options.VisualStudioVersion, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.Configuration, options.Configuration, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.Platform, options.Platform, propertyOverrides, logger);

            if (propertyOverrides.TryGetValue(PropertyNames.BypassFrameworkInstallChecks, out var value))
            {
                globalProperties.Add(PropertyNames.BypassFrameworkInstallChecks, value);
            }

            return(globalProperties);
        }
예제 #6
0
        public ProjectManager(ILoggerFactory loggerFactory,
                              MSBuildOptions options,
                              IEventEmitter eventEmitter,
                              IFileSystemWatcher fileSystemWatcher,
                              MetadataFileReferenceCache metadataFileReferenceCache,
                              PackageDependencyChecker packageDependencyChecker,
                              ProjectLoader projectLoader,
                              OmniSharpWorkspace workspace,
                              ImmutableArray <IMSBuildEventSink> eventSinks)
        {
            _logger                     = loggerFactory.CreateLogger <ProjectManager>();
            _options                    = options ?? new MSBuildOptions();
            _eventEmitter               = eventEmitter;
            _fileSystemWatcher          = fileSystemWatcher;
            _metadataFileReferenceCache = metadataFileReferenceCache;
            _packageDependencyChecker   = packageDependencyChecker;
            _projectFiles               = new ProjectFileInfoCollection();
            _failedToLoadProjectFiles   = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            _projectsRequestedOnDemand  = new ConcurrentDictionary <string, int>(StringComparer.OrdinalIgnoreCase);
            _projectLoader              = projectLoader;
            _workspace                  = workspace;
            _eventSinks                 = eventSinks;

            _queue = new BufferBlock <ProjectToUpdate>();
            _processLoopCancellation = new CancellationTokenSource();
            _processLoopTask         = Task.Run(() => ProcessLoopAsync(_processLoopCancellation.Token));

            _onDirectoryFileChanged = OnDirectoryFileChanged;

            if (_options.LoadProjectsOnDemand)
            {
                _workspace.AddWaitForProjectModelReadyHandler(WaitForProjectModelReadyAsync);
            }
        }
예제 #7
0
        private static Dictionary <string, string> GetGlobalProperties(MSBuildOptions options, string solutionDirectory, string sdksPath, ILogger logger)
        {
            var globalProperties = new Dictionary <string, string>
            {
                { PropertyNames.DesignTimeBuild, "true" },
                { PropertyNames.BuildProjectReferences, "false" },
                { PropertyNames._ResolveReferenceDependencies, "true" },
                { PropertyNames.SolutionDir, solutionDirectory + Path.DirectorySeparatorChar },

                // This properties allow the design-time build to handle the Compile target without actually invoking the compiler.
                // See https://github.com/dotnet/roslyn/pull/4604 for details.
                { PropertyNames.ProvideCommandLineInvocation, "true" },
                { PropertyNames.SkipCompilerExecution, "true" }
            };

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.MSBuildExtensionsPath,
                userOptionValue: options.MSBuildExtensionsPath,
                environmentValue: MSBuildEnvironment.MSBuildExtensionsPath);

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.MSBuildSDKsPath,
                userOptionValue: options.MSBuildSDKsPath,
                environmentValue: sdksPath);

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.VisualStudioVersion,
                userOptionValue: options.VisualStudioVersion,
                environmentValue: null);

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.Configuration,
                userOptionValue: options.Configuration,
                environmentValue: null);

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.Platform,
                userOptionValue: options.Platform,
                environmentValue: null);

            if (PlatformHelper.IsMono)
            {
                var monoXBuildFrameworksDirPath = PlatformHelper.MonoXBuildFrameworksDirPath;
                if (monoXBuildFrameworksDirPath != null)
                {
                    logger.LogDebug($"Using TargetFrameworkRootPath: {monoXBuildFrameworksDirPath}");
                    globalProperties.Add(PropertyNames.TargetFrameworkRootPath, monoXBuildFrameworksDirPath);
                }
            }

            return(globalProperties);
        }
예제 #8
0
        private static ProjectInstance LoadProject(
            string filePath, string solutionDirectory, string sdksPath, ILogger logger,
            MSBuildOptions options, ICollection <MSBuildDiagnosticsMessage> diagnostics, out ImmutableArray <string> targetFrameworks)
        {
            options = options ?? new MSBuildOptions();

            var globalProperties = GetGlobalProperties(options, solutionDirectory, sdksPath, logger);

            const string MSBuildSDKsPath  = "MSBuildSDKsPath";
            var          oldSdksPathValue = Environment.GetEnvironmentVariable(MSBuildSDKsPath);

            try
            {
                if (globalProperties.TryGetValue(MSBuildSDKsPath, out var sdksPathValue))
                {
                    Environment.SetEnvironmentVariable(MSBuildSDKsPath, sdksPathValue);
                }

                var collection = new ProjectCollection(globalProperties);

                // Evaluate the MSBuild project
                var project = string.IsNullOrEmpty(options.ToolsVersion)
                    ? collection.LoadProject(filePath)
                    : collection.LoadProject(filePath, options.ToolsVersion);

                var targetFramework = project.GetPropertyValue(PropertyNames.TargetFramework);
                targetFrameworks = PropertyConverter.SplitList(project.GetPropertyValue(PropertyNames.TargetFrameworks), ';');

                // If the project supports multiple target frameworks and specific framework isn't
                // selected, we must pick one before execution. Otherwise, the ResolveReferences
                // target might not be available to us.
                if (string.IsNullOrWhiteSpace(targetFramework) && targetFrameworks.Length > 0)
                {
                    // For now, we'll just pick the first target framework. Eventually, we'll need to
                    // do better and potentially allow OmniSharp hosts to select a target framework.
                    targetFramework = targetFrameworks[0];
                    project.SetProperty(PropertyNames.TargetFramework, targetFramework);
                }
                else if (!string.IsNullOrWhiteSpace(targetFramework) && targetFrameworks.Length == 0)
                {
                    targetFrameworks = ImmutableArray.Create(targetFramework);
                }

                var projectInstance = project.CreateProjectInstance();
                var buildResult     = projectInstance.Build(TargetNames.Compile,
                                                            new[] { new MSBuildLogForwarder(logger, diagnostics) });

                return(buildResult
                    ? projectInstance
                    : null);
            }
            finally
            {
                Environment.SetEnvironmentVariable(MSBuildSDKsPath, oldSdksPathValue);
            }
        }
예제 #9
0
        public static MSBuildOptions Merge(MSBuildOptions original, MSBuildOptions incoming)
        {
            var newOptions = (MSBuildOptions)original.MemberwiseClone();

            newOptions.OutputFolder  = newOptions.OutputFolder ?? incoming.OutputFolder;
            newOptions.Configuration = newOptions.Configuration ?? incoming.Configuration;
            newOptions.Platform      = newOptions.Platform ?? incoming.Platform;
            newOptions.BuildTargets  = newOptions.BuildTargets ?? incoming.BuildTargets;
            return(newOptions);
        }
예제 #10
0
        private static Dictionary <string, string> GetGlobalProperties(MSBuildOptions options, string solutionDirectory, string sdksPath, ILogger logger)
        {
            var globalProperties = new Dictionary <string, string>
            {
                { PropertyNames.DesignTimeBuild, "true" },
                { PropertyNames.BuildProjectReferences, "false" },
                { PropertyNames._ResolveReferenceDependencies, "true" },
                { PropertyNames.SolutionDir, solutionDirectory + Path.DirectorySeparatorChar }
            };

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.MSBuildExtensionsPath,
                userOptionValue: options.MSBuildExtensionsPath,
                environmentValue: MSBuildEnvironment.MSBuildExtensionsPath);

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.MSBuildSDKsPath,
                userOptionValue: options.MSBuildSDKsPath,
                environmentValue: sdksPath);

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.VisualStudioVersion,
                userOptionValue: options.VisualStudioVersion,
                environmentValue: null);

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.Configuration,
                userOptionValue: options.Configuration,
                environmentValue: null);

            globalProperties.AddPropertyIfNeeded(
                logger,
                PropertyNames.Platform,
                userOptionValue: options.Platform,
                environmentValue: null);

            if (PlatformHelper.IsMono)
            {
                var monoXBuildFrameworksDirPath = PlatformHelper.MonoXBuildFrameworksDirPath;
                if (monoXBuildFrameworksDirPath != null)
                {
                    logger.LogDebug($"Using TargetFrameworkRootPath: {monoXBuildFrameworksDirPath}");
                    globalProperties.Add(PropertyNames.TargetFrameworkRootPath, monoXBuildFrameworksDirPath);
                }
            }

            return(globalProperties);
        }
예제 #11
0
        public ProjectFileInfo Reload(
            string solutionDirectory, string sdksPath, ILogger logger,
            MSBuildOptions options = null, ICollection <MSBuildDiagnosticsMessage> diagnostics = null)
        {
            var projectInstance = LoadProject(FilePath, solutionDirectory, sdksPath, logger, options, diagnostics, out var targetFrameworks);

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

            var data = CreateProjectData(projectInstance, targetFrameworks);

            return(new ProjectFileInfo(Id, FilePath, data));
        }
예제 #12
0
        public void Initalize(IConfiguration configuration)
        {
            if (Initialized)
            {
                return;
            }

            _options = new MSBuildOptions();
            ConfigurationBinder.Bind(configuration, _options);

            _sdksPathResolver.Enabled      = _options.UseLegacySdkResolver;
            _sdksPathResolver.OverridePath = _options.MSBuildSDKsPath;

            if (_environment.LogLevel < LogLevel.Information)
            {
                var buildEnvironmentInfo = MSBuildHelpers.GetBuildEnvironmentInfo();
                _logger.LogDebug($"MSBuild environment: {Environment.NewLine}{buildEnvironmentInfo}");
            }

            _packageDependencyChecker = new PackageDependencyChecker(_loggerFactory, _eventEmitter, _dotNetCli, _options);
            _loader = new ProjectLoader(_options, _environment.TargetDirectory, _propertyOverrides, _loggerFactory, _sdksPathResolver);

            var dotNetInfo = GetDotNetInfo();

            _manager    = new ProjectManager(_loggerFactory, _options, _eventEmitter, _fileSystemWatcher, _metadataFileReferenceCache, _packageDependencyChecker, _loader, _workspace, _assemblyLoader, _eventSinks, dotNetInfo);
            Initialized = true;

            if (_options.LoadProjectsOnDemand)
            {
                _logger.LogInformation($"Skip loading projects listed in solution file or under target directory because {Key}:{nameof(MSBuildOptions.LoadProjectsOnDemand)} is true.");
                return;
            }

            var initialProjectPathsAndIds = GetInitialProjectPathsAndIds();

            foreach (var(projectFilePath, projectIdInfo) in initialProjectPathsAndIds)
            {
                if (!File.Exists(projectFilePath))
                {
                    _logger.LogWarning($"Found project that doesn't exist on disk: {projectFilePath}");
                    continue;
                }

                _manager.QueueProjectUpdate(projectFilePath, allowAutoRestore: true, projectIdInfo);
            }
        }
예제 #13
0
        private static void Main()
        {
            // Get the user's current directory, not the path of the script
            var root = PathUtils.Resolve(Directory.GetCurrentDirectory(), @"..\..\..\..");

            var defaultBuildOptions = new MSBuildOptions
            {
                OutputFolder  = @"BuildOutput\Debug",
                Configuration = @"Debug",
                Platform      = @"AnyCPU",
                BuildTargets  = "Clean, Build"
            };

            Target.Create("Weird").Path(root)
            .BuildProject(new MSBuildOptions
            {
                ProjectFile  = @"Source\Howatworks.Tascs.Core\Howatworks.Tascs.Core.csproj",
                OutputFolder = @"BuildOutput\Release"
            })
            .Exec(@"cmd.exe", Arg.Literal(@"/c"), Arg.Literal(@"echo"), Arg.Quoted(@"do weird"));

            Target.Create("Minimal")
            .DependsOn(Target.Named("Weird"))
            .Exec(@"cmd.exe", Arg.Literal(@"/c"), Arg.Literal(@"echo"), Arg.Quoted(@"do minimal"))
            .BuildProject(new MSBuildOptions(defaultBuildOptions)
            {
                ProjectFile = @"Source\Howatworks.Tascs.MSBuild\Howatworks.Tascs.MSBuild.csproj"
            });

            Target.Create("Unnecessary")
            .DependsOn(Target.Named("Weird"))
            .Exec(@"cmd.exe", @"/c", @"echo", Arg.Quoted(@"do unnecessary - don't do this"));

            Target.Create("Chained")
            .DependsOn(
                Target.Create("Downstream")
                .Echo("Downstream!")
                )
            .Echo("Chained!");

            Target.Execute("Chained", "Minimal");

            Console.WriteLine("Press any key...");
            Console.ReadKey();
        }
 public MSBuildProjectSystem(OmnisharpWorkspace workspace,
                             IOmnisharpEnvironment env,
                             IOptions <OmniSharpOptions> optionsAccessor,
                             ILoggerFactory loggerFactory,
                             IEventEmitter emitter,
                             IMetadataFileReferenceCache metadataReferenceCache,
                             IFileSystemWatcher watcher,
                             MSBuildContext context)
 {
     _workspace = workspace;
     _metadataReferenceCache = metadataReferenceCache;
     _watcher = watcher;
     _env     = env;
     _options = optionsAccessor.Options.MsBuild;
     _logger  = loggerFactory.CreateLogger <MSBuildProjectSystem>();
     _emitter = emitter;
     _context = context;
 }
예제 #15
0
        private static Dictionary <string, string> CreateGlobalProperties(
            MSBuildOptions options, string solutionDirectory, ImmutableDictionary <string, string> propertyOverrides, ILogger logger)
        {
            var globalProperties = new Dictionary <string, string>
            {
                { PropertyNames.DesignTimeBuild, "true" },
                { PropertyNames.BuildingInsideVisualStudio, "true" },
                { PropertyNames.BuildProjectReferences, "false" },
                { PropertyNames._ResolveReferenceDependencies, "true" },
                { PropertyNames.SolutionDir, solutionDirectory + Path.DirectorySeparatorChar },

                // Setting this property will cause any XAML markup compiler tasks to run in the
                // current AppDomain, rather than creating a new one. This is important because
                // our AppDomain.AssemblyResolve handler for MSBuild will not be connected to
                // the XAML markup compiler's AppDomain, causing the task not to be able to find
                // MSBuild.
                { PropertyNames.AlwaysCompileMarkupFilesInSeparateDomain, "false" },

                // This properties allow the design-time build to handle the Compile target without actually invoking the compiler.
                // See https://github.com/dotnet/roslyn/pull/4604 for details.
                { PropertyNames.ProvideCommandLineArgs, "true" },
                { PropertyNames.SkipCompilerExecution, "true" },

                // Ensures the SDK doesn't try to generate app hosts for the loading projects
                { PropertyNames.UseAppHost, "false" },
            };

            globalProperties.AddPropertyOverride(PropertyNames.MSBuildExtensionsPath, options.MSBuildExtensionsPath, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.TargetFrameworkRootPath, options.TargetFrameworkRootPath, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.RoslynTargetsPath, options.RoslynTargetsPath, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.CscToolPath, options.CscToolPath, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.CscToolExe, options.CscToolExe, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.VisualStudioVersion, options.VisualStudioVersion, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.Configuration, options.Configuration, propertyOverrides, logger);
            globalProperties.AddPropertyOverride(PropertyNames.Platform, options.Platform, propertyOverrides, logger);

            if (propertyOverrides.TryGetValue(PropertyNames.BypassFrameworkInstallChecks, out var value))
            {
                globalProperties.Add(PropertyNames.BypassFrameworkInstallChecks, value);
            }

            return(globalProperties);
        }
예제 #16
0
        public static ProjectFileInfo Create(
            string filePath, string solutionDirectory, string sdksPath, ILogger logger,
            MSBuildOptions options = null, ICollection <MSBuildDiagnosticsMessage> diagnostics = null)
        {
            if (!File.Exists(filePath))
            {
                return(null);
            }

            var projectInstance = LoadProject(filePath, solutionDirectory, sdksPath, logger, options, diagnostics, out var targetFrameworks);

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

            var id   = ProjectId.CreateNewId(debugName: filePath);
            var data = CreateProjectData(projectInstance, targetFrameworks);

            return(new ProjectFileInfo(id, filePath, data));
        }
예제 #17
0
        public void Initalize(IConfiguration configuration)
        {
            _options = new MSBuildOptions();
            ConfigurationBinder.Bind(configuration, _options);

            if (!MSBuildEnvironment.IsInitialized)
            {
                MSBuildEnvironment.Initialize(_logger);

                if (MSBuildEnvironment.IsInitialized &&
                    _environment.LogLevel < LogLevel.Information)
                {
                    var buildEnvironmentInfo = MSBuildHelpers.GetBuildEnvironmentInfo();
                    _logger.LogDebug($"MSBuild environment: {Environment.NewLine}{buildEnvironmentInfo}");
                }
            }

            var initialProjectPaths = GetInitialProjectPaths();

            foreach (var projectPath in initialProjectPaths)
            {
                if (!File.Exists(projectPath))
                {
                    _logger.LogWarning($"Found project that doesn't exist on disk: {projectPath}");
                    continue;
                }

                var project = LoadProject(projectPath);
                if (project == null)
                {
                    // Diagnostics reported while loading the project have already been logged.
                    continue;
                }

                _projectsToProcess.Enqueue(project);
            }

            ProcessProjects();
        }
예제 #18
0
        public static ProjectFileInfo Create(MSBuildOptions options, ILogger logger, string solutionDirectory, string projectFilePath, ICollection <MSBuildDiagnosticsMessage> diagnostics)
        {
            var projectFileInfo = new ProjectFileInfo();

            projectFileInfo.ProjectFilePath = projectFilePath;

#if DNX451
            if (!PlatformHelper.IsMono)
            {
                var properties = new Dictionary <string, string>
                {
                    { "DesignTimeBuild", "true" },
                    { "BuildProjectReferences", "false" },
                    { "_ResolveReferenceDependencies", "true" },
                    { "SolutionDir", solutionDirectory + Path.DirectorySeparatorChar }
                };

                if (!string.IsNullOrWhiteSpace(options.VisualStudioVersion))
                {
                    properties.Add("VisualStudioVersion", options.VisualStudioVersion);
                }

                var collection = new ProjectCollection(properties);

                logger.LogInformation("Using toolset {0} for {1}", options.ToolsVersion ?? collection.DefaultToolsVersion, projectFilePath);

                var project = string.IsNullOrEmpty(options.ToolsVersion) ?
                              collection.LoadProject(projectFilePath) :
                              collection.LoadProject(projectFilePath, options.ToolsVersion);

                var projectInstance = project.CreateProjectInstance();
                var buildResult     = projectInstance.Build("ResolveReferences", new Microsoft.Build.Framework.ILogger[] { new MSBuildLogForwarder(logger, diagnostics) });

                if (!buildResult)
                {
                    return(null);
                }

                projectFileInfo.AssemblyName             = projectInstance.GetPropertyValue("AssemblyName");
                projectFileInfo.Name                     = projectInstance.GetPropertyValue("ProjectName");
                projectFileInfo.TargetFramework          = new FrameworkName(projectInstance.GetPropertyValue("TargetFrameworkMoniker"));
                projectFileInfo.SpecifiedLanguageVersion = ToLanguageVersion(projectInstance.GetPropertyValue("LangVersion"));
                projectFileInfo.ProjectId                = new Guid(projectInstance.GetPropertyValue("ProjectGuid").TrimStart('{').TrimEnd('}'));
                projectFileInfo.TargetPath               = projectInstance.GetPropertyValue("TargetPath");

                projectFileInfo.SourceFiles =
                    projectInstance.GetItems("Compile")
                    .Select(p => p.GetMetadataValue("FullPath"))
                    .ToList();

                projectFileInfo.References =
                    projectInstance.GetItems("ReferencePath")
                    .Where(p => !string.Equals("ProjectReference", p.GetMetadataValue("ReferenceSourceTarget"), StringComparison.OrdinalIgnoreCase))
                    .Select(p => p.GetMetadataValue("FullPath"))
                    .ToList();

                projectFileInfo.ProjectReferences =
                    projectInstance.GetItems("ProjectReference")
                    .Select(p => p.GetMetadataValue("FullPath"))
                    .ToList();

                projectFileInfo.Analyzers =
                    projectInstance.GetItems("Analyzer")
                    .Select(p => p.GetMetadataValue("FullPath"))
                    .ToList();

                var defineConstants = projectInstance.GetPropertyValue("DefineConstants");
                if (!string.IsNullOrWhiteSpace(defineConstants))
                {
                    projectFileInfo.DefineConstants = defineConstants.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList();
                }
            }
            else
            {
                // On mono we need to use this API since the ProjectCollection
                // isn't fully implemented
#pragma warning disable CS0618
                var engine = Engine.GlobalEngine;
                engine.DefaultToolsVersion = "4.0";
#pragma warning restore CS0618
                // engine.RegisterLogger(new ConsoleLogger());
                engine.RegisterLogger(new MSBuildLogForwarder(logger, diagnostics));

                var propertyGroup = new BuildPropertyGroup();
                propertyGroup.SetProperty("DesignTimeBuild", "true");
                propertyGroup.SetProperty("BuildProjectReferences", "false");
                // Dump entire assembly reference closure
                propertyGroup.SetProperty("_ResolveReferenceDependencies", "true");
                propertyGroup.SetProperty("SolutionDir", solutionDirectory + Path.DirectorySeparatorChar);

                // propertyGroup.SetProperty("MSBUILDENABLEALLPROPERTYFUNCTIONS", "1");

                engine.GlobalProperties = propertyGroup;

                var project = engine.CreateNewProject();
                project.Load(projectFilePath);
                var buildResult = engine.BuildProjectFile(projectFilePath, new[] { "ResolveReferences" }, propertyGroup, null, BuildSettings.None, null);

                if (!buildResult)
                {
                    return(null);
                }

                var itemsLookup = project.EvaluatedItems.OfType <BuildItem>()
                                  .ToLookup(g => g.Name);

                var properties = project.EvaluatedProperties.OfType <BuildProperty>()
                                 .ToDictionary(p => p.Name);

                projectFileInfo.AssemblyName    = properties["AssemblyName"].FinalValue;
                projectFileInfo.Name            = Path.GetFileNameWithoutExtension(projectFilePath);
                projectFileInfo.TargetFramework = new FrameworkName(properties["TargetFrameworkMoniker"].FinalValue);
                if (properties.ContainsKey("LangVersion"))
                {
                    projectFileInfo.SpecifiedLanguageVersion = ToLanguageVersion(properties["LangVersion"].FinalValue);
                }
                projectFileInfo.ProjectId  = new Guid(properties["ProjectGuid"].FinalValue.TrimStart('{').TrimEnd('}'));
                projectFileInfo.TargetPath = properties["TargetPath"].FinalValue;

                // REVIEW: FullPath here returns the wrong physical path, we need to figure out
                // why. We must be setting up something incorrectly
                projectFileInfo.SourceFiles = itemsLookup["Compile"]
                                              .Select(b => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, b.FinalItemSpec)))
                                              .ToList();

                projectFileInfo.References = itemsLookup["ReferencePath"]
                                             .Where(p => !p.HasMetadata("Project"))
                                             .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec)))
                                             .ToList();

                projectFileInfo.ProjectReferences = itemsLookup["ProjectReference"]
                                                    .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec)))
                                                    .ToList();

                projectFileInfo.Analyzers = itemsLookup["Analyzer"]
                                            .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec)))
                                            .ToList();

                var defineConstants = properties["DefineConstants"].FinalValue;
                if (!string.IsNullOrWhiteSpace(defineConstants))
                {
                    projectFileInfo.DefineConstants = defineConstants.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList();
                }
            }
#else
            // TODO: Shell out to msbuild/xbuild here?
#endif
            return(projectFileInfo);
        }
예제 #19
0
        public void Initalize(IConfiguration configuration)
        {
            _options = new MSBuildOptions();
            OptionsServices.ReadProperties(_options, configuration);

            var solutionFilePath = _env.SolutionFilePath;

            if (string.IsNullOrEmpty(solutionFilePath))
            {
                var solutions = Directory.GetFiles(_env.Path, "*.sln");
                var result    = SolutionPicker.ChooseSolution(_env.Path, solutions);

                if (result.Message != null)
                {
                    _logger.LogInformation(result.Message);
                }

                if (result.Solution == null)
                {
                    return;
                }

                solutionFilePath = result.Solution;
            }

            SolutionFile solutionFile = null;

            _context.SolutionPath = solutionFilePath;

            using (var stream = File.OpenRead(solutionFilePath))
            {
                using (var reader = new StreamReader(stream))
                {
                    solutionFile = SolutionFile.Parse(reader);
                }
            }
            _logger.LogInformation($"Detecting projects in '{solutionFilePath}'.");

            foreach (var block in solutionFile.ProjectBlocks)
            {
                if (!_supportsProjectTypes.Contains(block.ProjectTypeGuid))
                {
                    if (UnityTypeGuid(block.ProjectName) != block.ProjectTypeGuid)
                    {
                        _logger.LogWarning("Skipped unsupported project type '{0}'", block.ProjectPath);
                        continue;
                    }
                }

                if (_context.ProjectGuidToWorkspaceMapping.ContainsKey(block.ProjectGuid))
                {
                    continue;
                }

                var projectFilePath = Path.GetFullPath(Path.GetFullPath(Path.Combine(_env.Path, block.ProjectPath.Replace('\\', Path.DirectorySeparatorChar))));

                _logger.LogInformation($"Loading project from '{projectFilePath}'.");

                var projectFileInfo = CreateProject(projectFilePath);

                if (projectFileInfo == null)
                {
                    continue;
                }

                var compilationOptions = new CSharpCompilationOptions(projectFileInfo.OutputKind);
#if DNX451
                compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
#endif

                if (projectFileInfo.AllowUnsafe)
                {
                    compilationOptions = compilationOptions.WithAllowUnsafe(true);
                }

                var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(projectFileInfo.Name),
                                                     VersionStamp.Create(),
                                                     projectFileInfo.Name,
                                                     projectFileInfo.AssemblyName,
                                                     LanguageNames.CSharp,
                                                     projectFileInfo.ProjectFilePath,
                                                     compilationOptions: compilationOptions);

                _workspace.AddProject(projectInfo);

                projectFileInfo.WorkspaceId = projectInfo.Id;

                _context.Projects[projectFileInfo.ProjectFilePath]        = projectFileInfo;
                _context.ProjectGuidToWorkspaceMapping[block.ProjectGuid] = projectInfo.Id;

                _watcher.Watch(projectFilePath, OnProjectChanged);
            }

            foreach (var projectFileInfo in _context.Projects.Values)
            {
                UpdateProject(projectFileInfo);
            }
        }
 public OmniSharpOptions()
 {
     Dnx               = new DnxOptions();
     MsBuild           = new MSBuildOptions();
     FormattingOptions = new FormattingOptions();
 }
예제 #21
0
 public OmniSharpOptions()
 {
     AspNet5           = new AspNet5Options();
     MsBuild           = new MSBuildOptions();
     FormattingOptions = new FormattingOptions();
 }
예제 #22
0
        public static ProjectFileInfo Create(
            MSBuildOptions options,
            ILogger logger,
            string solutionDirectory,
            string projectFilePath,
            ICollection <MSBuildDiagnosticsMessage> diagnostics)
        {
            var projectFileInfo = new ProjectFileInfo();

            projectFileInfo.ProjectFilePath = projectFilePath;

            if (!PlatformHelper.IsMono)
            {
                var properties = new Dictionary <string, string>
                {
                    { "DesignTimeBuild", "true" },
                    { "BuildProjectReferences", "false" },
                    { "_ResolveReferenceDependencies", "true" },
                    { "SolutionDir", solutionDirectory + Path.DirectorySeparatorChar }
                };

                if (!string.IsNullOrWhiteSpace(options.VisualStudioVersion))
                {
                    properties.Add("VisualStudioVersion", options.VisualStudioVersion);
                }

                var collection = new ProjectCollection(properties);

                logger.LogInformation("Using toolset {0} for {1}", options.ToolsVersion ?? collection.DefaultToolsVersion, projectFilePath);

                var project = string.IsNullOrEmpty(options.ToolsVersion) ?
                              collection.LoadProject(projectFilePath) :
                              collection.LoadProject(projectFilePath, options.ToolsVersion);

                var projectInstance = project.CreateProjectInstance();
                var buildResult     = projectInstance.Build("ResolveReferences", new Microsoft.Build.Framework.ILogger[] { new MSBuildLogForwarder(logger, diagnostics) });

                if (!buildResult)
                {
                    return(null);
                }

                projectFileInfo.AssemblyName             = projectInstance.GetPropertyValue("AssemblyName");
                projectFileInfo.Name                     = projectInstance.GetPropertyValue("ProjectName");
                projectFileInfo.TargetFramework          = new FrameworkName(projectInstance.GetPropertyValue("TargetFrameworkMoniker"));
                projectFileInfo.SpecifiedLanguageVersion = ToLanguageVersion(projectInstance.GetPropertyValue("LangVersion"));
                projectFileInfo.ProjectId                = new Guid(projectInstance.GetPropertyValue("ProjectGuid").TrimStart('{').TrimEnd('}'));
                projectFileInfo.TargetPath               = projectInstance.GetPropertyValue("TargetPath");
                var outputType = projectInstance.GetPropertyValue("OutputType");
                switch (outputType)
                {
                case "Library":
                    projectFileInfo.OutputKind = OutputKind.DynamicallyLinkedLibrary;
                    break;

                case "WinExe":
                    projectFileInfo.OutputKind = OutputKind.WindowsApplication;
                    break;

                default:
                case "Exe":
                    projectFileInfo.OutputKind = OutputKind.ConsoleApplication;
                    break;
                }

                projectFileInfo.SourceFiles =
                    projectInstance.GetItems("Compile")
                    .Select(p => p.GetMetadataValue("FullPath"))
                    .ToList();


                if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
                {
                    var framework = new NuGetFramework(projectFileInfo.TargetFramework.Identifier,
                                                       projectFileInfo.TargetFramework.Version,
                                                       projectFileInfo.TargetFramework.Profile);

                    // CoreCLR MSBuild won't be able to resolve framework assemblies from mono now.
                    projectFileInfo.References = projectInstance
                                                 .GetItems("ReferencePath")
                                                 .Where(p => !string.Equals("ProjectReference", p.GetMetadataValue("ReferenceSourceTarget"), StringComparison.OrdinalIgnoreCase))
                                                 .Select(p =>
                    {
                        var fullpath = p.GetMetadataValue("FullPath");
                        if (!File.Exists(fullpath))
                        {
                            string referenceName = Path.GetFileNameWithoutExtension(fullpath);
                            string path;
                            Version version;
                            if (FrameworkReferenceResolver.Default.TryGetAssembly(referenceName, framework, out path, out version))
                            {
                                logger.LogInformation($"Resolved refernce path: {referenceName} => {version} at {path}");
                            }
                            else
                            {
                                logger.LogError($"Fail to resolve reference path for {referenceName}");
                            }

                            return(path);
                        }
                        else
                        {
                            logger.LogInformation($"Resolved reference path {fullpath} by MSBuild.");
                            return(fullpath);
                        }
                    }).ToList();
                }
                else
                {
                    projectFileInfo.References =
                        projectInstance.GetItems("ReferencePath")
                        .Where(p => !string.Equals("ProjectReference", p.GetMetadataValue("ReferenceSourceTarget"), StringComparison.OrdinalIgnoreCase))
                        .Select(p => p.GetMetadataValue("FullPath"))
                        .ToList();
                }

                projectFileInfo.ProjectReferences =
                    projectInstance.GetItems("ProjectReference")
                    .Select(p => p.GetMetadataValue("FullPath"))
                    .ToList();

                projectFileInfo.Analyzers =
                    projectInstance.GetItems("Analyzer")
                    .Select(p => p.GetMetadataValue("FullPath"))
                    .ToList();

                var allowUnsafe = projectInstance.GetPropertyValue("AllowUnsafeBlocks");
                if (!string.IsNullOrWhiteSpace(allowUnsafe))
                {
                    projectFileInfo.AllowUnsafe = Convert.ToBoolean(allowUnsafe);
                }

                var defineConstants = projectInstance.GetPropertyValue("DefineConstants");
                if (!string.IsNullOrWhiteSpace(defineConstants))
                {
                    projectFileInfo.DefineConstants = defineConstants.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList();
                }

                var signAssembly = projectInstance.GetPropertyValue("SignAssembly");
                if (!string.IsNullOrWhiteSpace(signAssembly))
                {
                    projectFileInfo.SignAssembly = Convert.ToBoolean(signAssembly);
                }

                projectFileInfo.AssemblyOriginatorKeyFile = projectInstance.GetPropertyValue("AssemblyOriginatorKeyFile");

                var documentationFile = projectInstance.GetPropertyValue("DocumentationFile");
                if (!string.IsNullOrWhiteSpace(documentationFile))
                {
                    projectFileInfo.GenerateXmlDocumentation = true;
                }
            }
            else
            {
#if NET451
                // On mono we need to use this API since the ProjectCollection
                // isn't fully implemented
#pragma warning disable CS0618
                var engine = Engine.GlobalEngine;
                engine.DefaultToolsVersion = "4.0";
#pragma warning restore CS0618
                // engine.RegisterLogger(new ConsoleLogger());
                engine.RegisterLogger(new MSBuildLogForwarder(logger, diagnostics));

                var propertyGroup = new BuildPropertyGroup();
                propertyGroup.SetProperty("DesignTimeBuild", "true");
                propertyGroup.SetProperty("BuildProjectReferences", "false");
                // Dump entire assembly reference closure
                propertyGroup.SetProperty("_ResolveReferenceDependencies", "true");
                propertyGroup.SetProperty("SolutionDir", solutionDirectory + Path.DirectorySeparatorChar);

                // propertyGroup.SetProperty("MSBUILDENABLEALLPROPERTYFUNCTIONS", "1");

                engine.GlobalProperties = propertyGroup;

                var project = engine.CreateNewProject();
                project.Load(projectFilePath);
                var buildResult = engine.BuildProjectFile(projectFilePath, new[] { "ResolveReferences" }, propertyGroup, null, BuildSettings.None, null);

                if (!buildResult)
                {
                    return(null);
                }

                var itemsLookup = project.EvaluatedItems.OfType <BuildItem>()
                                  .ToLookup(g => g.Name);

                var properties = project.EvaluatedProperties.OfType <BuildProperty>()
                                 .ToDictionary(p => p.Name);

                projectFileInfo.AssemblyName    = properties["AssemblyName"].FinalValue;
                projectFileInfo.Name            = Path.GetFileNameWithoutExtension(projectFilePath);
                projectFileInfo.TargetFramework = new FrameworkName(properties["TargetFrameworkMoniker"].FinalValue);
                if (properties.ContainsKey("LangVersion"))
                {
                    projectFileInfo.SpecifiedLanguageVersion = ToLanguageVersion(properties["LangVersion"].FinalValue);
                }
                projectFileInfo.ProjectId  = new Guid(properties["ProjectGuid"].FinalValue.TrimStart('{').TrimEnd('}'));
                projectFileInfo.TargetPath = properties["TargetPath"].FinalValue;

                // REVIEW: FullPath here returns the wrong physical path, we need to figure out
                // why. We must be setting up something incorrectly
                projectFileInfo.SourceFiles = itemsLookup["Compile"]
                                              .Select(b => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, b.FinalItemSpec)))
                                              .ToList();

                projectFileInfo.References = itemsLookup["ReferencePath"]
                                             .Where(p => !p.HasMetadata("Project"))
                                             .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec)))
                                             .ToList();

                projectFileInfo.ProjectReferences = itemsLookup["ProjectReference"]
                                                    .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec)))
                                                    .ToList();

                projectFileInfo.Analyzers = itemsLookup["Analyzer"]
                                            .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec)))
                                            .ToList();

                var allowUnsafe = properties.GetPropertyValue("AllowUnsafeBlocks");
                if (!string.IsNullOrWhiteSpace(allowUnsafe))
                {
                    projectFileInfo.AllowUnsafe = Convert.ToBoolean(allowUnsafe);
                }

                var defineConstants = properties.GetPropertyValue("DefineConstants");
                if (!string.IsNullOrWhiteSpace(defineConstants))
                {
                    projectFileInfo.DefineConstants = defineConstants.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList();
                }

                var signAssembly = properties["SignAssembly"].FinalValue;
                if (!string.IsNullOrWhiteSpace(signAssembly))
                {
                    projectFileInfo.SignAssembly = Convert.ToBoolean(signAssembly);
                }

                projectFileInfo.AssemblyOriginatorKeyFile = properties["AssemblyOriginatorKeyFile"].FinalValue;

                var documentationFile = properties["DocumentationFile"].FinalValue;
                if (!string.IsNullOrWhiteSpace(documentationFile))
                {
                    projectFileInfo.GenerateXmlDocumentation = true;
                }
#endif
            }

            return(projectFileInfo);
        }
        public void Initalize(IConfiguration configuration)
        {
            _options = new MSBuildOptions();
            ConfigurationBinder.Bind(configuration, _options);

            if (_options.WaitForDebugger)
            {
                Console.WriteLine($"Attach to process {System.Diagnostics.Process.GetCurrentProcess().Id}");
                while (!System.Diagnostics.Debugger.IsAttached)
                {
                    System.Threading.Thread.Sleep(100);
                }
            }

            var solutionFilePath = _env.SolutionFilePath;

            if (string.IsNullOrEmpty(solutionFilePath))
            {
                var solutions = Directory.GetFiles(_env.Path, "*.sln");
                var result    = SolutionPicker.ChooseSolution(_env.Path, solutions);

                if (result.Message != null)
                {
                    _logger.LogInformation(result.Message);
                }

                if (result.Solution == null)
                {
                    return;
                }

                solutionFilePath = result.Solution;
            }

            SolutionFile solutionFile = null;

            _context.SolutionPath = solutionFilePath;

            using (var stream = File.OpenRead(solutionFilePath))
            {
                using (var reader = new StreamReader(stream))
                {
                    solutionFile = SolutionFile.Parse(reader);
                }
            }
            _logger.LogInformation($"Detecting projects in '{solutionFilePath}'.");

            foreach (var block in solutionFile.ProjectBlocks)
            {
                if (!_supportsProjectTypes.Contains(block.ProjectTypeGuid))
                {
                    if (UnityTypeGuid(block.ProjectName) != block.ProjectTypeGuid)
                    {
                        _logger.LogWarning("Skipped unsupported project type '{0}'", block.ProjectPath);
                        continue;
                    }
                }

                if (_context.ProjectGuidToWorkspaceMapping.ContainsKey(block.ProjectGuid))
                {
                    continue;
                }

                var projectFilePath = Path.GetFullPath(Path.GetFullPath(Path.Combine(_env.Path, block.ProjectPath.Replace('\\', Path.DirectorySeparatorChar))));

                _logger.LogInformation($"Loading project from '{projectFilePath}'.");

                var projectFileInfo = CreateProject(projectFilePath);

                if (projectFileInfo == null)
                {
                    continue;
                }

                var compilationOptions = new CSharpCompilationOptions(projectFileInfo.OutputKind);
                compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

                if (projectFileInfo.AllowUnsafe)
                {
                    compilationOptions = compilationOptions.WithAllowUnsafe(true);
                }

                if (projectFileInfo.SignAssembly && !string.IsNullOrEmpty(projectFileInfo.AssemblyOriginatorKeyFile))
                {
                    var keyFile = Path.Combine(projectFileInfo.ProjectDirectory, projectFileInfo.AssemblyOriginatorKeyFile);
                    compilationOptions = compilationOptions.WithStrongNameProvider(new DesktopStrongNameProvider())
                                         .WithCryptoKeyFile(keyFile);
                }

                if (projectFileInfo.GenerateXmlDocumentation)
                {
                    compilationOptions = compilationOptions.WithXmlReferenceResolver(XmlFileResolver.Default);
                }

                var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(projectFileInfo.Name),
                                                     VersionStamp.Create(),
                                                     projectFileInfo.Name,
                                                     projectFileInfo.AssemblyName,
                                                     LanguageNames.CSharp,
                                                     projectFileInfo.ProjectFilePath,
                                                     compilationOptions: compilationOptions);

                _workspace.AddProject(projectInfo);

                projectFileInfo.WorkspaceId = projectInfo.Id;

                _context.Projects[projectFileInfo.ProjectFilePath]        = projectFileInfo;
                _context.ProjectGuidToWorkspaceMapping[block.ProjectGuid] = projectInfo.Id;

                _watcher.Watch(projectFilePath, OnProjectChanged);
            }

            foreach (var projectFileInfo in _context.Projects.Values)
            {
                UpdateProject(projectFileInfo);
            }
        }
 public OmniSharpOptions()
 {
     AspNet5 = new AspNet5Options();
     MsBuild = new MSBuildOptions();
     FormattingOptions = new FormattingOptions();
 }