Garry Wong
Garry Wong

Reputation: 823

Why does using Process.Start makes the started app run from the parent app location instead of the started app's actual location?

I've run into a problem where using Process.Start on an exe file for another application would cause that application to warn about missing files and then crash. After a bit of testing and debugging it looks like, somehow, when using Process.Start, it makes the targeted exe run from the location of the parent program that launched it, rather than from the location where that exe is actually located.

Why does this happen? Is this intentional design? Needless to say this completely messes up the targeted app that you run, so how should this method of launching another exe be used?

Here's an example to demonstrate the problem:

Let's create a simple small app that searches for a file and prints "success" if it finds it, and "fail" if it doesn't.

using System;
using System.IO;
using System.Windows.Forms;

namespace Testapp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (File.Exists(@".\test\test.txt"))
                {
                    MessageBox.Show("Program executed successfully");
                }
                else
                {
                    MessageBox.Show("Program failed to execute properly");
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

The intended folder structure of the above program looks like this:

Testapp Folder
->Testapp.exe
->Test Folder
  ->test.txt

The program goes into the Test folder, if it exists, and searches for the test.txt file.

Now let's make a quick launcher app that will be used to run our test app:

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace LaunchTestApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                Process.Start(@".\Testapp.exe");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

The above application is intended to reside in the same directory as our Testapp.exe. When this is run that way, everything works out perfectly fine. The Launchapp runs our Testapp, and we can click on the button in our Testapp and see a messagebox that the program had executed successfully.

However, now let's make a slight change to our launching application. Our launching application will now reside on one directory level above our Testapp.exe, like so:

Launching App Folder
->Launchapp.exe
->Testapp Folder
  ->Testapp.exe
  ->Test Folder
    ->Test.txt

Naturally, we also change our Launchapp to target our Testapp.exe in a different directory, like so:

Process.Start(@".\Testapp\Testapp.exe");

Now when the Launchapp is run, and it consequently runs Testapp.exe, and we press our button, our Testapp.exe displays a message that the program failed to run properly.

At this point, if we go back to our Testapp code and change the location to search for the test.txt from .\test\test.txt\ to .\Testapp\test\test.txt, then the program will run successfully.

This demonstrates that the Testapp exe seems to be running from the location of Launchapp, rather than from the location of where Testapp exe is actually located.

Why does this happen, and how can I prevent it from happening? I want to be able to run an application located in a different folder from the one where my calling application resides, and thus it is obviously important that the started process runs from the location where that process is located, and not where the calling application is located.

Upvotes: 1

Views: 469

Answers (4)

Pratyush Sharma
Pratyush Sharma

Reputation: 11

Use like this:

ProcessStartInfo startInfo = new ProcessStartInfo();

startInfo.UseShellExecute = false;

startInfo.WorkingDirectory = @"THE DIRECTORY";

Process.start(startInfo);

Upvotes: 0

x0n
x0n

Reputation: 52480

In the absence of any other explicit instructions, it will always use the parent process's environment. This is just how it works. If you want to specify the working location on the filesystem for the new process, use the overload that accepts a ProcessStartInfo instance. This allows you to set the working folder along with many other values.

Upvotes: 1

Bradley Uffner
Bradley Uffner

Reputation: 17001

Processes inherit the working folder of the process that started them by default. It's just the way windows works (yes, it is intentionally done this way, other operating systems behave the same way).

You can use the .WorkingDirectory property of a ProcessStartInfo to start it from another path. http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx

Upvotes: 1

SLaks
SLaks

Reputation: 888303

You're misusing the term "run from".

When you run any program, its current directory is the current directory of its parent process, unless specified otherwise.

Usually (from explorer or a command prompt), this is the directory containing the EXE file.

If you start it from your own program, it will be the current directory of your program.

You can explicitly pass an arbitrary current directory in StartOptions.

Upvotes: 0

Related Questions