public async Task <Version?> GetVSVersionAsync(ProjectSystem.VS.IVsService <IVsAppId> vsAppIdService)
        {
            await _threadingService.SwitchToUIThread();

            IVsAppId vsAppId = await vsAppIdService.GetValueAsync();

            if (ErrorHandler.Succeeded(vsAppId.GetProperty((int)VSAPropID.VSAPROPID_ProductSemanticVersion, out object oVersion)) &&
                oVersion is string semVersion)
            {
                // This is a semantic version string. We only care about the non-semantic version part
                int index = semVersion.IndexOfAny(Delimiter.PlusAndMinus);
                if (index != -1)
                {
                    semVersion = semVersion.Substring(0, index);
                }

                if (Version.TryParse(semVersion, out Version vsVersion))
                {
                    return(vsVersion);
                }
            }

            return(null);
        }
        /// <summary>
        /// <see cref="IVsShellUtilitiesHelper.GetVSVersionAsync"/>
        /// </summary>
        public async Task <Version> GetVSVersionAsync(IServiceProvider serviceProvider)
        {
            await _threadingService.SwitchToUIThread();

            IVsAppId vsAppId = serviceProvider.GetService <IVsAppId, SVsAppId>();

            if (ErrorHandler.Succeeded(vsAppId.GetProperty((int)VSAPropID.VSAPROPID_ProductSemanticVersion, out object oVersion)) &&
                oVersion is string semVersion)
            {
                // This is a semantic version string. We only care about the non-semantic version part
                int index = semVersion.IndexOfAny(new char[] { '-', '+' });
                if (index != -1)
                {
                    semVersion = semVersion.Substring(0, index);
                }

                if (Version.TryParse(semVersion, out Version vsVersion))
                {
                    return(vsVersion);
                }
            }

            return(null);
        }
Exemple #3
0
        /// <summary>
        /// Returns the provider which knows how to launch the profile type.
        /// </summary>
        public async Task <IDebugProfileLaunchTargetsProvider?> GetLaunchTargetsProviderAsync(ILaunchProfile profile)
        {
            // WORKAROUND: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1152611
            await _threadingService.SwitchToUIThread();

            // We search through the imports in order to find the one which supports the profile
            foreach (Lazy <IDebugProfileLaunchTargetsProvider, IOrderPrecedenceMetadataView> provider in LaunchTargetsProviders)
            {
                if (provider.Value.SupportsProfile(profile))
                {
                    return(provider.Value);
                }
            }

            return(null);
        }
        private async Task <string?> GetCompilerRootAsync(SVsServiceProvider?serviceProvider)
        {
            await _threadingService.SwitchToUIThread();

            // https://github.com/dotnet/roslyn-sdk/issues/729 : don't hardcode net fx compiler
            var shell = (IVsShell?)serviceProvider?.GetService(typeof(SVsShell));

            if (shell is object &&
                shell.GetProperty((int)__VSSPROPID2.VSSPROPID_InstallRootDir, out var rootDirObj) == VSConstants.S_OK &&
                rootDirObj is string rootDir)
            {
                return(Path.Combine(rootDir, "MSBuild", "Current", "Bin", "Roslyn"));
            }

            return(null);
        }
        /// <summary>
        /// Sets the value of the property in the source assembly attribute.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task SetPropertyValueAsync(string value)
        {
            Project project = GetActiveProject();

            if (project == null)
            {
                return;
            }

            AttributeData attribute = await GetAttributeAsync(_assemblyAttributeFullName, project).ConfigureAwait(false);

            if (attribute == null)
            {
                return;
            }

            SyntaxNode attributeNode = await attribute.ApplicationSyntaxReference.GetSyntaxAsync().ConfigureAwait(false);

            var syntaxGenerator = SyntaxGenerator.GetGenerator(project);
            IReadOnlyList <SyntaxNode> arguments = syntaxGenerator.GetAttributeArguments(attributeNode);

            // The attributes of interest to us have one argument. If there are more then we have broken code - don't change that.
            if (arguments.Count == 1)
            {
                SyntaxNode argumentNode = arguments[0];
                SyntaxNode newNode;
                if (attribute.AttributeConstructor.Parameters.FirstOrDefault()?.Type.SpecialType == SpecialType.System_Boolean)
                {
                    newNode = syntaxGenerator.AttributeArgument(bool.Parse(value) ? syntaxGenerator.TrueLiteralExpression() : syntaxGenerator.FalseLiteralExpression());
                }
                else
                {
                    newNode = syntaxGenerator.AttributeArgument(syntaxGenerator.LiteralExpression(value));
                }

                newNode = newNode.WithTriviaFrom(argumentNode);
                DocumentEditor editor = await DocumentEditor.CreateAsync(project.GetDocument(attributeNode.SyntaxTree)).ConfigureAwait(false);

                editor.ReplaceNode(argumentNode, newNode);

                // Apply changes needs to happen on the UI Thread.
                await _threadingService.SwitchToUIThread();

                _workspace.TryApplyChanges(editor.GetChangedDocument().Project.Solution);
            }
        }
Exemple #6
0
        public VsService([Import(typeof(SAsyncServiceProvider))] IAsyncServiceProvider serviceProvider, IProjectThreadingService threadingService)
        {
            Requires.NotNull(serviceProvider, nameof(serviceProvider));
            Requires.NotNull(threadingService, nameof(threadingService));

            _value = new AsyncLazy <T>(async() =>
            {
                // If the service request requires a package load, GetServiceAsync will
                // happily do that on a background thread.
                object iunknown = await serviceProvider.GetServiceAsync(ServiceType);

                // We explicitly switch to the UI thread to avoid doing a QueryInterface
                // via blocking RPC for STA objects when we cast explicitly to the type
                await threadingService.SwitchToUIThread();

                return((T)iunknown);
            }, threadingService.JoinableTaskFactory);
        }
Exemple #7
0
        private async Task NavigateToAsync(IProjectTree node)
        {
            string?browsePath = await DependencyServices.GetBrowsePathAsync(_project, node);

            if (browsePath == null)
            {
                return;
            }

            await _threadingService.SwitchToUIThread();

            // Find the hierarchy based on the project file, and then select it
            var hierarchy = (IVsUIHierarchy?)_projectServices.GetHierarchyByProjectName(browsePath);

            if (hierarchy == null || !_solutionExplorer.IsAvailable)
            {
                return;
            }

            _ = _solutionExplorer.Select(hierarchy, HierarchyId.Root);
        }
Exemple #8
0
        private async Task <IVsOutputWindowPane> CreateOutputWindowPaneAsync()
        {
            await _threadingService.SwitchToUIThread();

            IVsOutputWindow outputWindow = _outputWindow.Value;

            if (outputWindow == null)
            {
                return(null);    // Command-line build
            }
            Guid activePane = outputWindow.GetActivePane();

            IVsOutputWindowPane pane = CreateProjectOutputWindowPane(outputWindow);

            // Creating a pane causes it to be "active", reset the active pane back to the previously active pane
            if (activePane != Guid.Empty)
            {
                outputWindow.ActivatePane(activePane);
            }

            return(pane);
        }
Exemple #9
0
        public int TranslateAccelerator(VsMsg[] pMsg)
        {
            if (pMsg == null || pMsg.Length == 0)
            {
                throw new ArgumentNullException(nameof(pMsg));
            }

            var xMsg     = pMsg[0];
            var xMessage = new Message();

            xMessage.hwnd    = xMsg.hwnd;
            xMessage.message = (int)xMsg.message;
            xMessage.wParam  = xMsg.wParam;
            xMessage.lParam  = xMsg.lParam;
            xMessage.time    = (int)xMsg.time;
            xMessage.pt_x    = xMsg.pt.x;
            xMessage.pt_y    = xMsg.pt.y;

            var xUsed = ComponentDispatcher.RaiseThreadMessage(ref xMessage);

            if (xUsed)
            {
                xMsg.message = (uint)xMessage.message;
                xMsg.wParam  = xMessage.wParam;
                xMsg.lParam  = xMessage.lParam;

                return(VSConstants.S_OK);
            }

            int xResult = 0;

            if (mPropertyPageSite != null)
            {
                ProjectThreadingService.SwitchToUIThread();
                xResult = mPropertyPageSite.TranslateAccelerator(pMsg);
            }

            return(xResult);
        }
Exemple #10
0
        public async Task RenameAsync(Project myNewProject)
        {
            Document newDocument = (from d in myNewProject.Documents where StringComparers.Paths.Equals(d.FilePath, _newFilePath) select d).FirstOrDefault();

            if (newDocument == null)
            {
                return;
            }

            var root = await newDocument.GetSyntaxRootAsync().ConfigureAwait(false);

            if (root == null)
            {
                return;
            }

            string oldName = Path.GetFileNameWithoutExtension(_oldFilePath);
            string newName = Path.GetFileNameWithoutExtension(newDocument.FilePath);

            var declaration = root.DescendantNodes().Where(n => HasMatchingSyntaxNode(newDocument, n, oldName)).FirstOrDefault();

            if (declaration == null)
            {
                return;
            }

            var semanticModel = await newDocument.GetSemanticModelAsync().ConfigureAwait(false);

            if (semanticModel == null)
            {
                return;
            }

            var symbol = semanticModel.GetDeclaredSymbol(declaration);

            if (symbol == null)
            {
                return;
            }

            var userConfirmed = true;
            await _threadingService.SwitchToUIThread();

            var userNeedPrompt = _optionsSettings.GetPropertiesValue("Environment", "ProjectsAndSolution", "PromptForRenameSymbol", false);

            if (userNeedPrompt)
            {
                string renamePromptMessage = string.Format(Resources.RenameSymbolPrompt, oldName);

                await _threadingService.SwitchToUIThread();

                userConfirmed = _userNotificationServices.Confirm(renamePromptMessage);
            }

            if (userConfirmed)
            {
                var renamedSolution = await _roslynServices.RenameSymbolAsync(newDocument.Project.Solution, symbol, newName).ConfigureAwait(false);

                await _threadingService.SwitchToUIThread();

                var renamedSolutionApplied = _roslynServices.ApplyChangesToSolution(newDocument.Project.Solution.Workspace, renamedSolution);

                if (!renamedSolutionApplied)
                {
                    string failureMessage = string.Format(Resources.RenameSymbolFailed, oldName);
                    await _threadingService.SwitchToUIThread();

                    _userNotificationServices.NotifyFailure(failureMessage);
                }
            }
        }
Exemple #11
0
        public async Task ResetBufferAsync()
        {
            var projectXml = await _projectXmlAccessor.GetProjectXmlAsync().ConfigureAwait(false);

            var existingText = await ReadBufferXmlAsync().ConfigureAwait(false);

            var isLastSavedEqual = false;

            lock (_savedXmlLock)
            {
                // If the project xml is the same as the last thing we saved, then any changes in the editor are new changes
                // on top of the existing changes, and we should not attempt to overwrite them.
                isLastSavedEqual = projectXml.Equals(_lastSavedXml, StringComparison.Ordinal);
            }

            if (!isLastSavedEqual && !existingText.Equals(projectXml, StringComparison.Ordinal))
            {
                await _threadingService.SwitchToUIThread();

                // If the docdata is not dirty, we just update the buffer to avoid the file reload pop-up. Otherwise,
                // we write to disk, to force the pop-up.
                Verify.HResult(_docData.IsDocDataDirty(out int isDirty));
                if (Convert.ToBoolean(isDirty))
                {
                    _fileSystem.WriteAllText(FilePath, projectXml, await _unconfiguredProject.GetFileEncodingAsync().ConfigureAwait(true));
                }
                else
                {
                    var textSpan = new Span(0, _textDocument.TextBuffer.CurrentSnapshot.Length);

                    // When the buffer is being reset, it's often been set to ReadOnly. We can't update the buffer when it's readonly, so save
                    // the currently flags and turn off ReadOnly, restoring after we're done. We're on the UI thread, so this is invisible to
                    // the user.
                    Verify.HResult(_textBuffer.GetStateFlags(out uint oldFlags));
                    _textBuffer.SetStateFlags(oldFlags & ~(uint)BUFFERSTATEFLAGS.BSF_USER_READONLY);

                    // Make sure that the buffer is reset back to the old flags, regardless of TextBuffer.Replace throwing any kind of exception
                    try
                    {
                        _textDocument.TextBuffer.Replace(textSpan, projectXml);
                        // We save the DocData here so that if the user decides to Undo the change from the file itself, the editor will be considered
                        // dirty and will prompt about unsaved changes if closed before saving again.
                        _docData.SaveDocData(VSSAVEFLAGS.VSSAVE_Save, out string unused, out int cancelled);
                    }
                    finally
                    {
                        var isReadonly = (oldFlags & (uint)BUFFERSTATEFLAGS.BSF_USER_READONLY) == (uint)BUFFERSTATEFLAGS.BSF_USER_READONLY;
                        if (isReadonly)
                        {
                            Verify.HResult(_textBuffer.GetStateFlags(out uint newFlags));
                            _textBuffer.SetStateFlags(newFlags | (uint)BUFFERSTATEFLAGS.BSF_USER_READONLY);
                        }
                    }
                }
            }

            // Since we're writing to the file on disk in all scenarios, we can potentially race with the project reload mechanism during project
            // close if the file on disk has divergent changes from the temp file. This causes a series of confusing popups for the user that make
            // it very likely they will accidentally discard changes. We save here to make sure we don't run into that race.
            await _unconfiguredProject.SaveAsync().ConfigureAwait(false);
        }
Exemple #12
0
        protected override async Task InitializeCoreAsync(CancellationToken cancellationToken)
        {
            await _threadingService.SwitchToUIThread(cancellationToken);

            Verify.HResult(_solution.Value.AdviseSolutionEvents(this, out _cookie));
        }