17

Why I ask is that my program uses 3rd party software that sometimes leaves behind orphan processes that have no link back to my program or the 3rd party process. These orphan processes start to add up and consume tons of resources over time. I would like to kill them off periodically, but in order for me to do that, I need to know for sure they were created by my program and not some other program. I have viewed the orphan processes in Process Explorer and when looking at the properties of the process, I see a field called "Current Directory". The current directory for the orphaned process is the install directory of my program. This would give me reassurance I am killing a process created by my program.

Since these processes are created by a 3rd party, I need to just kill them after they are created by running taskkill on them or something. Is there a way to figure out the current working directory of a process using out of the box windows commands in a batch file? If this can be done through wmic queries that would be preferable, but I cannot seem to find the current working directory when using wmic. I assume if Process Explorer is able to obtain this info, I should be able to get it too through some batch commands.

user972276
  • 2,973
  • 9
  • 33
  • 46

3 Answers3

15

tlist from WDK to the rescue! The 2nd line of its output ("CWD: ...") shows the working directory of a process:

> tlist 944
 944 postgres.exe
   CWD:     D:\Lab\Database\pgsql\test\
   CmdLine: "D:/Tools/pgsql/bin/postgres.exe"  -D "."
   VirtualSize:   221116 KB   PeakVirtualSize:   242620 KB
   WorkingSetSize: 17076 KB   PeakWorkingSetSize: 19336 KB
   NumberOfThreads: 4
   9084 Win32StartAddr:0x00000000 LastErr:0x00000000 State:Waiting
   8504 Win32StartAddr:0x00000000 LastErr:0x000000b7 State:Waiting
   8616 Win32StartAddr:0x00000000 LastErr:0x00000000 State:Waiting
   7468 Win32StartAddr:0x00000000 LastErr:0x00000000 State:Waiting
    9.3.5.14202 shp  0x0000000000400000  D:\Tools\pgsql\bin\postgres.exe
 6.1.7601.18247 shp  0x00000000770D0000  C:\Windows\SYSTEM32\ntdll.dll
 ...

See the doc for more info.

wdscxsj
  • 840
  • 1
  • 8
  • 17
14

Handle is an utility that displays information about open handles for any process in the system. You can use it to see the programs that have a file open, or to see the object types and names of all the handles of a program.

Its GUI-based version is Process Explorer .

handle -p yourProcess.exe  > log.txt

It'll list all handles for yourProcess.exe in log file and now using batch command you can easily extract 'current working directory' of yourProcess from log.txt.

added by barlop

here is the output.. for process c:\tinyweb\tiny.exe run from c:\tinyweb\rrr

C:\Users\user>handle -p tiny.exe

Nthandle v4.1 - Handle viewer
Copyright (C) 1997-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

------------------------------------------------------------------------------
tiny.exe pid: 20668 compA\user
   10: File          C:\Windows
   1C: File          C:\tinyweb\rrr
   9C: File          C:\tinyweb\rrr\access_log
   A0: File          C:\tinyweb\rrr\agent_log
   A4: File          C:\tinyweb\rrr\error_log
   A8: File          C:\tinyweb\rrr\referer_log
   E4: Section       \Sessions\1\BaseNamedObjects\__wmhr_msgs_buffer_name$1e74
   EC: File          C:\Windows\winsxs\x86_microsoft.windows.common-controls_659

C:\Users\user>

If you want to parse it specifically then you could do it in pure cmd.exe with e.g. for /f, or with a third party scripting language like ruby, or with windows ports of various *nix style command line tools. This line uses such tools and gets it (obviously the following line requires grep and sed, preferably decent versions of them e.g. from cygwin)

C:\Users\harvey>handle -p tiny.exe | grep "pid:" -A 3 | sed -n "3p" | grep -o ".:[\]\S*"
C:\tinyweb\rrr
barlop
  • 12,887
  • 8
  • 80
  • 109
Sunny
  • 7,812
  • 10
  • 34
  • 48
  • +1! It is a part of system internal package, isn't it? Is it a part of W8? – TrueY Feb 20 '14 at 15:36
  • 4
    "current working directory" isn't exported by handle.exe. Any idea why? – Lizz Sep 09 '14 at 10:16
  • 1
    I agree, handle.exe does not show the required information, plus in order to run it needs admin rights. – kriegaex Mar 07 '17 at 23:12
  • Handle works, but I can't specify the PID I want. Basically have to parse the output using a gnarly looking batch file or a quick node process or some such. – Dave Mar 30 '17 at 18:01
  • @Dave see my added note.. it does show PID and i'd use regexes to parse rather than batch's for /f. – barlop Apr 13 '18 at 14:22
  • @barlop: Unfortunately, you cannot generally assume a fixed location of the working directory in `handle`'s output; the best you can do is to examine all entries for whether they're _files_ or _folders_, and even then you may end up with _multiple_ folders. – mklement0 Jul 19 '19 at 10:43
  • @mklement0 do you mean if that exe file is located in multiple directories? or do you mean that the working directory is independent of the file's path. I'm not even sure what working directory means anymore 'cos from the command line one could do `c:\blah>c:\abc\def.exe` so then I guess the working directory is `c:\blah` .. So WD is then just a synonym for current directory. But then double clicking an icon in a GUI what is working directory. Is it an option in the GUI that sets %CD% and if so then does the program even pay any attention to %CD% or just open files from wherever it last did – barlop Jul 19 '19 at 10:48
  • @barlop No, I mean that a given process can have handles to multiple directories open, whereas it can only have one working directory. Thus, given an arbitrary process, how would you know which among multiple open directories is the working directory? Try `handle -p explorer.exe`, for instance. (Your particular use case may allow you to make assumptions that eliminate this ambiguity, but I'm pointing out that this technique isn't generally robust). – mklement0 Jul 19 '19 at 10:52
  • @mklement0 I just edited my comment with a few more questions while you posted your comment – barlop Jul 19 '19 at 10:54
  • 2
    @barlop: Yes, the working directory (a.k.a current directory) is unrelated to the path of the executable that started a process. While all processes - including GUI apps - have a (single) working directory, as [reported by `tlist`](https://stackoverflow.com/a/25853120/45375), that doesn't necessarily mean that it is the same directory that the program presents to the _user_ as the directory to operate on/in. File Explorer is an example, because its own (invisible) working dir. is `C:\Windows\System32`, but the "current" directory for the user is whatever directory is shown in the GUI. – mklement0 Jul 19 '19 at 11:42
  • @barlop: Note that `%CD%` is purely a `cmd.exe` construct: it is a pseudo environment variable that reflects the working directory at the command prompt and in batch files only. (While you can technically also _set_ it, that won't work as intended, because creates a true environment variable with a static value that is unrelated to the working directory.) – mklement0 Jul 19 '19 at 11:46
  • 1
    @mklement0 ah yes I remember now C# has an option when starting a process to set the working directory https://stackoverflow.com/questions/114928/net-process-start-default-directory . and to get it https://stackoverflow.com/questions/3375406/c-sharp-get-working-directory-of-another-process . so yeah I see it'd be for GUI applications too. Thanks – barlop Jul 19 '19 at 18:13
-2

The following will work, though you only need "CommandLine" or "ExecutablePath" - not both:

wmic process where "ProcessID=1111" get CommandLine, ExecutablePath

It will return something like the following, showing where the program for PID 1111 is running:

"C:\Program Files (x86)\Common Files\MyProgram\Agent\agent.exe"
Lizz
  • 1,442
  • 5
  • 25
  • 51
  • 25
    This is just returning the path where the executable is located, not its current working directory. – Dave Mar 30 '17 at 17:58