7

Can we depend on the current working directory in ASP.NET code-behinds? Or, in other words, can we use relative paths, and be sure that they'll work?

If, in one page on a website, I set the current working directory to something specific, will it still be the same the next time another page on the website is loaded? When the same page on the website is loaded?

If I set the current working directory to something specific, in Page_Load(), can I be sure that it will still be the same by the time Page_PreRender() is called? Or could another page on the same website change it on me, in between? Could a page on a different website in the same application pool change it on me? A page in a different website in a different app pool?

In other words, what is the scope of the current working directory, in IIS? Is it specific to a page? Is it specific to a web site? Or is it shared among all pages in an app pool?

Where, among page, website, app pool, and server, are the boundaries that isolate different values of current working directory?

Jeff Dege
  • 9,556
  • 21
  • 74
  • 132
  • 1
    Why would you want to leverage the current working directory on a web server? I don't understand how that makes any sense. The working directory is the directory that was used when launching w3wp.exe -- how is that relevant? – Kirk Woll Sep 10 '10 at 22:03
  • From the code-behind, we're accessing a .NET assembly that was written to provide shared functionality between web and desktop apps. A user can submit a job via a desktop app, or a user can submit a job via the website. In either case, the processing of the job is handled by the .NET assembly, and it finishes by writing a file to one of many queue directories, accessed via relative paths. The question is whether we need to rewrite all of the file handling in the assembly in order to make it work reliably with IIS. – Jeff Dege Sep 10 '10 at 22:39
  • You should not need to re-write anything. The directories will be relative to the root of the site they are in. – IrishChieftain Sep 10 '10 at 23:05
  • "If, in one page on a website, I set the current working directory to something specific" How do you "set" the current directory of a page? – Max Toro Oct 04 '10 at 21:22

3 Answers3

10

AppDomain.CurrentDomain.RelativeSearchPath will give you the physical path to the bin folder

Marek Grzenkowicz
  • 16,009
  • 8
  • 78
  • 100
Houston
  • 101
  • 1
  • 2
5

Environment.CurrentDirectory is a simple wrapper around the GetCurrentDirectory and SetCurrentDirectory winapi functions. Indeed, trying to set the directory requires UnmanagedCode permissions. Whenever a function prevents your site from running in partial trust, you are right to be wary of depending on it. :)

From the SetCurrentDirectory documentation:

Changes the current directory for the current process.

The best explanation I can find that covers the relationship between the w3wp.exe process and an ASP.NET site is this answer. Any other page within your site could potentially change your page's current working directory. Any pages on any other site under the same application pool could potentially change your page's current working directory. These outside changes to the current working directory could happen at any time during your page's execution. On the other hand, a page on a site under a different application pool will not change your page's current working directory. The reason I say "could potentially" is that it gets even more complicated if you consider web garden scenarios, where there can be more than one process for a single ASP.NET site.

Now consider that SetCurrentDirectory is not thread safe:

Multithreaded applications and shared library code should not use the SetCurrentDirectory function and should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. This limitation also applies to the GetCurrentDirectory and GetFullPathName functions. The exception being when the application is guaranteed to be running in a single thread, for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported.

Chances are that you don't want to depend on the current working directory. Having said that, given how foolish it is to rely on the current working directory, you can be reasonably certain that no other code will be touching it. :) A quick peek with Reflector shows that no .NET framework code changes it. A few functions do check it though, so watch out for those. If you control the deployment environment, you can ensure that your site runs in its own application pool. With proper synchronization technique, you should then be able to safely update the current working directory. I wouldn't consider it anything other than a hack though.

Community
  • 1
  • 1
Michael Kropat
  • 12,704
  • 9
  • 64
  • 85
0

Links should be created relative to the site root using the tilde (~) operator:

<a href="~/mysite/somepage.aspx" id="someLink" runat="server">Some Page</a>

Within a server, an application pool completely isolates your site so that if some other site crashes on the same server, it won't bring down your site with it. IIS is pretty much site-specific with the added isolation benefits of app pools. I can see no practical use in trying to change a link on one page from the code-behind in another (or maybe I don't quite understand the question).

Here's a summary of the IIS architecture:

http://learn.iis.net/page.aspx/243/aspnet-integration-with-iis-7/

IrishChieftain
  • 15,072
  • 7
  • 47
  • 90