コード例 #1
0
        public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo)
        {
            // HACK: Fetch this service to ensure it's still created on the UI thread; once this is moved off we'll need to fix up it's constructor to be free-threaded.
            _visualStudioWorkspaceImpl.Services.GetRequiredService <VisualStudioMetadataReferenceManager>();

            // HACK: since we're on the UI thread, ensure we initialize our options provider which depends on a UI-affinitized experimentation service
            _visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitialized();

            var id           = ProjectId.CreateNewId(projectSystemName);
            var assemblyName = creationInfo.AssemblyName ?? projectSystemName;

            // We will use the project system name as the default display name of the project
            var project = new VisualStudioProject(
                _visualStudioWorkspaceImpl,
                _dynamicFileInfoProviders,
                _hostDiagnosticUpdateSource,
                id,
                displayName: projectSystemName,
                language,
                assemblyName: assemblyName,
                compilationOptions: creationInfo.CompilationOptions,
                filePath: creationInfo.FilePath,
                parseOptions: creationInfo.ParseOptions);

            var versionStamp = creationInfo.FilePath != null?VersionStamp.Create(File.GetLastWriteTimeUtc(creationInfo.FilePath))
                                   : VersionStamp.Create();

            _visualStudioWorkspaceImpl.AddProjectToInternalMaps(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectSystemName);

            _visualStudioWorkspaceImpl.ApplyChangeToWorkspace(w =>
            {
                var projectInfo = ProjectInfo.Create(
                    id,
                    versionStamp,
                    name: projectSystemName,
                    assemblyName: assemblyName,
                    language: language,
                    filePath: creationInfo.FilePath,
                    compilationOptions: creationInfo.CompilationOptions,
                    parseOptions: creationInfo.ParseOptions)
                                  .WithTelemetryId(creationInfo.ProjectGuid);

                // If we don't have any projects and this is our first project being added, then we'll create a new SolutionId
                if (w.CurrentSolution.ProjectIds.Count == 0)
                {
                    // Fetch the current solution path. Since we're on the UI thread right now, we can do that.
                    string?solutionFilePath = null;
                    var solution            = (IVsSolution)Shell.ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution));
                    if (solution != null)
                    {
                        if (ErrorHandler.Failed(solution.GetSolutionInfo(out _, out solutionFilePath, out _)))
                        {
                            // Paranoia: if the call failed, we definitely don't want to use any stuff that was set
                            solutionFilePath = null;
                        }
                    }

                    var solutionSessionId = GetSolutionSessionId();

                    w.OnSolutionAdded(
                        SolutionInfo.Create(
                            SolutionId.CreateNewId(solutionFilePath),
                            VersionStamp.Create(),
                            solutionFilePath,
                            projects: new[] { projectInfo },
                            analyzerReferences: w.CurrentSolution.AnalyzerReferences)
                        .WithTelemetryId(solutionSessionId));
                }
                else
                {
                    w.OnProjectAdded(projectInfo);
                }

                _visualStudioWorkspaceImpl.RefreshProjectExistsUIContextForLanguage(language);
            });

            return(project);
コード例 #2
0
        public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo)
        {
            // HACK: Fetch this service to ensure it's still created on the UI thread; once this is moved off we'll need to fix up it's constructor to be free-threaded.
            _visualStudioWorkspaceImpl.Services.GetRequiredService <VisualStudioMetadataReferenceManager>();

            // HACK: since we're on the UI thread, ensure we initialize our options provider which depends on a UI-affinitized experimentation service
            _visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitialized();

            var id = ProjectId.CreateNewId(projectSystemName);
            var directoryNameOpt = creationInfo.FilePath != null?Path.GetDirectoryName(creationInfo.FilePath) : null;

            // We will use the project system name as the default display name of the project
            var project = new VisualStudioProject(_visualStudioWorkspaceImpl, _dynamicFileInfoProviders, _hostDiagnosticUpdateSource, id, displayName: projectSystemName, language, directoryNameOpt);

            var versionStamp = creationInfo.FilePath != null?VersionStamp.Create(File.GetLastWriteTimeUtc(creationInfo.FilePath))
                                   : VersionStamp.Create();

            var assemblyName = creationInfo.AssemblyName ?? projectSystemName;

            _visualStudioWorkspaceImpl.AddProjectToInternalMaps(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectSystemName);

            _visualStudioWorkspaceImpl.ApplyChangeToWorkspace(w =>
            {
                var projectInfo = ProjectInfo.Create(
                    id,
                    versionStamp,
                    name: projectSystemName,
                    assemblyName: assemblyName,
                    language: language,
                    filePath: creationInfo.FilePath,
                    compilationOptions: creationInfo.CompilationOptions,
                    parseOptions: creationInfo.ParseOptions);

                // If we don't have any projects and this is our first project being added, then we'll create a new SolutionId
                if (w.CurrentSolution.ProjectIds.Count == 0)
                {
                    // Fetch the current solution path. Since we're on the UI thread right now, we can do that.
                    string solutionFilePath = null;
                    var solution            = (IVsSolution)Shell.ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution));
                    if (solution != null)
                    {
                        if (ErrorHandler.Failed(solution.GetSolutionInfo(out _, out solutionFilePath, out _)))
                        {
                            // Paranoia: if the call failed, we definitely don't want to use any stuff that was set
                            solutionFilePath = null;
                        }
                    }

                    w.OnSolutionAdded(
                        SolutionInfo.Create(
                            SolutionId.CreateNewId(solutionFilePath),
                            VersionStamp.Create(),
                            solutionFilePath,
                            projects: new[] { projectInfo }));

                    // set working folder for the persistent service
                    var persistenceService = w.Services.GetRequiredService <IPersistentStorageLocationService>() as VisualStudioPersistentStorageLocationService;
                    persistenceService?.UpdateForVisualStudioWorkspace(w);
                }
                else
                {
                    w.OnProjectAdded(projectInfo);
                }
            });

            // We do all these sets after the w.OnProjectAdded, as the setting of these properties is going to try to modify the workspace
            // again. Those modifications will all implicitly do nothing, since the workspace already has the values from above.
            // We could pass these all through the constructor (but that gets verbose), or have some other control to ignore these,
            // but that seems like overkill.
            project.AssemblyName       = assemblyName;
            project.CompilationOptions = creationInfo.CompilationOptions;
            project.FilePath           = creationInfo.FilePath;
            project.ParseOptions       = creationInfo.ParseOptions;

            return(project);
        }
コード例 #3
0
        public async Task <VisualStudioProject> CreateAndAddToWorkspaceAsync(
            string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo, CancellationToken cancellationToken)
        {
            // HACK: Fetch this service to ensure it's still created on the UI thread; once this is
            // moved off we'll need to fix up it's constructor to be free-threaded.

            await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            _visualStudioWorkspaceImpl.Services.GetRequiredService <VisualStudioMetadataReferenceManager>();

            // Since we're on the UI thread here anyways, use that as an opportunity to grab the
            // IVsSolution object and solution file path.
            //
            // ConfigureAwait(true) as we have to come back to the UI thread to do the cast to IVsSolution2.
            var solution = (IVsSolution2?)await _serviceProvider.GetServiceAsync(typeof(SVsSolution)).ConfigureAwait(true);

            var solutionFilePath = solution != null && ErrorHandler.Succeeded(solution.GetSolutionInfo(out _, out var filePath, out _))
                ? filePath
                : null;

            await _visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitializedAsync(cancellationToken).ConfigureAwait(true);

            // From this point on, we start mutating the solution.  So make us non cancellable.
            cancellationToken = CancellationToken.None;

            var id           = ProjectId.CreateNewId(projectSystemName);
            var assemblyName = creationInfo.AssemblyName ?? projectSystemName;

            // We will use the project system name as the default display name of the project
            var project = new VisualStudioProject(
                _visualStudioWorkspaceImpl,
                _dynamicFileInfoProviders,
                _hostDiagnosticUpdateSource,
                id,
                displayName: projectSystemName,
                language,
                assemblyName: assemblyName,
                compilationOptions: creationInfo.CompilationOptions,
                filePath: creationInfo.FilePath,
                parseOptions: creationInfo.ParseOptions);

            var versionStamp = creationInfo.FilePath != null?VersionStamp.Create(File.GetLastWriteTimeUtc(creationInfo.FilePath))
                                   : VersionStamp.Create();

            _visualStudioWorkspaceImpl.AddProjectToInternalMaps(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectSystemName);

            _visualStudioWorkspaceImpl.ApplyChangeToWorkspace(w =>
            {
                var projectInfo = ProjectInfo.Create(
                    id,
                    versionStamp,
                    name: projectSystemName,
                    assemblyName: assemblyName,
                    language: language,
                    filePath: creationInfo.FilePath,
                    compilationOptions: creationInfo.CompilationOptions,
                    parseOptions: creationInfo.ParseOptions)
                                  .WithTelemetryId(creationInfo.ProjectGuid);

                // If we don't have any projects and this is our first project being added, then we'll create a new SolutionId
                if (w.CurrentSolution.ProjectIds.Count == 0)
                {
                    var solutionSessionId = GetSolutionSessionId();

                    w.OnSolutionAdded(
                        SolutionInfo.Create(
                            SolutionId.CreateNewId(solutionFilePath),
                            VersionStamp.Create(),
                            solutionFilePath,
                            projects: new[] { projectInfo },
                            analyzerReferences: w.CurrentSolution.AnalyzerReferences)
                        .WithTelemetryId(solutionSessionId));
                }
                else
                {
                    w.OnProjectAdded(projectInfo);
                }
            });

            _visualStudioWorkspaceImpl.RefreshProjectExistsUIContextForLanguage(language);

            return(project);