Simple question here. I have a C# program which needs to stores some files onto the hard drive, but I don't need them to be anywhere useful to the end-user, only somewhere that the program can read/write from.
Is there a directory that I can reference programmatically to be my "filespace playground" - that is, that I can read/write freely to and from?
EDIT: Also, if I use a temp directory, how long are the files guaranteed to be there? I don't want the them to disappear while my program is still running!
I would use the Application Data Directory. You can get to it using something like:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
It is the prefered location in windows for application specific data and it is generally hidden from the user unless they would like to go and find it.
You can use the system temporary directory which you can get with:
string tmpDir = System.IO.Path.GetTempPath();
If you want, you can create a subfolder under there. The temp folder is great for files that you don't care about. If you want to keep the files you can use the ApplicationData folder as Tim C and Graham Miller suggested.
I think you want the application data directory:
var appplicationDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
It sounds like you're looking for isolated storage:
Isolated storage is a data storage
mechanism that provides isolation and
safety by defining standardized ways
of associating code with saved data.
Standardization provides other
benefits as well. Administrators can
use tools designed to manipulate
isolated storage to configure file
storage space, set security policies,
and delete unused data. With isolated
storage, your code no longer needs
unique paths to specify safe locations
in the file system, and data is
protected from other applications that
only have isolated storage access.
Hard-coded information that indicates
where an application's storage area is
located is unnecessary.
Use the system Temp directory:
System.IO.Path.Combine( System.IO.Path.GetTempPath(), "your app name" )
The temp directory is automatically cleaned up by the system (usually by hard disk cleanup) so it's usually the best bet for storing random files that are only needed while the app is running and don't need to stick around.
If you need a more permanent solution that is storing user data files, use the AppData folder as suggested by other folks.
C:\TEMP?
seriously, no, there is no build-in sandbox playground. You have to chose/create a directory which fits your needs.
This is normally the AppData folder. It's in a user specific directory tree, but not in a place that normal users go.
Usually, app-specific data is stored in locations specified by of the SpecialFolder enumeration. You can use ApplicationData for per-use app-specific data, or LocalApplicationData for per-computer variant:
var playground = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData));
Isolated Storage may work for you.
http://msdn.microsoft.com/en-us/library/bdts8hk0%28VS.95%29.aspx
or,
http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/53def6a4-076c-43f8-86e9-e223d99396a0
The base class library offers you a class to manage a set of temporary files. It is well hidden in the System.CodeDom namespace but nonetheless it can be useful in other contexts as well:
TempFileCollection
The following sample shows how the TempFileCollection class can be used.
using System;
using System.CodeDom.Compiler;
using System.IO;
class Program
{
static void Main(string[] args)
{
TempFileCollection tfc = new TempFileCollection(Path.GetTempPath());
// add a temporary text file
string filename1 = tfc.AddExtension("txt");
// add another file with a fully specified name
// this file will not automatically be deleted
string filename2 = Path.Combine(tfc.TempDir, "mycustomfile.txt");
tfc.AddFile(filename2, true);
Console.WriteLine(tfc.Count);
// Create and use the test files.
File.WriteAllText(filename1, "Hello World.");
File.WriteAllText(filename2, "Hello again.");
tfc.Delete();
}
}
Related
I need to make a program that reads the columns of an excel. But for that, I need to get the path (directory) of this excel. What prevents me from doing this, is that I didn't want to leave my local directory fixed, because if someone downloads the file on another machine, they will need to change the path.
You asked How to get directory of an xls file C#.
As others have pointed out, the file needs to be in a known location and one way to do that is to add the Excel file to your solution and mark it as Content, specifying that it should be copied to the output directory. The image below shows how to set these properties.
You also seem to be looking for a robust way to make this happen when you deploy the app for other users. For this, you will need a strategy for making an .msi or .msix that will place this file where it needs to be. But to answer your basic question the way you asked it the path in this case can be obtained in this manner. This code will get the path and open the Excel file.
// Get the path and open the Excel file
static void Main(string[] args)
{
var path =
Path.Combine(
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
"Microsoft Excel Worksheet.xlsx");
Console.WriteLine(path);
System.Diagnostics.Process.Start("explorer.exe", path);
}
I should mention that a file in the executing directory can be read but not written (without elevated permissions). If the file is user data then refer to the answer that uses an Environment variable:
var appdata = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
You have two options:
If you don't want to your excel files to be stored in your application's directory, you can simply put things in the root of your C: partition. Every windows device is gonna have the C: partition. As the user Lee Taylor has pointed out, it turns out you can have a windows device without the C: partition, although uncommon
If you don't mind having your excel files stored in your application's directory, you can get the relative path of your application's directory throughPath.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
There are other ways but I believe these are the simplest and easiest to do.
If you just need to dynamically get the path to a file that is in the same project directory, then the following code works for me -
string filePath = Directory.GetParent(Environment.CurrentDirectory).Parent.FullName + "\\excel\\Prices.xlsx";
where "\excel" is the folder in my project and "\Prices.xlsx" the file in the project
edit: About the path-problem. I will try to get there later. For now I just need help for zip a file. Could not find a way to do this yet.
Im currently going through a few basics and I don't know what I have to look for to get to where I want to be. So, what are my goals?:
I want to create a name.json file here C:\Users\Username\Desktop
Then I want to compress name.json to an zip file.
I also created another file Testfile.zip on my Desktop. I want to unzip that file.
So far I created a name.json file. But I cannot find a solution on how to create one on the desktop.
I could not find a solution on compressing name.json so far.
public MainPage()
{
this.InitializeComponent();
createJson();
UnzipFile();
}
public async void createJson()
{
string text = "This text";
string json = JsonConvert.SerializeObject(text);
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("name.json");
await FileIO.WriteTextAsync(file, json);
}
public async void UnzipFile()
{
var localFolder = ApplicationData.Current.LocalFolder;
var archive = await localFolder.GetFileAsync("Testfile.zip");
ZipFile.ExtractToDirectory(archive.Path, localFolder.Path);
}
Working with .zip files is possible using System.IO.Compression.ZipArchive and related classes. You are already using ZipFile.ExtractToDirectory which is the right approach here. However, the issue you are facing is rather related to permissions.
UWP apps are sandboxed which means they are not allowed to touch any filesystem location by default. This is to ensure better security and easier uninstallation of apps. This however means you cannot easily create a file on the user's desktop, as your app does not have access there. The only folders your app can freely access are those accessible by ApplicationData.Current and then those it declares access to in application manifest. You can also declare broad filesystem access here to get access to all locations on the PC.
To further complicate this, there are two types of I/O APIs in UWP. The modern StorageFile API which is async enabled, but tad slower, and the classic file I/O APIs in C# which includes ZipFile and ZipArchive. The main disadvantage of the classic APIs is that they always have access only to application folders and you can never access any other system paths, even if you declare broad filesystem access.
However, even without declaring broad filesystem access capability you can manually get access to the folder/file of user's choosing using FolderPicker, FileOpenPicker and FileSavePicker. Using these you can let the user choose the destination where you will save the file or open a file.
Finally - to circumvent the limitation of not being able to use the classic file I/O APIs, you can first unzip the .zip file in a temporary folder inside ApplicationData.Current.LocalFolder and then use the StorageFile.MoveAndReplaceAsync(IStorageFile) or StorageFile.MoveAsync(IStorageFolder) method to move the files to the location the user has chosen using FileSavePicker.
For further info you can check out this blog post with a tutorial on using .zip in UWP.
I would like to know how Windows generate folder, where will be ClickOnce application installed.
In Startmenu is "shortcut" to file, what is putted in some "startrek" folder like:
C:\Users\USERNAME\AppData\Local\Apps\2.0\GT??4KXX.PRJ\EGV???1G.??C\prin..tion_7???5a2?????74b6_0000.0002_1dae????89111c35
What does those folder names mean?
For example:
If i will have for example some settings.txt file where i want that user can change some parameters of the application. Is there way how to know, WHERE it will be installed and WHERE the file is? (Where user will find this settings.txt file).
I know that i can create the file for example in C:\ and after start the application i will modify the file in "strong" path. But i dont really like too much files, folders, whatever in C:\ and i prefer to have settings files in same folder like the application. But with ClickOnce installations is it really hard - impossible - to find that file.
It seems like when the "startrek" is something like hash of the project.
So i would like to know what does the folder means and if its some hash of the project or what is that.
To find the folder that contains your executable, you can use the Assembly.Location property.
For example:
string exeFolder = System.Reflection.Assembly.GetExecutingAssembly().Location;
However, if you want to store settings for your ClickOnce app, you shouldn't do it by writing a file to the .exe's folder.
Instead, you should use Microsoft's Application Settings support. Doing it any other way is going to be a lot of extra hassle, and Microsoft's support is very good. It does need half an hour to read through the documentation, but it's far and away the best thing to do, IMHO.
(I'm assuming that you only need the settings to be stored on the local PC for the same user to use later. If you want the settings to follow the user around (i.e. roaming settings), you can't use the Microsoft support.)
If you have more complex settings that you want to store in a file that you create directly, you should consider using the isolated storage that the answer from JRoughan mentions.
From inside the ClickOnce app you can find the default directory where files are stored using
ApplicationDeployment.CurrentDeployment.DataDirectory
Or you can use isolated storage and choose whether you want to save per application or per user.
I don't think it's possible to determine these folders from outside the app itself. If you need a known location you'll have to hard-code it.
Update
I also don't believe it's possible to infer what the install directory will be for an app. It would be unwise to use even if possible as updates to the app will not be in the same location.
If you have data that the user is modifying through your program, you will be happier if you don't leave it in the ClickOnce program directory. You can get completely messed up when there's an update. Check out this article about what to do with your data to keep it safe and be able to find it. It talks about putting it in LocalApplicationData, but if you want your user to be able to find it and edit it, just put it in MyDocuments/yourappname/settings or something like that.
I wouldn't use Isolated Storage; there are reported problems with that and ClickOnce.
I am developing a WinForms application using C# 3.5. I have a requirement to save a file on a temporary basis. Let's just say, for arguments sake, that's it's for a short duration of time while the user is viewing a particular tab on the app. After the user navigates away from the tab I am free to delete this file. Each time the user navigates to the tab(which is typically only done once), the file will be created(using a GUID name).
To get to my question - is it considered good practice to save a file to the temp directory? I'll be using the following logic:
Path.GetTempFileName();
My intention would be to create the file and leave it without deleting it. I'm going to assume here that the Windows OS cleans up the temp directory at some interval based on % of available space remaining.
Note: I had considered using the IsolatedStorage option to create the file and manually delete the file when I was finished using it i.e. when the user navigates away from the tab. However, it's not going so well as I have a requirement to get the Absolute or Relative path to the file and this does not appear to be an straight-forward/safe chore when interacting with IsolatedStorage. My opinion is that it's just not designed to allow
this.
I write temp files quite frequently. In my humble opionion the key is to clean up after one self by deleting unneeded temp files.
In my opinion, it's a better practice to actually delete the temporary files when you don't need them. Consider the following remarks from Path.GetTempFileName() Method:
The GetTempFileName method will raise an IOException if it is used to
create more than 65535 files without deleting previous temporary
files.
The GetTempFileName method will raise an IOException if no
unique temporary file name is available. To resolve this error, delete
all unneeded temporary files.
Also, you should beaware about the following hotfix for Windows 7 and Windows Server 2008 R2.
Creating temp files in the temp directory is fine. It is considered good practice to clean up any temporary file when you are done using it.
Remember that temp files shouldn't persist any data you need on a long term basis (defined as across user sessions). Exaples of data needed "long term" are user settings or a saved data file.
Go ahead and save there, but clean up when you're done (closing the program). Keeping them until the end also allows re-use.
How would I create and write to a file in a Monotouch iPhone app?
The file should persist between application launches, so I guess it has to be placed somewhere in the App bundle ( documents or resources?).
[Note: My response is pretty thorough because I don't know your level of understanding regarding app bundles or the structure of your iPhone app's sandboxed little world - apologies if I cover things you already know - I prefer to write a little too much than too little, and to add a bit of the why when discussing the how...]
You have a few options (of course). I'm assuming you're already familiar with .Net to some extent and that your question is more about how to do this the iPhone Way.
Every iPhone app (and you'll see the same thing for apps on OS X) is a "bundle" which isn't an executable in the traditional sense, but actually a folder hierarchy inside of which your app binary lives (along with resources, settings, etc.).
Because of how uber-sandboxed iPhone apps are, you don't have access to the shared folders you'd usually be able to use when doing desktop development (having, for example, a common Documents folder that lives under a user's home folder to which applications have access).
Instead, your app has its own folder hierarchy that's like its own personal set of the folders that would typically be shared across apps.
The easiest way to see what your app's folder structure looks like on the phone is to look at the folder the iPhone simulator uses for app installs, settings, blah blah blah. On my machine (I don't recall if this is configurable, but it's probably the same on your system), you can get to the folder by this path:
~/Library/Application Support/iPhone Simulator
Inside of that, there's a User/Applications folder that contains the apps you've installed to the simulator. Drill down into any one of those folders, and you can see the folder structure your app will have access to on the phone.
For storing files that you'd like persisted across app sessions, your app's Documents folder is the spot. It's not your only choice for creating files, but it's the right choice for this job. In addition to your files being properly stored, keeping them in the Documents folder will also get them backed up by iTunes when the user syncs.
With MonoTouch, you can get your app's Documents folder path with Environment.GetFolderPath(Environment.SpecialFolder.Personal);
If you'd like to test it out, this is some extremely simple code that'll write a file called "out.txt" to your app's Documents folder. This code also reads the contents of the file to show it was created - for further verification, go to the simulator's Applications folder, sort the app folders by the date they were modified, drill down into the most recently modified, and look inside its Documents folder - you'll find "out.txt" (you can't find your app's folder by name because, when your app is installed, it gets stuffed inside a folder with a name like "2B3CA854-FADB-4DDC-9732-0E61B3DD8D8C" - sorting the folders by the date they were modified will point you to the most recently modified app, which, in this case, is whatever app contains the following code):
// For this to function, don't forget "using System.IO;"
// If you're just playing around with this to see it work, place it inside
// your AppDelegate's "FinishedLaunching" method in main.cs
string path = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
string filePath = Path.Combine(path, "out.txt");
// File.WriteAllText will create a file and then write text to it. If the
// file already exists, File.WriteAllText will overwrite it.
File.WriteAllText(filePath, "Howdy, world.");
// Now we prove it worked by reading the contents of the file and then
// printing them to the console...
string text = File.ReadAllText(filePath);
Console.WriteLine(text);
So, the only thing here that's really iPhone-specific is knowing that "Environment.SpecialFolder.Personal" maps to your app's Documents folder. Beyond that, it's .Net as usual.
And, again, this was probably overkill, but I wanted to answer sufficiently thoroughly for everybody who sees it.
The following How To from the Xamarin.iOS guide site has a few pointers to where to store your files:
http://docs.xamarin.com/guides/ios/application_fundamentals/working_with_the_file_system/
You can do something like this at runtime:
using (StreamWriter writer = new StreamWriter (Path.Combine (Environment.SpecialFolders.Documents, "yourfilename.ext"))) { }
and that will create the file. To open it for reading, use the same Path.Combine() but with StreamReader.