views:

766

answers:

5

Background:

I built an installer for my app, and all my dll's and content files are getting correctly copied to the C:\Program Files\MyCompany\MyApp directory. When I run my app from Visual Studio, everything works great. When I run the installed version of my app, however, I get a DirectoryNotFoundException. The problem seems to be with Environment.CurrentDirectory.

I was expecting Environment.CurrentDirectory to be...

"C:\\Program Files\\MyCompany\\MyApp"

...but it was actually...

"C:\\Documents and Settings\\DanThMan"

What's going on here? How do I solve this?

Thanks.

EDIT:

Okay, hmm. This problem only occurs if I run the Start Menu shortcut. If I run MyApp.exe directly, everything is fine.

EDIT 2:

I think I've gotten to the bottom of this now. In my Installer (which is a Visual Studio SetupProject), the Start Menu shortcut has a property called WorkingFolder, which "Specifies the folder where the target application for the shortcut will be installed." I had accidentally set WorkingFolder to "MyCompany". It should be "Application Folder". Now that I have it set correctly, Environment.CurrentDirectory is once again working as expected. Thanks for all your help.

EDIT 3:

However, reading the warnings below, I have decided to go with the following as a replacement for Environment.CurrentDirectory:

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
+5  A: 

Use Application.StartupPath instead of Environment.CurrentDirectory.
I've had a similar problem, where the CurrentDirectory was being changed inadvertently by something like an OpenFileDialog without me even realizing it.
In your case, it sounds like the process that you're starting the application form is changing the CurrentDirectory unbeknownst to you.

Donut
StartupPath doesn't seem to be a member of System.Windows.Application, System.Net.Mime.MediaTypeNames.Application, or MS.Internal.Documents.Application. If it makes any difference, this is a WPF app.
DanM
Ah ok... yeah, `Application.StartupPath` is found in the `System.Windows.Forms` namespace.
Donut
+1  A: 

When a program is started, the current directory is typically the same as the one of the starting application, unless the starting application specifies a different working directory. It can really be anywhere on disk.

In your case, the starting application is the shell (explorer.exe) in both cases. It does specify a working directory when starting a program, depending on the context of the launch. You have seen two different cases (double-clicking on a file in explorer, and running from the start menu); you have also found what Microsoft considers the most sensible values for current directory in either case: the user's home directory, and the directory that is shown in explorer (respectively).

Martin v. Löwis
+1  A: 

The Environment.CurrentDirectory contains current directory that is really current directory now. The value depends on many factors. Any application may change the value. This value doesn't concerned with your application only.

If you want to get the start up directory then use Application.StartupPath.

den123
+5  A: 

If you want to get the path to the directory under which your executable runs, you should not rely on the Environment.CurrentDirectory, since it can be changed in a number of ways (shotrtcut settings, etc). Try one of these options instead:

System.IO.Path.GetDirectoryName(Application.ExecutablePath);

or

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
Alek Davis
I went with the second solution because the first one won't work with a WPF app (unless you include the assembly for Windows Forms).
DanM
+1  A: 

Since you said that your application is using WPF, you can use the code below instead of Application.StartupPath :

String appPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
Francis B.