How can I tell whether the user launched my console application by double-clicking the EXE (or a shortcut), or whether they already had a command line window open and executed my console app within that session?
Asked
Active
Viewed 2,412 times
4
-
2possible duplicate of [Can a Win32 console application detect if it has been run from the explorer or not?](http://stackoverflow.com/questions/510805/can-a-win32-console-application-detect-if-it-has-been-run-from-the-explorer-or-no) – joshuapoehls Aug 20 '10 at 01:25
3 Answers
10
Stick this static field in your "Program
" class to ensure it runs before any output:
static bool StartedFromGui =
!Console.IsOutputRedirected
&& !Console.IsInputRedirected
&& !Console.IsErrorRedirected
&& Environment.UserInteractive
&& Environment.CurrentDirectory == System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location)
&& Console.CursorTop == 0 && Console.CursorLeft == 0
&& Console.Title == Environment.GetCommandLineArgs()[0]
&& Environment.GetCommandLineArgs()[0] == System.Reflection.Assembly.GetEntryAssembly().Location;
This is a little bit overkill/paranoid, but picks up being started from Explorer while not responding to things like cls && app.exe
(by checking for the full path) or even cls && "f:\ull\path\to\app.exe"
(by looking at the title).
I got the idea from the win32 version of this question.
-
I added a second field `static bool startedFromVisualStudio = !Console.IsOutputRedirected && !Console.IsInputRedirected && !Console.IsErrorRedirected && Environment.UserInteractive && Environment.CurrentDirectory == System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) && Console.CursorTop == 0 && Console.CursorLeft == 0 && Environment.GetCommandLineArgs()[0].Contains("vshost");` to also wait for a keypress when launched from VS – JCH2k Aug 03 '16 at 09:33
1
You might be able to figure it out by P/Invoking to the Win32 GetStartupInfo() function.
[DllImport("kernel32", CharSet=CharSet.Auto)]
internal static extern void GetStartupInfo([In, Out] STARTUPINFO lpStartupInfo);

Mark Cidade
- 98,437
- 31
- 224
- 236
0
You can find out what the parent process is:
Console.WriteLine(System.Diagnostics.Process.GetCurrentProcess()?.Parent()?.ProcessName);
Where Parent() is an extension method, e.g.:
public static class Extensions
{
private static string FindIndexedProcessName(int pid)
{
var processName = Process.GetProcessById(pid).ProcessName;
var processesByName = Process.GetProcessesByName(processName);
string processIndexdName = null;
for (var index = 0; index < processesByName.Length; index++)
{
processIndexdName = index == 0 ? processName : processName + "#" + index;
var processId = new PerformanceCounter("Process", "ID Process", processIndexdName);
if ((int)processId.NextValue() == pid)
{
return processIndexdName;
}
}
return processIndexdName;
}
private static Process FindPidFromIndexedProcessName(string indexedProcessName)
{
var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName);
return Process.GetProcessById((int)parentId.NextValue());
}
public static Process Parent(this Process process)
{
return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id));
}
}

Wolfgang Grinfeld
- 870
- 10
- 11