Reputation: 33
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
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
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