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); }
/// <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); } }
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); }
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); }
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); }
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); }
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); } } }
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); }
protected override async Task InitializeCoreAsync(CancellationToken cancellationToken) { await _threadingService.SwitchToUIThread(cancellationToken); Verify.HResult(_solution.Value.AdviseSolutionEvents(this, out _cookie)); }