C# 如何以编程方式停止调试?

C# 如何以编程方式停止调试?,c#,debugging,C#,Debugging,我想对按钮单击执行操作,单击按钮时应停止调试: private void button3_Click(object sender, EventArgs e) { //write code here to stop debugging } “停止调试”是什么意思?您可以在Visual Studio中使用分离选项,但代码中没有。要在调试时退出应用程序,请使用以下命令(windows窗体代码): 如果以编程方式分离调试器,则需要获取对当前运行的EnvDTE80.DTE2对象的引用。一旦你有了

我想对按钮单击执行操作,单击按钮时应停止调试:

private void button3_Click(object sender, EventArgs e)
{
    //write code here to stop debugging
}

“停止调试”是什么意思?您可以在Visual Studio中使用分离选项,但代码中没有。要在调试时退出应用程序,请使用以下命令(windows窗体代码):


如果以编程方式分离调试器,则需要获取对当前运行的EnvDTE80.DTE2对象的引用。一旦你有了这些,你可以尝试:

var dte = ...
dte.Debugger.DetachAll()
要获得对EnvDTE80.DTE2的引用,其方法似乎是可行的:

您可以将其全部封装在某个类中,如下所示:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE80;

class DetachDebugger
{
    [DllImport("ole32.dll")]
    private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);

    [DllImport("ole32.dll")]
    private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

    public static void Detach()
    {
        var dte = GetCurrent();
        dte.Debugger.DetachAll();
    }

    /// <summary>
    /// Gets the current visual studio's solution DTE2
    /// </summary>
    private static DTE2 GetCurrent()
    {
        List<DTE2> dte2s = new List<DTE2>();

        IRunningObjectTable rot;
        GetRunningObjectTable(0, out rot);
        IEnumMoniker enumMoniker;
        rot.EnumRunning(out enumMoniker);
        enumMoniker.Reset();
        IntPtr fetched = IntPtr.Zero;
        IMoniker[] moniker = new IMoniker[1];
        while (enumMoniker.Next(1, moniker, fetched) == 0)
        {
            IBindCtx bindCtx;
            CreateBindCtx(0, out bindCtx);
            string displayName;
            moniker[0].GetDisplayName(bindCtx, null, out displayName);
            // add all VisualStudio ROT entries to list
            if (displayName.StartsWith("!VisualStudio"))
            {
                object comObject;
                rot.GetObject(moniker[0], out comObject);
                dte2s.Add((DTE2)comObject);
            }
        }

        // get path of the executing assembly (assembly that holds this code) - you may need to adapt that to your setup
        string thisPath = System.Reflection.Assembly.GetExecutingAssembly().Location;

        // compare dte solution paths to find best match
        KeyValuePair<DTE2, int> maxMatch = new KeyValuePair<DTE2, int>(null, 0);
        foreach (DTE2 dte2 in dte2s)
        {
            int matching = GetMatchingCharsFromStart(thisPath, dte2.Solution.FullName);
            if (matching > maxMatch.Value)
                maxMatch = new KeyValuePair<DTE2, int>(dte2, matching);
        }

        return (DTE2)maxMatch.Key;
    }

    /// <summary>
    /// Gets index of first non-equal char for two strings
    /// Not case sensitive.
    /// </summary>
    private static int GetMatchingCharsFromStart(string a, string b)
    {
        a = (a ?? string.Empty).ToLower();
        b = (b ?? string.Empty).ToLower();
        int matching = 0;
        for (int i = 0; i < Math.Min(a.Length, b.Length); i++)
        {
            if (!char.Equals(a[i], b[i]))
                break;

            matching++;
        }
        return matching;
    }
}

您好,欢迎来到SO,如果您想受到重视,请花点时间修改您帖子中的语法。您能澄清一下您的意思是“中断”还是“分离”吗?你的意思是编程上的还是仅仅是一个断点?我想知道我们是否把这个问题弄得更难了……你到底为什么要这样做?@AHMADSUMRAIZ Mikhail的评论可能有点直截了当,但他的观点是正确的,你不应该生气。最后,你最好有一个措辞清晰的问题,因为它能让你更容易地给出答案。
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE80;

class DetachDebugger
{
    [DllImport("ole32.dll")]
    private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);

    [DllImport("ole32.dll")]
    private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

    public static void Detach()
    {
        var dte = GetCurrent();
        dte.Debugger.DetachAll();
    }

    /// <summary>
    /// Gets the current visual studio's solution DTE2
    /// </summary>
    private static DTE2 GetCurrent()
    {
        List<DTE2> dte2s = new List<DTE2>();

        IRunningObjectTable rot;
        GetRunningObjectTable(0, out rot);
        IEnumMoniker enumMoniker;
        rot.EnumRunning(out enumMoniker);
        enumMoniker.Reset();
        IntPtr fetched = IntPtr.Zero;
        IMoniker[] moniker = new IMoniker[1];
        while (enumMoniker.Next(1, moniker, fetched) == 0)
        {
            IBindCtx bindCtx;
            CreateBindCtx(0, out bindCtx);
            string displayName;
            moniker[0].GetDisplayName(bindCtx, null, out displayName);
            // add all VisualStudio ROT entries to list
            if (displayName.StartsWith("!VisualStudio"))
            {
                object comObject;
                rot.GetObject(moniker[0], out comObject);
                dte2s.Add((DTE2)comObject);
            }
        }

        // get path of the executing assembly (assembly that holds this code) - you may need to adapt that to your setup
        string thisPath = System.Reflection.Assembly.GetExecutingAssembly().Location;

        // compare dte solution paths to find best match
        KeyValuePair<DTE2, int> maxMatch = new KeyValuePair<DTE2, int>(null, 0);
        foreach (DTE2 dte2 in dte2s)
        {
            int matching = GetMatchingCharsFromStart(thisPath, dte2.Solution.FullName);
            if (matching > maxMatch.Value)
                maxMatch = new KeyValuePair<DTE2, int>(dte2, matching);
        }

        return (DTE2)maxMatch.Key;
    }

    /// <summary>
    /// Gets index of first non-equal char for two strings
    /// Not case sensitive.
    /// </summary>
    private static int GetMatchingCharsFromStart(string a, string b)
    {
        a = (a ?? string.Empty).ToLower();
        b = (b ?? string.Empty).ToLower();
        int matching = 0;
        for (int i = 0; i < Math.Min(a.Length, b.Length); i++)
        {
            if (!char.Equals(a[i], b[i]))
                break;

            matching++;
        }
        return matching;
    }
}
private void button3_Click(object sender, EventArgs e)
{
    //write code here to stop debugging
    DetachDebugger.Detach();
}