views:

198

answers:

3

I am developing console application in .Net and I want to change a behavior a little based on information that application was started from cmd.exe or from explorer.exe. Is it possible?

+2  A: 

The CreateToolhelp32Snapshot Function has a Process32First method that will allow you to read a PROCESSENTRY32 Structure. The structure has a property that will get you the information you want:

th32ParentProcessID - The identifier of the process that created this process (its parent process).

This article will help you get started using the ToolHelpSnapshot function:

http://www.codeproject.com/KB/cs/IsApplicationRunning.aspx

Espo
+7  A: 
Process this_process = Process.GetCurrentProcess();
int parent_pid = 0;
using (ManagementObject MgmtObj = new ManagementObject("win32_process.handle='" + this_process.Id.ToString() + "'"))
{
MgmtObj.Get();
parent_pid = Convert.ToInt32(MgmtObj["ParentProcessId"]);
}
string parent_process_name = Process.GetProcessById(parent_pid).ProcessName;
Factor Mystic
Please check Adam Mitz comment bellow. I still found this answer the best because of simplicity. However someone should concern.
Jakub Šturc
+3  A: 

One issue with the ToolHelp/ManagementObject approaches is that the parent process could already have exited.

The GetStartupInfo Win32 function (use PInvoke if there's no .NET equivalent) fills in a structure that includes the window title. For a Win32 console application "app.exe", this title string is "app" when started from cmd and "c:\full\path\to\app.exe" when started from explorer (or the VS debugger).

Of course this is a hack (subject to change in other versions, etc.).

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
int main()
{
  STARTUPINFO si;
  GetStartupInfo(&si);
  MessageBox(NULL, si.lpTitle, NULL, MB_OK);
  return 0;
}
Adam Mitz