Hi,

I have written a v. small VB.NET program that spawns "cmd.exe" using Process, redirects stdin/out/err; works OK so far.

Does anyone know how to get :
* the details about the process currently running (if any) under cmd.exe (like how the command shell displays 'c:\windows\system32\cmd.exe - dir /s/b' when the dir command has been run); preferably not by using GetWindowText on the cmd.exe window
* the current directory of the command shell (even if some batch file or program has changed it)

Any help is much appreciated.

Dani AI

Generated

For : this is doable but requires two different techniques depending on whether the shell has launched a separate process or is running an internal command.

Use WMI (or Toolhelp) to enumerate children of the cmd.exe process. That shows any external child process(es) plus their command line/EXE path and PID — e.g. when cmd.exe launches notepad.exe or a console program. Example (VB.NET, requires a reference to System.Management):

Imports System.Management

Function GetCmdChildren(cmdPid As Integer) As List(Of String)
    Dim list As New List(Of String)
    Dim q = "SELECT ProcessId, Name, CommandLine, ExecutablePath FROM Win32_Process WHERE ParentProcessId = " & cmdPid
    Using s As New ManagementObjectSearcher(q)
        For Each mo As ManagementObject In s.Get()
            Dim pid = If(mo("ProcessId") IsNot Nothing, CInt(mo("ProcessId")), 0)
            Dim name = If(mo("Name") IsNot Nothing, mo("Name").ToString(), "")
            Dim cmdline = If(mo("CommandLine") IsNot Nothing, mo("CommandLine").ToString(), "")
            list.Add(String.Format("{0}: {1} {2}", pid, name, cmdline))
        Next
    End Using
    Return list
End Function

To get the shell's current directory (even after a batch file changes it), query the shell itself over the redirected streams. Sending a unique echo of %CD% is simple and robust:

' proc is the Process for cmd.exe with RedirectStandardInput/Output = True
proc.StandardInput.WriteLine("echo __CMD_CWD__%CD%__")
proc.StandardInput.Flush()
Dim cwdLine As String = Nothing
Do
    Dim line = proc.StandardOutput.ReadLine()
    If line Is Nothing Then Exit Do
    If line.StartsWith("__CMD_CWD__") Then
        cwdLine = line.Substring("__CMD_CWD__".Length)
        Exit Do
    End If
Loop
' cwdLine holds the current directory

Notes and caveats: internal commands like dir run inside cmd.exe (no child PID), so WMI will show no child — tracking stdin or the shell output is required. WMI access to CommandLine can be subject to permissions on some Windows versions. Avoid blocking by reading stdout asynchronously or using reader threads. Reading another process’s CWD from its memory/PEB is possible but platform-specific and fragile; prefer the echo method when controlling the spawned cmd.exe.

Is this impossible??

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.