1

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

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

这适用于普通用户场景。但是如果我们开发,我们会遇到一个大问题:应用程序看不到应用程序Bar1是否Bar2处于调试状态,这两种情况Bar.svhost.exe都可以在任务管理器中使用。

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

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

知道如何解决问题吗?

(结束Foo.exeout of Bar1orBar2是不可能的,因为多个Bar1orBar2可以在机器上运行但Foo只需要运行一次。因此Foo.exe必须检查自己。并且“Kill”进程将让它清理)

补充:这里是问题的伪代码示例

//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;
}
4

3 回答 3

4

你检查过Debugger.IsAttached吗?

于 2012-08-07T14:23:44.293 回答
0

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

Foo.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;
}
于 2012-08-08T05:32:02.670 回答
0

如果要检查其他应用程序是否附加了调试器,请使用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;
        }
    }
}
于 2014-11-06T11:46:12.133 回答