/// <summary>
 /// <para>
 /// This is a bit of a hack. There currently isn't a good way to determine if the
 /// <paramref name="node"/> represents a project backed by the managed project
 /// system. In the interests of getting something working, here we check if the
 /// Solution Explorer thinks the node is a project and then check that it has a
 /// supported extension.
 /// </para>
 /// <para>
 /// The _right_ way to do this probably involves getting the project GUID from the
 /// node and then running that throught the Project API to determine if the project
 /// has the appropriate capabilities. At the moment there's no good way to
 /// achieve that first step, however.
 /// </para>
 /// </summary>
 private static bool NodeRepresentsAManagedProject(WorkspaceVisualNodeBase node)
 {
     return(node?.VSSelectionMoniker != null &&
            node.VSSelectionKind == CloudEnvironment.SolutionViewProjectGuid &&
            node.NodeMoniker != null &&
            s_supportedProjectExtensions.Any(extension => node.NodeMoniker.EndsWith(extension, StringComparison.OrdinalIgnoreCase)));
 }
Esempio n. 2
0
        /// <summary>
        /// Handles opening the file associated with the given <paramref name="node"/>.
        /// </summary>
        /// <param name="node"></param>
        private void OpenFile(WorkspaceVisualNodeBase node)
        {
            if (node == null ||
                string.IsNullOrEmpty(node.NodeMoniker))
            {
                return;
            }

            _taskContext.Factory.RunAsync(async() =>
            {
                var serviceContainer = _serviceProvider.GetService <SVsBrokeredServiceContainer, IBrokeredServiceContainer>();
                var serviceBroker    = serviceContainer.GetFullAccessServiceBroker();

                var openDocumentService = await serviceBroker.GetProxyAsync <IOpenDocumentService>(VisualStudioServices.VS2019_4.OpenDocumentService);

                try
                {
                    await openDocumentService.OpenDocumentAsync(node.NodeMoniker, cancellationToken: default);
                }
                finally
                {
                    (openDocumentService as IDisposable)?.Dispose();
                }
            });
        }
        /// <summary>
        /// Handles opening the file associated with the given <paramref name="node"/>.
        /// </summary>
        /// <param name="node"></param>
        private void OpenFile(WorkspaceVisualNodeBase node)
        {
            if (node == null ||
                string.IsNullOrEmpty(node.NodeMoniker))
            {
                return;
            }

            _taskContext.Factory.RunAsync(async() =>
            {
                IBrokeredServiceContainer serviceContainer        = _serviceProvider.GetService <SVsBrokeredServiceContainer, IBrokeredServiceContainer>();
                ServiceHub.Framework.IServiceBroker serviceBroker = serviceContainer.GetFullAccessServiceBroker();

                IOpenDocumentService?openDocumentService = await serviceBroker.GetProxyAsync <IOpenDocumentService>(VisualStudioServices.VS2019_4.OpenDocumentService);

                try
                {
                    if (openDocumentService != null &&
                        node is IFileSystemNode fileSystemNode)
                    {
                        await openDocumentService.OpenDocumentAsync(fileSystemNode.FullPath, cancellationToken: default);
                    }
                    //else
                    // TODO: figure out what to tell the user if we can't get the service
                    // https://github.com/dotnet/project-system/issues/6306
                }
                finally
                {
                    (openDocumentService as IDisposable)?.Dispose();
                }
            });
        }
            // Note: all the Exec commands are async, this allows us to call them in a fire and forget
            // pattern, without blocking the UI or losing any logging

            private async void ExecNpmInstallMissing(WorkspaceVisualNodeBase node)
            {
                using (var npmController = this.CreateController(node.Workspace))
                    using (var commander = npmController.CreateNpmCommander())
                    {
                        await commander.Install();
                    }
            }
 private async void ExecNpmUpdate(WorkspaceVisualNodeBase node)
 {
     using (var npmController = this.CreateController(node.Workspace))
         using (var commander = npmController.CreateNpmCommander())
         {
             await commander.UpdatePackagesAsync();
         }
 }
 public bool IsPackageManagerUISupported(WorkspaceVisualNodeBase workspaceVisualNodeBase)
 {
     if (workspaceVisualNodeBase is null)
     {
         return(false);
     }
     return(IsPackageManagerUISupportAvailable);
 }
 private void ExecNpmInstallNew(WorkspaceVisualNodeBase node)
 {
     using (var npmController = this.CreateController(node.Workspace))
         using (var npmWorker = new NpmWorker(npmController))
             using (var manager = new NpmPackageInstallWindow(npmController, npmWorker))
             {
                 manager.ShowModal();
             }
 }
Esempio n. 8
0
        /// <summary>
        /// Provides our <see cref="IWorkspaceCommandHandler"/> for nodes representing
        /// managed projects.
        /// </summary>
        public IWorkspaceCommandHandler?ProvideCommandHandler(WorkspaceVisualNodeBase parentNode)
        {
            if (NodeRepresentsAManagedProject(parentNode))
            {
                return(_commandHandler);
            }

            return(null);
        }
Esempio n. 9
0
        public IWorkspaceCommandHandler ProvideCommandHandler(WorkspaceVisualNodeBase parentNode)
        {
            if (parentNode is IFolderNode)
            {
                return(_handler);
            }

            return(null);
        }
        public IWorkspaceCommandHandler ProvideCommandHandler(WorkspaceVisualNodeBase parentNode)
        {
            if (EnsurePackageJson(parentNode))
            {
                this.outputPane.ShowWindow();
                return(this.npmHandler);
            }

            return(null);
        }
Esempio n. 11
0
        public IWorkspaceCommandHandler ProvideCommandHandler(WorkspaceVisualNodeBase parentNode)
        {
            if (EnsurePackageJson(parentNode))
            {
                return(this.npmHandler);
            }

            // we only have a command handler for 'package.json' files
            return(null);
        }
Esempio n. 12
0
            private async void ExecDynamic(WorkspaceVisualNodeBase node, uint nCmdID)
            {
                // Unfortunately the NpmController (and NpmCommander), used for the install and update commands
                // doesn't support running arbitrary scripts. And changing that is outside
                // the scope of these changes.
                var filePath = ((IFileNode)node).FullPath;

                if (TryGetCommand(nCmdID, filePath, out var commandName))
                {
                    using (var npmController = this.CreateController(node.Workspace))
                        using (var commander = npmController.CreateNpmCommander())
                        {
                            await commander.ExecuteNpmCommandAsync($"run-script {commandName}", showConsole : true);
                        }
                }
            }
Esempio n. 13
0
            private async void ExecDebugAsync(WorkspaceVisualNodeBase node)
            {
                var workspace   = node.Workspace;
                var packageJson = PackageJsonFactory.Create(((IFileNode)node).FullPath);

                //invoke debuglaunchtargetprovider on this file
                var fileContextActions = await node.Workspace.GetFileContextActionsAsync(packageJson.Main, new[] { DebugLaunchActionContext.ContextTypeGuid });

                if (fileContextActions.Any())
                {
                    // we requested a single context, so there should be a single grouping. Use the First action, since they're ordered by priority.
                    var action = fileContextActions.Single().FirstOrDefault();
                    Debug.Assert(action != null, "Why is action null, when we did get a fileContextActions?");
                    await action.ExecuteAsync(DefaultBuildProgressUpdater, CancellationToken.None);
                }
            }
        private async Task ShowPackageManagerUIAsync(WorkspaceVisualNodeBase workspaceVisualNodeBase)
        {
            await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            if (ShouldMEFBeInitialized())
            {
                await InitializeMEFAsync();
            }

            IVsWindowFrame window = await CreateNewWindowFrameAsync(workspaceVisualNodeBase);

            if (window != null)
            {
                Search(window, string.Empty);
                window.Show();
            }
        }
            private async void ExecDynamic(WorkspaceVisualNodeBase node, uint nCmdID)
            {
                // Unfortunately the NpmController (and NpmCommander), used for the install, update commands
                // doesn't support running arbitrary scripts. And changing that is outside
                // the scope of these changes.
                var filePath = ((IFileNode)node).FullPath;

                if (TryGetCommand(nCmdID, filePath, out var commandName))
                {
                    var npmPath = NpmHelpers.GetPathToNpm();

                    await NpmWorker.ExecuteNpmCommandAsync(
                        npmPath,
                        executionDirectory : Path.GetDirectoryName(filePath),
                        arguments : new[] { "run-script", commandName },
                        visible : true); // show the CMD window
                }
            }
        private async Task <IVsWindowFrame> CreateNewWindowFrameAsync(WorkspaceVisualNodeBase workspaceVisualNodeBase)
        {
            await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            // Find existing hierarchy and item id of the document window if it's already registered.
            var rdt = await _asyncServiceProvider.GetServiceAsync <IVsRunningDocumentTable, IVsRunningDocumentTable>();

            Assumes.Present(rdt);
            IVsHierarchy hier;
            uint         itemId;
            var          docData = IntPtr.Zero;
            int          hr;

            try
            {
                uint cookie;
                hr = rdt.FindAndLockDocument(
                    (uint)_VSRDTFLAGS.RDT_NoLock,
                    workspaceVisualNodeBase.NodeMoniker,
                    out hier,
                    out itemId,
                    out docData,
                    out cookie);

                if (hr != VSConstants.S_OK)
                {
                    // the docuemnt window is not registered yet. So use the hierarchy from the current selection.
                    itemId = (uint)VSConstants.VSITEMID.Root;
                }
            }
            finally
            {
                if (docData != IntPtr.Zero)
                {
                    Marshal.Release(docData);
                    docData = IntPtr.Zero;
                }
            }

            return(await CreateToolWindowAsync(workspaceVisualNodeBase, hier, itemId));
        }
Esempio n. 17
0
 public IWorkspaceCommandHandler ProvideCommandHandler(WorkspaceVisualNodeBase parentNode)
 => parentNode is IFolderNode ? _handler : null;
 private static bool EnsurePackageJson(WorkspaceVisualNodeBase node)
 {
     return(node is IFileNode fileNode && StringComparer.OrdinalIgnoreCase.Equals(fileNode.FileName, "package.json"));
 }
Esempio n. 19
0
 private static bool EnsurePackageJson(WorkspaceVisualNodeBase node)
 {
     return(node is IFileNode fileNode && PackageJsonFactory.IsPackageJsonFile(fileNode.FileName));
 }
 public IChildrenSource ProvideChildren(WorkspaceVisualNodeBase parentNode)
 {
     // We don't provide new children so return null
     return(null);
 }
Esempio n. 21
0
 public IChildrenSource ProvideChildren(WorkspaceVisualNodeBase parentNode) => null;
Esempio n. 22
0
 public IChildrenSource?ProvideChildren(WorkspaceVisualNodeBase parentNode)
 {
     return(null);
 }
Esempio n. 23
0
 /// <summary>
 /// Provides our <see cref="IWorkspaceCommandHandler"/> for nodes representing
 /// managed projects.
 /// </summary>
 public IWorkspaceCommandHandler ProvideCommandHandler(WorkspaceVisualNodeBase parentNode)
 {
     return(_commandHandler);
 }
 public void OpenPackageManagerUI(WorkspaceVisualNodeBase workspaceVisualNodeBase)
 {
     _joinableTaskFactory.RunAsync(() => OpenPackageManagerUIAsync(workspaceVisualNodeBase)).PostOnFailure(nameof(PackageManagerUICommandHandler));
 }
        private async Task OpenPackageManagerUIAsync(WorkspaceVisualNodeBase workspaceVisualNodeBase)
        {
            await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            await ShowPackageManagerUIAsync(workspaceVisualNodeBase);
        }
 private Task OpenPackageManagerUIAsync(WorkspaceVisualNodeBase workspaceVisualNodeBase)
 {
     return(Task.CompletedTask);
 }
 public void OpenPackageManagerUI(WorkspaceVisualNodeBase workspaceVisualNodeBase)
 {
     _joinableTaskFactory.RunAsync(() => OpenPackageManagerUIAsync(workspaceVisualNodeBase));
 }
        private async ValueTask <IVsWindowFrame> CreateToolWindowAsync(WorkspaceVisualNodeBase workspaceVisualNodeBase, IVsHierarchy hier, uint itemId)
        {
            await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            if (!Guid.TryParse(IProjectContextInfoUtility.GetProjectGuidStringFromVslsQueryString(workspaceVisualNodeBase.VSSelectionMoniker), out Guid projectGuid))
            {
                throw new InvalidOperationException();
            }

            IVsWindowFrame windowFrame = null;

            var uiShell = await _asyncServiceProvider.GetServiceAsync <SVsUIShell, IVsUIShell>();

            Assumes.Present(uiShell);

            uint       toolWindowId;
            bool       foundToolWindowId = _projectGuidToToolWindowId.TryGetValue(projectGuid.ToString(), out toolWindowId);
            const uint FTW_none          = 0;

            if (foundToolWindowId)
            {
                ErrorHandler.ThrowOnFailure(
                    uiShell.FindToolWindowEx(
                        FTW_none,                                  //grfFTW - badly-documented enum value.
                        typeof(PackageManagerToolWindowPane).GUID, // rguidPersistenceSlot
                        toolWindowId,                              // dwToolWindowId
                        out windowFrame));

                if (windowFrame != null)
                {
                    ((IVsWindowFrame2)windowFrame).ActivateOwnerDockedWindow();
                }
                else
                {
                    _projectGuidToToolWindowId.Remove(projectGuid.ToString());
                }
            }

            if (windowFrame == null)
            {
                IServiceBroker serviceBroker = await ServiceBrokerProvider.Value.GetAsync();

                IProjectContextInfo projectContextInfo = await IProjectContextInfoUtility.CreateAsync(serviceBroker, projectGuid.ToString(), CancellationToken.None);

                INuGetUI uiController = await UIFactory.Value.CreateAsync(serviceBroker, projectContextInfo);

                // This model takes ownership of --- and Dispose() responsibility for --- the INuGetUI instance.
                var model   = new PackageManagerModel(uiController, isSolution: false, editorFactoryGuid: GuidList.NuGetEditorType);
                var control = await PackageManagerControl.CreateAsync(model, OutputConsoleLogger.Value);

                var caption = string.Format(CultureInfo.CurrentCulture, Resx.Label_NuGetWindowCaption, Path.GetFileNameWithoutExtension(workspaceVisualNodeBase.NodeMoniker));

                int[] pfDefaultPosition = null;

                var windowPane = new PackageManagerToolWindowPane(control, projectGuid.ToString());
                ErrorHandler.ThrowOnFailure(
                    uiShell.CreateToolWindow(
                        (uint)__VSCREATETOOLWIN.CTW_fInitNew,
                        ++_maxToolWindowId,                        // dwToolWindowId
                        windowPane,                                // ToolWindowPane
                        Guid.Empty,                                // rclsidTool = GUID_NULL
                        typeof(PackageManagerToolWindowPane).GUID, // rguidPersistenceSlot
                        Guid.Empty,                                // reserved - do not use - GUID_NULL
                        null,                                      // IServiceProvider
                        caption,
                        pfDefaultPosition,
                        out windowFrame));
                _projectGuidToToolWindowId.Add(projectGuid.ToString(), _maxToolWindowId);
                windowPane.Closed += WindowPane_Closed;

                if (windowFrame != null)
                {
                    WindowFrameHelper.AddF1HelpKeyword(windowFrame, keywordValue: F1KeywordValuePmUI);
                    WindowFrameHelper.DisableWindowAutoReopen(windowFrame);
                    WindowFrameHelper.DockToolWindow(windowFrame);
                }
            }

            return(windowFrame);
        }