I’ve been working on this for a few days and have finally got it doing what it is supposed to do, so thought I would post it here in case it helps someone else out. Basically this VB.NET code will get the command line for an external process, even if your application did not start that process (which is the limitation you have if you try using Process.StartInfo). This gets the full command line that was used to start the process so it includes the path to the executable and any command line arguments / parameters specified.
The first thing I should point out is that this only works on either a 32 bit system or on a 64 bit system where your process and the process that you want to get the command line for are both 32 bit processes (running in WOW64 mode). I’m still working on parsing the PEB for the 64 bit versions of Windows but hopefully will have a 64 bit version up and running soon. My code has been tested on Windows XP 32 bit and Windows 7 64 bit. If you want to get the command line for a process not running under your own user account then you must be an administrator and on Windows 7 (and presumably Vista) you must do Run As Administrator.
Second thing I should point out is that this method makes use of my NativeMemoryReader class, which you can get the source code for here: http://www.vbforums.com/showthread.php?p=3819578
Third thing to point out is that this method along with loads of others that wrap native Windows API functionality in easy to use .NET methods will be included in a class library (imaginatively named Cjwdev.WindowsAPI) that I will be releasing soon. Keep an eye on this blog for more details over the next couple of weeks.
So here are the definitions for the APIs that this method makes use of and some constants I’ve declared.
The NtQueryInformationProcess API declared above is an internal API that the Microsoft documentation states “could change with the next release of Windows” but as mentioned earlier I’ve tested it with XP and Windows 7 and it was fine on both.
and here is my function that returns the command line (as a string):
So once you have copied that method and the API definitions above into your project then if you wanted to get the command line for each svchost.exe process then you could do this for example (on a 32 bit OS anyway, as svchost is a 64 bit process on a 64 bit OS) :
As always let me know if you find this code useful or have any questions.