Working Directory in Visual Studio C# file - c#

What exactly is Working Directory in the properties of Visual Studio C# project.
I have see a project where I right click and go to Properties and then I go to Debug tab, it shows me Working Directory where Author of the code has specified folder in local machine. I want to know what does that working directory means and what kinds of file will it store in that directory.
Thank you in advance.

Every process has a current Working Directory which is where all relative paths will be formed from. If not specified, this directory is the directory in which the active application started.
You can check which directory is set by calling:
System.IO.Directory.GetCurrentDirectory();
As mentioned above in a comment by #0xA3 this setting has no effect to your deployed product, it is is only for debugging.

The working directory of a project (and any Windows program in general) is the default place in which a program is looking up it's files. For example: My program has working directory C:\dir and tries to open test.txt, it would look in C:\dir\test.txt.
So every opened file will be opened relative to the working folder.

I think it will store nothing there, unless you add/write code in your application which explicitly creates files, either explicitly in the application's working directory, or implicitly specifying only a filename without specifying a directory at all.

Related

FileNotFoundException is occur while running Wpf application on 32bit machine

I created setup file using Inno setup.I have exe,dll and one xml file in my setup.
When I install on 64 bit machine it works fine means it take xml file from directory where exe is present.
But When I install same setup on 32 bit machine it take dll path but while accessing xml file it takes path of desktop where shortcut of exe is present and showing FileNotFoundException.
Thanks
Your application is most likely not specifying pathnames on the files it is trying to open, so it is expecting to find them in the current directory. Inno Setup by default does not set the "Start In" field on shortcuts its creates; this causes Windows to pick a directory itself, which usually won't be the directory containing your application.
In virtually all cases, this is something that should be corrected at the application level. Properly designed GUI applications should not expect to be started from a particular directory; they should always specify full pathnames on files they open. In Delphi or C++Builder, for example, it's possible to get the full pathname of the directory containing the application EXE by calling: ExtractFilePath(ParamStr(0)). To get the full path of a file named "File.txt" in the application directory, use: ExtractFilePath(ParamStr(0)) + 'File.txt'.
To get path of working directory of application while loading xml file in code.
string WorkingDir=System.AppDomain.CurrentDomain.BaseDirectory
XDocument temp_xdocument= XDocument.Load(WorkingDir+"file.xml");
It works for me.

Defining where files are installed

I am trying to deploy a .NET application as a ClickOnce Application, but I am having trouble defining where the application is installed. I need to know this because I have to include support files. I have already added the support files as "existing items". I had assumed that the program would install in Program Files, but it does not exist there. Instead, there is just a shortcut on the desktop. Can someone explain how/where the install path is defined using VS2012?
One solution I found was to use some of the Application class properties to determine where ClicOnce installed an instance of my program. But be aware that some those are deleted on uninstall of the program.
// To get the path for the executable file that started the application, not including the executable name.
PATH_RESOURCES = Application.StartupPath ;
For persistant data I created references to specific paths like :
PATH_USERDATA = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\myAppName\";
if (!System.IO.Directory.Exists((string)PATH_USERDATA))
{
System.IO.Directory.CreateDirectory((string)PATH_USERDATA);
}
PATH_REPORTS = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + #"\myAppName\";
if (!System.IO.Directory.Exists((string)PATH_REPORTS ))
{
System.IO.Directory.CreateDirectory((string)PATH_REPORTS );
}
Clickonce application gets installed under the user profile, not the Program Files path.
On windows Vista and Windows 7, clickonce application path will be somewhere in c:\users\username\AppData\Local\Apps\2.0\
On Windows XP, clickonce application path will be somewhere in c:\document and Settings\username\LocalSettings\Apps\2.0\
Note that Clickonce application path is different everytime upon installation, I found the best way is to make your app to write its own app path to the reg key, this way you know exactly where the app path is by looking at the reg.
So as user831062 pointed out, ClickOnce apps get installed under the user profile, not the Program Files path. Because of this, the install directory is different on every machine and almost impossible to access directly.
The part that I was hung-up on, was where are the files that I have included in the project located, and more importantly - how do I access them?
Well, as mentioned IN THIS LINK, if you mark the file as a "data file", under:
Project Properties > Publish > Application Files > Publish Status
you'll be able to access them using something like:
textBox = File.ReadAllLines(ApplicationDeployment.CurrentDeployment.DataDirectory + #"\myFile.txt")).ToList();
If you don't mark it as a "data file", but rather as just an "Include (Auto)", it will just be located in the install directory itself, which can be accessed by calling the file directly using something like:
textBox = File.ReadAllLines(#"myFile.txt")).ToList();
Anyway, took me an hour or so to find this, so hopefully it helps someone else out.
If you have added your files to your project, set the property for "build action" to "content" and set "copy to output directory" to "copy always". This way, the files will be included in your deployment. When the application is run, retrieve the location of the assembly and look in the same relative folder as where they were included in the project. For example, if they are in the top folder of the build output directory (/bin/debug/ or /bin/release/), they will be included in the same folder as the executable, which you can discover using this:
System.Reflection.Assembly.GetExecutingAssembly().Location

Visual Studio Moving a Content File on Publish

I'm developing a Web application that uses a couple XML files to store data. I have their Build Action set to Content, and on install the files are copied successfully to the Applications Virtual Directory:
C:\inetpub\wwwroot\ApplicationName\
The problem I'm having is that writing to these XML files (in order to save settings and things like that) causes a lot of write permissions issues. Therefore to get around it, I'm trying to copy these files from the virtual directory they're installed to to a new directory under the C drive, using the following PostBuildEvent in the Web Deployment Project:
xcopy "$(TargetDir)*.xml" "C:\CompanyName\ApplicationName\" /y
However, this does nothing. I'm not sure if this is because PostBuildEvents in the installer are not actually fired on install, but only on building the installer, or if TargetDir represents the bin directory:
C:\inetpub\wwwroot\ApplicationName\bin\
instead of the root application virtual directory:
C:\inetpub\wwwroot\ApplicationName\
Does anyone have any ideas? Has anyone dealt with this sort of thing before? I'm really stumped on this one.
Update:
I included a PostBuildEvent that should give full permissions to all users:
icacls "$(TargetDir)" /grant Users:F
But it doesn't seem to have resolved the problem.
I'm also unsure where exactly $(TargetDir) if pointing to, if it would be ..\ApplicationName\ or ..\ApplicationName\bin\
All you have to do is give full permissions to the user under whose context the Web Application Pool runs.
You can find this user by starting IIS manager and look at the Application Pools and Identity column
Something like
cacls C:\inetpub\wwwroot\ApplicationName /G Users:F
will give all permissions to this subdirectory to all users on the computer, If you are running under ApplicationPoolIndentity refer here
Turns out there's a much easier way to do what I was trying to do.
Instead of using PostBuildEvents to create a new directory structure and move files there, I added the new directory structure into
InstallerProject > View > File System
after which I located the Content Files from SomeProject entry in my installer project, and changed the Folder value to the newly specified directory structure, in this case
C:\CompanyName\ApplicationName\
This seems to work fine, I'm now able to access these files freely as I originally intended.

Program path under Windows XP(C# program)

My program works fine on Windows 7/ Vista and most Windows XPs I've tested on. I open a file that is 1 directory under the program itself. It's Administration\adm.txt (that's exactly the relative directory that I use) . I am using .NET 2.0 for my project.
I tried to run my program on an old Windows XP(which had .NET 2.0 installed) and I got the strangest error I have ever seen in my life. The program runs fine, until the user opens an open file dialog. Afterwards the program started thinking that it was in the directory where the open file dialog last was. So if the open file dialog was last browsing through C:\My Documents\ and I try to open the Administration\adm.txt file I get an exception that "C:\My Documents\Administration\adm.txt" does not exist. Unfortunately I can't use that computer myself again, but I'd really like to know how this happened. Does anybody have any ideas?
Standard behaviour in Windows is for the file dialogs to change the application's current directory. You can prevent it with the OFN_NOCHANGEDIR flag to the OPENFILENAME structure
that is used to configure the open and save dialogs.
For the story, see the Old New Thing blog:
http://blogs.msdn.com/b/oldnewthing/archive/2010/11/12/10089878.aspx
As well as tinman's reply, I will add that it is not a good idea to use a directory that is relative to the current directory, because other processes (including your own as you have seen) can change the current directory. The following code is a more reliable method to create a file name in a directory below your program's directory:
string exeDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string fileName = System.IO.Path.Combine(exeDirectory, System.IO.Path.Combine("Administration", "adm.txt"));

Deploying c# application issues

I have a application with one folder which i added by right clicking the project, selecting add folder. Inside this folder i have xml files which are set to build action:content, copy to output directory: copy if newer (i have tried setting to embedded resource) As well as this i have a few text files and so on.
In my bin/debug output directory i have the exe, the folder with the xml, the stand alone .txt files and so on. My problem is, if i send the exe to my friend to try he always gets an exception thrown.
Say he puts the exe on the desktop, my programme at some point reads the filenames of the xml files in the folder. It uses the following code to do so
String[] filePaths = Directory.GetFiles(#"DataSources\");
I assume that because of this, when the exe runs from the desktop, it expect the folder of .xml files to be in the same place? I have the same type of exception when trying to read the .txt files too. What am i doing wrong here?
Thanks for your time
When reading from files using relative paths you get the one relative to the applications current directory. tip: In C# you can see what directory that is using Environment.CurrentDirectory.
So if you create a shortcut on your desktop, you need to make sure you right click the shortcut and set its "Start in"-folder to the directory of your application. That way its current directory will be set when its started and relative paths will be relative to that path and not the path of the shortcut.
If you actually moved the exe file to the desktop you also need to move any resources that it needs, so if it wants a folder named "datasources" you would have to move that folder as well, or set the current directory when you start the application.
Have you tried something like: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.executablepath.aspx or http://msdn.microsoft.com/en-us/library/system.environment.currentdirectory.aspx ?
So
Directory.GetFiles(environment.currentdirectory + #"\DataSources\");

Categories