查看是否正在调试其他程序集



我们有一个程序集,我们称之为Foo.exe。此可执行文件将由另一个应用程序启动,例如 Bar1.exeBar2.exe .

如果Foo.exe运行,它会每 10 秒检查一次Bar1Bar2进程是否正在运行。如果没有,它会清理一些东西并关闭。

这适用于普通用户方案。但是如果我们开发,我们有一个大问题:应用程序无法查看应用程序Bar1Bar2是否正在调试中,在这两种情况下,Bar.svhost.exe在任务管理器中都可用。

这意味着,如果Bar.svhost.exe将被忽略,Foo.exe调试过程中结束,这是不可能的。

但是如果看到Bar.svhost.exeFoo.exe永远不会结束,我们必须手动杀死,但后来它没有被正确清洁。

知道如何解决问题吗?

(无法在Bar1Bar2中结束Foo.exe,因为可以在计算机上运行多个Bar1Bar2,但Foo只需要运行一次。因此,Foo.exe必须自我检查。并且"杀死"过程将让它清理)

加:这里有一个伪代码问题的例子

//Bar1.exe and Bar2.exe
void Main()
{
    if (!FooIsRunning())
        StartFoo();
    DoSomething();
}
//Foo.exe
void Main()
{
    Initialize();
    while (BarIsRunning());
    Cleanup();
}
private bool BarIsRunning()
{
    var processes = Process.GetProcesses();
    if (processes.Any(p => p.ProcessName.Contains("Bar.exe"))
        return true;
    var vshostProcess = processes.FirstOrDefault(p => p.ProcessName.Contains("Bar.vshost.exe");
    return vshostProcess != null && ProcessIsDebugging(process);
}
private bool ProcessIsDebugging(Process process)
{
    // How to...
    return true;
}

你检查过 Debugger.IsAttached 吗?

如果要

检查其他应用程序是否附加了调试器,请使用 CheckRemoteDebuggerPresent

我已经为这些进程编写了一个扩展方法:

public static class ProcessExtensions
{
    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
    static extern bool CheckRemoteDebuggerPresent(IntPtr hProcess, ref bool isDebuggerPresent);
    public static bool IsDebuggerAttached(this Process process)
    {
        try
        {
            var isDebuggerAttached = false;
            CheckRemoteDebuggerPresent(process.Handle, ref isDebuggerAttached);
            return isDebuggerAttached;
        }
        catch (Exception)
        {
            return false;
        }
    }
}
我想

我解决了这个问题。我发现如果 Bar1 或 Bar2 将被调试,MainWindowTitle 是不同的。在调试之前,Bar1.vshost的MainWindowTitle.exe将是真正的应用程序标题,如果不是,则MainWindowTitle为空。

福.exe

private static bool IsLastClientClosed()
{
    var processes = Process.GetProcesses();
    var debuggingProcesses = processes.Where(p => p.ProcessName.Contains("Bar1.vshost") || p.ProcessName.Contains("Bar2.vshost")).ToList();
    if (debuggingProcesses.Any())
        return !DebuggingRuns(debuggingProcesses);
    return processes.Any(p => p.ProcessName.StartsWith("Bar1") || p.ProcessName.StartsWith("Bar2"));
}
private static bool DebuggingRuns(IEnumerable<Process> processes)
{
    foreach (var process in processes)
    {
        try
        {
            if (!string.IsNullOrEmpty(process.MainWindowTitle))
                return true;
        }
        catch
        {
        }
    }
    return false;
}

相关内容

最新更新