コード例 #1
0
        void AttachClick(object sender, RoutedEventArgs e)
        {
            _taskContext.ThrowIfNotOnMainThread();

            // Figure out core file path
            CoreListEntry?coreListEntry = null;

            if (TabControl.SelectedContent == GameletGroupBox)
            {
                coreListEntry = (CoreListEntry?)CoreList.SelectedItem;
                if (coreListEntry == null)
                {
                    _dialogUtil.ShowError(ErrorStrings.NoCoreFileSelected);
                    return;
                }
            }

            string coreFilePath = null;
            bool   deleteAfter  = false;

            if (TabControl.SelectedContent == LocalGroupBox)
            {
                coreFilePath = LocalCorePathBox.Text;
            }
            else if (TabControl.SelectedContent == GameletGroupBox)
            {
                var tempPath = Path.GetTempPath();
                try
                {
                    _cancelableTaskFactory
                    .Create(TaskMessages.DownloadingCoreFile,
                            async task => await _remoteFile.GetAsync(new SshTarget(_instance),
                                                                     "/usr/local/cloudcast/core/" +
                                                                     coreListEntry?.Name,
                                                                     tempPath, task))
                    .RunAndRecord(_actionRecorder, ActionType.CrashDumpDownload);
                }
                catch (ProcessException ex)
                {
                    Trace.WriteLine($"Failed to download core file.{Environment.NewLine}" +
                                    $"{ex}");
                    _dialogUtil.ShowError(ErrorStrings.FailedToDownloadCore(ex.Message),
                                          ex.ToString());
                    return;
                }

                coreFilePath = Path.Combine(tempPath, coreListEntry?.Name);
                deleteAfter  = true;
            }

            if (string.IsNullOrEmpty(coreFilePath))
            {
                ShowMessage(ErrorStrings.FailedToRetrieveCoreFilePath);
                return;
            }

            // Check if we have a debugger (should always be the case).
            var vsDebugger =
                (IVsDebugger4)ServiceProvider.GlobalProvider.GetService(typeof(IVsDebugger));

            if (vsDebugger == null)
            {
                ShowMessage(ErrorStrings.FailedToStartDebugger);
                return;
            }

            try
            {
                _actionRecorder.RecordToolAction(ActionType.CrashDumpAttach, delegate
                {
                    _taskContext.ThrowIfNotOnMainThread();

                    VsDebugTargetInfo4[] debugTargets = new VsDebugTargetInfo4[1];
                    debugTargets[0].dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess;

                    // LaunchDebugTargets4() throws an exception if |bstrExe| and |bstrCurDir|
                    // are empty. Use core path and temp directory as placeholders.
                    debugTargets[0].bstrExe                = coreFilePath;
                    debugTargets[0].bstrCurDir             = Path.GetTempPath();
                    var parameters                         = _paramsFactory.Create();
                    parameters.CoreFilePath                = coreFilePath;
                    parameters.DebugSessionId              = _debugSessionMetrics.DebugSessionId;
                    parameters.DeleteCoreFile              = deleteAfter;
                    debugTargets[0].bstrOptions            = _paramsFactory.Serialize(parameters);
                    debugTargets[0].guidLaunchDebugEngine  = YetiConstants.DebugEngineGuid;
                    VsDebugTargetProcessInfo[] processInfo =
                        new VsDebugTargetProcessInfo[debugTargets.Length];
                    vsDebugger.LaunchDebugTargets4(1, debugTargets, processInfo);
                });
            }
            catch (COMException except)
            {
                Trace.WriteLine($"Failed to start debugger: {except}");

                // Both DebugEngine and Visual Studio already show error dialogs if DebugEngine
                // has to abort while it's attaching, no need to show another dialog in that case.
                if (except.ErrorCode != VSConstants.E_ABORT)
                {
                    _dialogUtil.ShowError(ErrorStrings.FailedToStartDebugger, except.ToString());
                }
            }
            finally
            {
                Close();
            }
        }