Device
Device

Reputation: 33

See if other assembly is being debugged

We have an assembly, lets call it Foo.exe. This executable will be started by another application like Bar1.exe or Bar2.exe.

If Foo.exe runs it checks every 10 seconds if a Bar1 or Bar2 process is running. If not it cleans up some things and shuts down.

This works on the normal user scenario. But if we develop we have one big problem: The application cannot see if the application Bar1 or Bar2 is under debugging or not, in both cases Bar.svhost.exe is available in the task manager.

That means, if the Bar.svhost.exe will be ignored, Foo.exe ends during debugging process, this is not possible.

But if the Bar.svhost.exe will be seen, the Foo.exe never ends, we have to kill is manually but then it was not cleaned properly.

Any idea how to solve the problem?

(Ending the Foo.exe out of Bar1 or Bar2 is not possible, because multiple Bar1 or Bar2 can be run on the machine but Foo just have to run once. Therefore the Foo.exe has to check itself. And the "Kill" the process will be let it cleaning up)

Add: Here an pseudo code example of the problem

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

Upvotes: 1

Views: 414

Answers (3)

ElGaucho
ElGaucho

Reputation: 408

If you want to check if other applications have a debugger attached, use CheckRemoteDebuggerPresent

I've written an extension method for the processes:

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

Upvotes: 0

Device
Device

Reputation: 33

I think I solve the problem. I figured out that the MainWindowTitle is different if Bar1 or Bar2 will be debugged or not. Until debugging the MainWindowTitle of the Bar1.vshost.exe will be the real application title, if not the MainWindowTitle is empty.

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

Upvotes: 0

Dominik
Dominik

Reputation: 3362

Have you checked Debugger.IsAttached ?

Upvotes: 4

Related Questions