8

I have a WPF application that gets installed on the client machine through the Windows Installer. This application also registers a file extension (.xyz), so when the user double clicks a file, it opens my WPF application and displays the file (like Microsoft Word). This program also has a ton of files that are not marked as resource or content files that it uses (user manuals, part drawings, etc).

The problem comes when the user double clicks a .xyz file and it opens the WPF application. The application now has a working directory of the directory where the .xyz file is located. Now the program cannot find any of the files (user manuals, part drawings, etc) it needs.

What is the best way to handle this type of problem? I could set the working directory (Environment.CurrentDirectory), but my open file dialog box changes the working directory when the user saves or opens an .xyz file. I could use a pack uri for the part drawings, but I use Process.Start for the user manuals because they are a PDF. I tried searching, but couldn't come up with anyting.

awilinsk
  • 2,054
  • 6
  • 31
  • 50

6 Answers6

7

You should be able to get to your install directory either by finding the executable's directory or by using reflection to find an assemly's directory:

By finding executable, you could add a reference to Windows.Forms to make this work (admittedly not ideal):

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

string appPath = Path.GetDirectoryName(Application.ExecutablePath);

Using reflection:

using System.IO;
using System.Reflection;

string path = Path.GetDirectoryName(Assembly.GetAssembly(typeof(MyClass)).CodeBase);

Or

string path = System.Reflection.Assembly.GetExecutingAssembly().Location;

You can probably just cache that path onload of your app as it will not change.

brendan
  • 29,308
  • 20
  • 68
  • 109
  • Application.ExecutablePath does not exist in WPF, so I used reflection. This works for the PDF files and as for the Image files, I'm using a pack URI. It just seems like there would be some better way of handling this scenerio. – awilinsk Jun 18 '10 at 14:24
  • As [this link](http://stackoverflow.com/a/948438/419348) said, `System.Reflection.Assembly.GetExecutingAssembly().Location` might get the location after `shadow-copying`. – AechoLiu Jun 05 '14 at 02:52
5

There's a difference between the location of the Assembly and the working directory of the application. Sometimes these might be the same, but this must not be the case. To change the working directory you can execute your application from cmd.exe or just create a shortcut with a different directory in the Start in Property.

You can get the working directory of the Application like this:

System.IO.Path.GetFullPath(".")

Note: The .-Directory is always the current working Directory, we just get the absolute path to it. Sometimes you might not need the absolute path. For example if you want to read a file in the working directory:

new StreamReader("./file-in-the-working-directory.txt");

or even:

new StreamReader("file-in-the-working-directory.txt");
MarcDefiant
  • 6,649
  • 6
  • 29
  • 49
  • 1
    Why do all those other answers are favorised? This one is the only correct one. All the others give the Location of the executable instead of the working directory. – marc40000 Aug 12 '15 at 10:15
1

Another thing you might want to do is simply reset the current working directory on startup.

Directory.SetCurrentDirectory(GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));

That will get you squared up.

Joel Barsotti
  • 3,031
  • 7
  • 35
  • 59
0
Path.GetDirectoryName(Application.ResourceAssembly.Location)
Andre Silva
  • 4,782
  • 9
  • 52
  • 65
Andreas
  • 3,843
  • 3
  • 40
  • 53
0

This thread might help:

http://bytes.com/topic/c-sharp/answers/255026-get-directory-running-executable

Lunivore
  • 17,277
  • 4
  • 47
  • 92
-1

Just in case you need to wrap your brain around just getting a path, I'm leaving you with my example. I used the name of the project to track down how to break apart the full path string. I'll even leave the original line, so you can maybe understand the thought process.

var filepath = System.Reflection.Assembly.GetExecutingAssembly().Location;
var rootindex = filepath.IndexOf("TestProject\\");
var wordlength = "TestProject".Count();
var rootpath = filepath.Remove(rootindex + wordlength);
sDir = filepath.Remove(rootindex + wordlength);
//sDir = "c:\\dev\\Test_Solution\\TestProject";

I know this is basic stuff, but I've been off the job for a few months and sometimes it's nice to have a little help with the obvious stuff.

Ria
  • 10,237
  • 3
  • 33
  • 60