Пример #1
0
        /// <summary>
        /// Writes an exception to the Visual Studio debug pane.
        /// </summary>
        /// <param name="e">The exception.</param>
        /// <param name="message">Optional text to include before the exception information.</param>
        public static void Exception(Exception e, string message = null)
        {
            if (e == null)
            {
                return;
            }

            // We're going to build a multi-line message to reduce pressure
            // on the task/threading in [RaspberryDebugPackage.Log()].

            var sb = new StringBuilder();

            sb.Append("\n");

            if (string.IsNullOrEmpty(message))
            {
                sb.Append($"EXCEPTION: {e.GetType().FullName}: {e.Message}\n");
            }
            else
            {
                sb.Append($"EXCEPTION: {e.GetType().FullName}: {message} {e.Message}\n");
            }

            sb.Append(e.StackTrace);
            sb.Append("\n");

            RaspberryDebugPackage.Log(sb.ToString());
        }
Пример #2
0
        /// <summary>
        /// Updates the Visual Studio user interface.  This is performed asynchronously
        /// by default which will result in better performance.
        /// </summary>
        /// <param name="synchronously">
        /// Optionally specifies that the update should be performed immediately,
        /// before the method returns.
        /// </param>
        internal static void UpdateVisualStudioUI(bool synchronously = false)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            var vsShell = (IVsUIShell)RaspberryDebugPackage.GetGlobalService(typeof(IVsUIShell));

            if (vsShell != null)
            {
                var hr = vsShell.UpdateCommandUI(synchronously ? 1 : 0);

                Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(hr);
            }
        }
Пример #3
0
        /// <summary>
        /// Initializes the package.
        /// </summary>
        /// <param name="cancellationToken">A cancellation token to monitor for initialization cancellation, which can occur when VS is shutting down.</param>
        /// <param name="progress">A provider for progress updates.</param>
        /// <returns>The tracking <see cref="Task"/>.</returns>
        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress)
        {
            Instance = this;
            dte      = (DTE2)(await GetServiceAsync(typeof(SDTE)));

            // When initialized asynchronously, the current thread may be a background thread at this point.
            // Do any initialization that requires the UI thread after switching to the UI thread.

            await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            // Initialize the log panel.

            var debugWindow     = Package.GetGlobalService(typeof(SVsOutputWindow)) as IVsOutputWindow;
            var generalPaneGuid = VSConstants.GUID_OutWindowDebugPane;

            debugWindow.GetPane(ref generalPaneGuid, out debugPane);

            // Intercept the debugger commands and quickly decide whether the startup project is enabled
            // for Raspberry remote debugging so we can invoke our custom commands instead.  We'll just
            // let the default command implementations do their thing when we're not doing Raspberry
            // debugging.

            debugStartCommandEvent = dte.Events.CommandEvents["{5EFC7975-14BC-11CF-9B2B-00AA00573819}", 0x0127];
            debugStartWithoutDebuggingCommandEvent = dte.Events.CommandEvents["{5EFC7975-14BC-11CF-9B2B-00AA00573819}", 0x0170];
            debugAttachToProcessCommandEvent       = dte.Events.CommandEvents["{5EFC7975-14BC-11CF-9B2B-00AA00573819}", 0x00d5];
            debugRestartCommandEvent = dte.Events.CommandEvents["{5EFC7975-14BC-11CF-9B2B-00AA00573819}", 0x0128];

            debugStartCommandEvent.BeforeExecute += DebugStartCommandEvent_BeforeExecute;
            debugStartWithoutDebuggingCommandEvent.BeforeExecute += DebugStartWithoutDebuggingCommandEvent_BeforeExecute;
            debugAttachToProcessCommandEvent.BeforeExecute       += AttachToProcessCommandEvent_BeforeExecute;
            debugRestartCommandEvent.BeforeExecute += DebugRestartCommandEvent_BeforeExecute;

            // Initialize the new commands.

            await SettingsCommand.InitializeAsync(this);

            await DebugStartCommand.InitializeAsync(this);

            await DebugStartWithoutDebuggingCommand.InitializeAsync(this);

            await DebugAttachToProcessCommand.InitializeAsync(this);
        }
Пример #4
0
 /// <summary>
 /// Writes a line of text to the Visual Studio debug pane.
 /// </summary>
 /// <param name="text">Optionally specifies the log text.</param>
 public static void WriteLine(string text = "")
 {
     RaspberryDebugPackage.Log(text + "\n");
 }
Пример #5
0
 /// <summary>
 /// Writes text to the debug pane.
 /// </summary>
 /// <param name="text">The text text.</param>
 public static void Write(string text)
 {
     RaspberryDebugPackage.Log(text);
 }
Пример #6
0
        /// <summary>
        /// Executes an asynchronous action that does not return a result within the context of a
        /// Visual Studio progress dialog.  You may make nested calls and this may also be called
        /// from any thread.
        /// </summary>
        /// <typeparam name="TResult">The action result type.</typeparam>
        /// <param name="description">The operation description.</param>
        /// <param name="action">The action.</param>
        /// <returns>The tracking <see cref="Task"/>.</returns>
        public static async Task <TResult> ExecuteWithProgressAsync <TResult>(string description, Func <Task <TResult> > action)
        {
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(description), nameof(description));
            Covenant.Requires <ArgumentNullException>(action != null, nameof(action));

            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            if (progressDialog == null)
            {
                Covenant.Assert(operationStack.Count == 0);

                rootDescription = description;
                operationStack.Push(description);

                var dialogFactory = (IVsThreadedWaitDialogFactory)RaspberryDebugPackage.GetGlobalService((typeof(SVsThreadedWaitDialogFactory)));

                dialogFactory.CreateInstance(out progressDialog);

                progressDialog.StartWaitDialog(
                    szWaitCaption:          progressCaption,
                    szWaitMessage:          description,
                    szProgressText:         null,
                    varStatusBmpAnim:       null,
                    szStatusBarText:        $"[{LogName}]{description}",
                    iDelayToShowDialog:     0,
                    fIsCancelable:          false,
                    fShowMarqueeProgress:   true);
            }
            else
            {
                Covenant.Assert(operationStack.Count > 0);

                operationStack.Push(description);

                progressDialog.UpdateProgress(
                    szUpdatedWaitMessage:   progressCaption,
                    szProgressText:         description,
                    szStatusBarText:        null,
                    iCurrentStep:           0,
                    iTotalSteps:            0,
                    fDisableCancel:         true,
                    pfCanceled:             out var cancelled);
            }

            var orgCursor = Cursor.Current;

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                return(await action().ConfigureAwait(false));
            }
            finally
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                Cursor.Current = orgCursor;

                var currentDescription = operationStack.Pop();

                if (operationStack.Count == 0)
                {
                    progressDialog.EndWaitDialog(out var cancelled);

                    progressDialog  = null;
                    rootDescription = null;
                }
                else
                {
                    progressDialog.UpdateProgress(
                        szUpdatedWaitMessage:   currentDescription,
                        szProgressText:         null,
                        szStatusBarText:        rootDescription,
                        iCurrentStep:           0,
                        iTotalSteps:            0,
                        fDisableCancel:         true,
                        pfCanceled:             out var cancelled);
                }
            }
        }