Process.Start() and PATH environment variable

Reg Domaratzki picture Reg Domaratzki · Sep 12, 2012 · Viewed 38k times · Source

I have the following trivial C# application that simply attempts to launch "jconsole.exe", which on my machine is located in C:\Programs\jdk16\bin.

using System;
using System.Diagnostics;

namespace dnet {
  public class dnet {
    static void Main( string[] args ) {
      try {
        Process.Start("jconsole.exe");
        Console.WriteLine("Success!");
      } catch (Exception e) {
        Console.WriteLine("{0} Exception caught.", e);
      }
    }
  }
}

If my PATH environment variable is set to

c:\windows;c:\windows\sytem32;c:\programs\jdk16\bin

it works perfectly. However, if the PATH environment variable is set to

c:\windows;c:\windows\sytem32;c:\\programs\jdk16\bin

(note the two backslashes between "c:" and "programs"), it fails with a win32 exception.

System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at dnet.dnet.Main(String[] args)

Interestingly, in the same command prompt where I run the .NET program and get the exception, I can simply type "jconsole.exe", and the program will start. Windows appears to have no trouble finding the executable with the double backslash in the PATH, but Process.Start() does.

Why is the extra backslash in the PATH causing problems, and how I can get around the problem? I don't know where the executable I want to call will be located at runtime, so I'd rather rely on the PATH variable.

Answer

Amith George picture Amith George · Sep 12, 2012

Not quite sure why the problem occurs. Though, I can think of one solution that works on my machine:

var enviromentPath = System.Environment.GetEnvironmentVariable("PATH");

Console.WriteLine(enviromentPath);
var paths = enviromentPath.Split(';');
var exePath = paths.Select(x => Path.Combine(x, "mongo.exe"))
                   .Where(x => File.Exists(x))
                   .FirstOrDefault();

Console.WriteLine(exePath);

if (string.IsNullOrWhiteSpace(exePath) == false)
{
    Process.Start(exePath);
}

I did find one para which gave me the idea for this solution. From the documentation for Process.Start

If you have a path variable declared in your system using quotes, you must fully qualify that path when starting any process found in that location. Otherwise, the system will not find the path. For example, if c:\mypath is not in your path, and you add it using quotation marks: path = %path%;"c:\mypath", you must fully qualify any process in c:\mypath when starting it.

The way I read it, even though the PATH variable contained a valid path that Windows is able to use, Process.Start is unable to use it and needs the fully qualified path .