DoDo
DoDo

Reputation: 11

How to find cmd.exe process id from which app is started?

I have simple win application(writen using .net C#) that needs to be started from cmd.exe, and then write to that console, but problem is that i need process id from that cmd.exe process. I can get all running process,

Process[] procList = Process.GetProcessesByName("cmd");

but how to find my? :)

Maybe to read input, and check is "ApplicationName.exe" writen inside, or to get curently active cmd.exe window? But with what function?

Upvotes: 0

Views: 1889

Answers (3)

AyrA
AyrA

Reputation: 863

Add this functions somewhere in a class to your project: (requires a using System.Runtime.InteropServices; on top of the class)

    [DllImport("kernel32.dll")]
    private static extern bool AttachConsole(int dwProcessId);
    [DllImport("kernel32.dll")]
    private static extern bool FreeConsole();

Then call AttachConsole(-1) Now you can use the System.Console class as usual to write to the console and set colors and whatnot. If you no longer need to write to the console, call FreeConsole() to detach your process from it.

Be aware that this does not actually blocks the console from processing further commands. The user is still allowed to enter anything into the console at anytime.

The recommended way is as follows:

  1. Create a console application
  2. Write to it whatever you want.
  3. Call FreeConsole() once you no longer need it.
  4. Open your form using Application.Run(). Not using application.Run and only showing the form does not creates a proper message loop and strange things can happen.

You can switch 3 and 4, but as soon as you call the Application.Run method, the code will not continue until the form is closed. So either write to the console in the form and free it from there or spawn the form in a separate thread (which has other unintended side consequences)

You can supply any process ID to the AttachConsole function. -1 default to the parent process which is most likely what you want.

Upvotes: 0

Captain Sensible
Captain Sensible

Reputation: 5037

The following code creates a WQL event query to detect a new process, waits for a new process to start and then displays the information about the process:

WqlEventQuery query = new WqlEventQuery("__InstanceCreationEvent", new TimeSpan(0, 0, 1), "TargetInstance isa \"Win32_Process\"");
ManagementEventWatcher watcher = new ManagementEventWatcher(query);
ManagementBaseObject e = watcher.WaitForNextEvent();
Console.WriteLine("Process {0} has been created, path is: {1}", 
((ManagementBaseObject)e["TargetInstance"])["Name"],
((ManagementBaseObject)e["TargetInstance"])["ExecutablePath"]);
watcher.Stop();

I think you may find a solution to your problem by examining this WMI code sample. Hope it helps.

Upvotes: 0

Fyodor Soikin
Fyodor Soikin

Reputation: 80805

Even if you find "yours" cmd, how are you going to write into it?

There is a better way to achieve what you describe. Just compile your project as "Console Application", but have it create a WinForms window anyway. Yes, it is possible, nothing stops you from it. Then you would be able to write to the console using your System.Console class, no magic required.

Upvotes: 0

Related Questions