5

I'm trying to call chrome.exe inside a C# program by using System.Diagnostics.Process namespace.

my chrome.exe is located inside path C:\Program Files (x86)\Google\Chrome\Application

if I call RunProc function by passing bellow parameters - (keep absolute path of the exe and keep WorkingDirectory empty)

("C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe" , "https://www.google.com", "") it works just fine.

But, with parameters -

("Chrome.exe , "https://www.google.com", "C:\Program Files (x86)\Google\Chrome\Application") it gives exception at step proc.Start(); stating - The system cannot find the file specified.

I also tried writing WorkingDirectory = workingDir while initializing StartInfo but still looking for solutions.

class Program
{
    static void Main(string[] args)
    {
        RunProc(@"chrome.exe", @"https://www.google.com", @"C:\Program Files (x86)\Google\Chrome\Application");
    }

    static bool RunProc(string exe, string args, string workingDir)
    {
        Process proc = new Process
        {
            StartInfo =
            {
                FileName =  exe,
                CreateNoWindow = true,
                RedirectStandardInput = true,
                WindowStyle = ProcessWindowStyle.Hidden,
                UseShellExecute = false,
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                Arguments = args,
                //WorkingDirectory = workingDir
            }
        };

        if (!string.IsNullOrEmpty(workingDir))
        {
            proc.StartInfo.WorkingDirectory = workingDir;
        }

        proc.Start();
        proc.StandardInput.WriteLine(args);
        proc.StandardInput.Flush();
        proc.StandardInput.Close();

        return true;
    }

}
Arkil Shaikh
  • 342
  • 3
  • 9
  • It would be awesome if you could provide a [mcve], so we can see **in code** how you are calling that method (and with what parameters). – mjwills Nov 15 '18 at 11:08
  • With this line: `FileName = exe`, does `exe` contain the full path to the file you want to start, or simply the file name? The Working Directory isn't used to execute the file – Martin Nov 15 '18 at 11:08
  • The Variable exe contains only file name. I want to set the working directory where the file is present. And if the file is available in your working directly so you should be able to run exe only with name. – Arkil Shaikh Nov 15 '18 at 13:41
  • @mjwills - I have updated the question, given full working code and an example.Hope this will help. – Arkil Shaikh Nov 16 '18 at 04:42

3 Answers3

4

The only way for this to work is for you to change your working directory to the passed in working directory before attempting to start the other process. The WorkingDirectory property is just that, and doesn't in any way get involved in locating the executable to run. That just relies on your working directory and your PATH environment variable, if you fail to provide a fully-qualified name.

static bool RunProc(string exe, string args, string workingDir)
{
    var prevWorking = Environment.CurrentDirectory;
    try
    {
        Environment.CurrentDirectory = workingDir;
        Process proc = new Process
        {
            StartInfo =
            {
               FileName =  exe,
               CreateNoWindow = true,
               RedirectStandardInput = true,
               WindowStyle = ProcessWindowStyle.Hidden,
               UseShellExecute = false,
               RedirectStandardError = true,
               RedirectStandardOutput = true,
               Arguments = args,
            }
        };

        proc.Start();
        proc.StandardInput.WriteLine(args);
        proc.StandardInput.Flush();
        proc.StandardInput.Close();

        return true;
    }
    finally
    {
        Environment.CurrentDirectory = prevWorking;
    }
}
Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
1

Why not just call the .exe from the path where it is located directly ?

Process.Start(@"C:\new\folder\abcd.exe");

Or just put

proc.StartInfo.WorkingDirectory = @"c:\new\folder";

before proc.start();

John Linaer
  • 15
  • 1
  • 6
  • Thanks for the response. I can follow your first suggestion but the place I'm using this piece of code will have complex exe names, folder path and arguments, so it would be better to keep all these separate. I already tried your 2nd suggestion, that didn't work. – Arkil Shaikh Nov 15 '18 at 12:29
0

What do you think about combining the absolute path of the .exe within your static method and check if the path exists before you call the Process start:

using System.Diagnostics;
using System.IO;

namespace RunProc
{
    class Program
    {
        static void Main(string[] args)
        {
            RunProc(@"chrome.exe", @"https://www.google.com", @"C:\Program Files (x86)\Google\Chrome\Application");
        }

        static bool RunProc(string exe, string args, string workingDir)
        {
            string filePath = workingDir + "\"" + exe;

            if (!File.Exists(filePath))
                return false;

            Process proc = new Process
            {
                StartInfo =
                {
                    FileName =  filePath,
                    CreateNoWindow = true,
                    RedirectStandardInput = true,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    UseShellExecute = false,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    Arguments = args,
                }
            };

            proc.Start();
            proc.StandardInput.WriteLine(args);
            proc.StandardInput.Flush();
            proc.StandardInput.Close();

            return true;
        }
    }
}

Maybe, the method RunProc is a bit clearer with DirectoryInfo and FileInfo

using System.Diagnostics;
using System.IO;

namespace RunProc
{
    class Program
    {
        static void Main(string[] args)
        {
            FileInfo myRelativeFileExe = new FileInfo(@"chrome.exe");
            DirectoryInfo myAbsoluteFileDir = new DirectoryInfo(@"C:\Program Files (x86)\Google\Chrome\Application");
            
            RunProc(myRelativeFileExe, myAbsoluteFileDir, @"https://www.google.com");
        }

        static bool RunProc(FileInfo exe, DirectoryInfo workingDir, string args)
        {
            FileInfo myAbsoluteFilePath = new FileInfo(Path.Combine(workingDir.ToString(), exe.ToString()));

            if (!myAbsoluteFilePath.Exists)
                return false;

            Process proc = new Process
            {
                StartInfo =
                {
                    FileName =  myAbsoluteFilePath.FullName,
                    CreateNoWindow = true,
                    RedirectStandardInput = true,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    UseShellExecute = false,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    Arguments = args,
                }
            };

            proc.Start();
            proc.StandardInput.WriteLine(args);
            proc.StandardInput.Flush();
            proc.StandardInput.Close();

            return true;
        }
    }
}
Rene
  • 976
  • 1
  • 13
  • 25