Confusion over relative and absolute paths - c#

I have a WPF program which deals with images on a canvas.
I am at the stage where I am trying to use serialization to be able to save the contents of my program and reload it at a later stage.
So At the moment when I am inserting any images into a control I am using absolute path values, I understand that this would be a bad idea for a program where I am wanting to save the state of the program and reload it at a later time.
So what is the best course of action to take in this situation.
Do I create a folder inside my WPF project for example called Images and then do I copy all Images I use in my program to this folder and then point the path to this?
Or am I completely on the wrong lines here?

If you are serializing the state data of your application, you would usually create a folder in one or more of the so-called system special folders, which you can get by a call to Environment.GetFolderPath.
You may for example store data with application scope (same for all users) in a folder below the special folder specified by the SpecialFolder.CommonApplicationData enum (which is C:\ProgramData on Windows 7 systems).
Data that is specific for the current roaming user (who works on multiple computers on a network), would be stored in a folder below SpecialFolder.ApplicationData. There is also SpecialFolder.LocalApplicationData for the non-roaming user.
You may take a look at the Environment.SpecialFolder enumeration to get an overview.

From my own experience, create a folder and save the images there. It will just make your life easier in the long run, and it makes it easy to see where the resources of the application are.

Related

Is it possible for a user to only select file save location once?

I've been trying to learn how to handle saving normal .txt files in UWP, and have realized that it's quite locked down compared to WPF, especially in the sense of what folders you can access without requesting the user to select a location. I have searched for various ways this might be possible but found no working answer.
Question Description:
I basically would love to know if this is possible, and preferably a point in the direction where I can learn how exactly to do this.
Application settings page requires user to select folder where files are saved.
Application remembers this between launches (unsure if this is possible, but I can't require the user to select the folder on every launch)
Application saves files to the specified folder.
In my understanding, this should be possible, as the user is the one specifying the location via filepicker, but is it possible to have this work between launches so that the user wont be required to re-select the save folder?
I need to figure this out, as I would like my application to support selecting attached network drives, cloud storage folders, etc.
Any help is very much appreciated, and if there are any questions I will answer them to the best of my ability.
Fow this purpose there are two access lists designed: FutureAccessList and MostRecentlyUsedList. Once the user has picked up the folder with the picker, you add it to such list and receive a token, which you save for future purpose in LocalSettings:
ApplicationData.Current.LocalSettings.Values["MyFolder"] = StorageApplicationPermissions.FutureAccessList.Add(pickedFolder);
Then later, once you want to access that folder, you can do it like this:
StorageFolder folder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(ApplicationData.Current.LocalSettings.Values["MyFolder"].ToString());
You can't save a StorageFolder or a path to it in settings, hence the UWP app needs permissions to access the folder. Using above access lists solves this problem.
I believe you want to save user settings and keep it somewhere so that next time when they launch the application, they can use the same settings.
Please check out this tutorial from Microsoft, which describes how to do exactly that.
https://msdn.microsoft.com/en-us/library/bb397750(v=vs.110).aspx

Accessing file information for all users, C#

I'm writing a short C# program that will iterate over each user on a given Windows system, check in their local app data folder for a specific directory, and operating on it if it exists.
I'm looking for a good way to resolve the absolute file path to each users' local app data folder. I can use Environment.SpecialFolder.LocalApplicationData but that will only work for the user that is currently running the program.
I know I can cobble together a few different utilities and make a couple assumptions about where a user's local data is usually stored to make it work for 99% of the time (determine a list of all users, go through each one and find/guess where their app data is, etc.), but I was hoping there was a more elegant solution?

C# ClickOnce install folder - how windows generate the folder names

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.

Should I save uploaded(img files) to App_Data?

I am using asp.net mvc and have a section where a user can upload images. I am wondering where should I store them.
I was following this tutorial and he seems to store it in the app_data. I however read another person say it should only hold your database.
So not sure what the advantages are for using app_data. I am on a shared hosting so I don't know if that makes a difference.
Edit
I am planning to store the path to the images in the database. I will be then using them in a image tag and rendering them to the user when they come to my site. I have a file uploader that only will expect images(check will be client and server)
The tutorial is a simple example - and if you read the comments, the original code just saved to an uploads directory, no app_data in sight.
It was changed to app_data because that's a special folder - one that will not allow execution of code.
And you have understood correctly - app_data is really there for holding file based databases. That's the meaning of the folder. As such saving images into it doesn't feel like the right thing to do.
If you are certain only images will get uploaded (and you control that), I would suggest an /uploads directory - a reserved location for images that also will not allow code execution (something that you should be able to control via IIS).
I would say that depends on what you will do with that images later. If you use those images in an img tag, you could save them somewhere in the Content/ folder structure.
If you do not need them reachable from the outside, or need to stream them changed back, you might store them out of the web root if the hoster allows for that.
I wouldn't store them in app_data, as I - personally - think that it's more a convention to store there a database. Most developers not familiar with that product wouldn't look there for the image.
But: you could store binaries in a db (even though it is probably not the best thing to do), so a reference in a db pointing to a file in the same directory makes sense again.
It's more an opinion thing than a technical question though, I think.
I prefer to store them in the database. When storing images on the file system I've found it can be a bit harder to manage them. With a database you can quickly rename files, delete them, copy them, etc. You can do the same when they're on the file system, but it takes some scripting knowledge.
Plus I prefer not to manage paths and file locations, which is another vote for the database. Those path values always make their way into the web.config and it can become more difficult to deploy and manage.

How to handle temporary files in an ASP.NET application

Recently I was working on displaying workflow diagram images in our web application. I managed to use the rehosted WF designer and create images on-the-fly on the server, but imagining how large the workflow diagrams can very quickly become, I wanted to give a better user experience by using some ajax control for displaying images that would support zoom & pan functionality.
I happened to come across the website of seadragon, which seems to be just an amazing piece of work that I could use. There is just one disadvantage - in order to use their library for generating deep zoom versions of images I have to use the file structure on a server. Because of the temporary nature of the images I am using (workflow diagrams with progress indicators), it is important to not only be able to create such images but also to get rid of them after some time.
Now the question is how can I best ensure that the temporary image files and the folder hierarchy can be created on a server (ASP.NET web app), and later cleaned up. I was thinking of using the cache functionality and by the expiration of the cache item delete the corresponding image folder hierarchy, or simply in the Application_Start and Application_End of Global.asax delete the content of the whole temporary folder, but I'm not really sure whether this is a good idea and whether there are some security restrictions or file-system-related troubles. What do you think ?
We do something similar for creating PDF reports and found the easiest way is to use a timestamp check to determine how "old" files are, and then delete them based on a period of time, in our case more then 2 hours old. This is done before the next PDF document is created, but as part of the creation process. We also created a specific folder and gave the ASP.Net user read/write access to the folder.
The only disadvantage is that if the process of creating PDF's is not used regularly there will be a build up of files, however they will be cleaned up eventually. In 2 years and close on 4000 PDF's we have yet to have an error doing it this way.
Use the App_Data folder. This folder is inside your application and writable by your app without having to go outside the context of the app, but it's also secured from casual browsing. It's meant to hold data files for your application.
Application_Start and Application_End will only fire once each, so if you need better cleanup than that, I would consider using a cache structure or a simple windows service to handle the cleanup.
First, you have to make sure your IIS worker process has rights to write/delete files from your cache directory (and NOT the rest of your site, just in case)
2nd, I would stay away from using App_Start and App_End, App end to clean up files is not 100% guaranteed to fire, and you could end up with a growing pile of orphaned images.
I would instead make a scheduled process, maybe runs once per hour, or once a day, depending on what you want. And have it check how old each image in your cache is, and if its older than your arbitrary "expiure time" then delete it.
Other than that there's not much to it.

Categories

Resources