I'm having a brain fart at the moment. I have a set of files that are read in by a class library in a .NET Web Site. The issue is the files are used in three different sites (all the sites reference the class library), so I don't want to copy the files across all three. What I want to do is have a folder in the class library itself as a shared resource, something like this:
ClassLib
\Templates
-file1.xml
-file2.pdf
-MyClass.cs
and have MyClass read the files from the Templates directory. Easy enough, except that MyClass.cs is called from a page, let's call it Default.aspx. Now MyClass.cs has code like the following:
IList<string> files = GetTemplateFiles(); // returns the path to the template files e.g. Templates/file1.xml
foreach (string file in files) {
if (File.Exists(file)) {
// do things here...
}
}
File.Exists is always false, seemingly because it is looking in the default directory and not the path to ClassLib (which is something like C:\Projects\Shared\MyLib\). Now, I cannot use AppDomain.CurrentDomain.BaseDirectory because this varies based on the web site which is calling it; the templates should always be available from the Templates directory in the class library, not the calling application. The properties in Assembly.GetExecutingAssembly() don't seem to be of much help either, pointing to ASP.NET Temporary Files.
Basically my question is what the best way to handle this would be. The template files should be a shared resource available to every application (and not copy/pasted into three Templates/ directories in each application), but I don't know which application will call it at a given time so I need to avoid hard-coding the file path to the templates folder. I'm missing something small but critical in how I'm trying to retrieve the template file, but I can't figure out exactly what.
Decide on a common, shared path available to all three sites and define that path in your web.config files, making sure that IIS is able to access that shared folder.
Related
I have an Asp.net web service and I need to store user-uploaded files. At first I thought of storing them in the App_Data folder, however, I now see that when publishing from Visual Studio with the 'Remove additional files at destination' option, it will remove files from the App_Data folder despite checking also the 'Exclude files from the App_Data folder'.
(There seem to be workarounds for this, but if it's not through the 'Publish' designer, I'm afraid that at some point the files will be removed, either due to human error, or some future MS update that will break it.)
So, I need some folder that is not under the publish path, and yet accessible (to the web app, not to the public), and that will not be auto-deleted.
EDIT
This is being done on a web hosted environment, so privileges are limited.
You may choose any folder in any path (even in another drive) as long as your asp.net application has privilege to write to it. you may even create a virtual directory for this purpose.
Edit
As you are using a hosting environment, I don't know which options they have provided, as sometimes they restrict a lot, however in most cases when you are creating a new website in your hosting environment, you are asked to provide the path something like : \wwwroot you may want to change it to something like:
\somepath\wwwroot (of course you should create somepath first), and you will have access to somepath too.
Trying to get relative path of config file, which is next to a class in core project, and also trying to avoid hardcoded relative paths (i.e. "../../../seleniumconfig.json")
This is my project structure,
Awesome.Core (library project)
Selenium (folder)
ZSelenium.cs
seleniumconfig.json (want it here so only powerusers can reach to this file)
Awesome.OtherProject1 (calling project, references Awesome.Core)
Program.cs
Awesome.OtherProject2 (another calling project, references Awesome.Core)
Program.cs
Program.cs (in Awesome.OtherProject1)
using (var scope = Container.BeginLifetimeScope())
{
var selenium = scope.Resolve<ZSelenium>();
...
}
ZSelenium.cs
var rootDir = new DirectoryInfo(Environment.CurrentDirectory);
// "/users/myuser/Documents/MyProject/AwesomeProject.OtherProject"
I can construct my relative path from rootDir variable, but there will be a lot of hardcoded ../../.. stuff which I would like to avoid. Also, if I call ZSelenium.cs from another project, the relative path might change.
Does anyone know a better way to get the path of ZSelenium.cs within the core project?
Configurations files do not belong into the Programm folder, ever. We did kind of do it anyway in the Windows 98 times, but it was frowned upon back then. Since XP is it not reliably possible anymore to write such a configuration file. The Programm folders is protected. Most users can only read them, not write them for security reasons. And that includes any programms started by that user too.
If you want to store user or system specific settings, that is what the special folders are there for. Their one defining purpose is that whatever user runs your programm, should have read (and likely write) access to his own and all shared folders.
You may be able to add a "default configuration" to the Programm directory to use as pattern for new users. But even for that there is a existing structure (the default user folder) so you can leave placing the template to the Setup.
i have a small app in C# winform. It work great but i don't understand how to change the image of a picture box in code :
i have this directory for my image :
myProjectDirectory/bin/Pics/myImage.jpg
and this code give me an FileNotFoundException :
this.imgInvader.Image = Image.FromFile("../Pics/invader2.jpg");
i don't understand because i see on stackoverflow that FromFile method begin at bin/Release. So a ../Pics/myImage.jpg should work no ?
Thx
Use the relative path of the image.
this.imgInvader.Image = Image.FromFile(#"bin\Pics\invader2.jpg");
Here give the path from the location where your code behind file is located. Suppose if your file is in root directory and if your images are in bin/Pics/ folder then the above code works. It automatically gets the path related to the location the program is running from.
Trying to reference image files that are outside the executable output directory is incredibly fragile. There are lots of ways it can go wrong (unfortunately, there's not enough context in your question for anyone to know exactly which of these ways is your specific problem).
If you must use files on disk to store your image resources, then they should be copied into the build output directory (i.e. "Release") and referenced there. Add the file to your Visual Studio project, select it, and in the properties window, set the "Build Action" value to "Content". If the file is in a folder under the project, then it will also be copied to a folder of the same name in the output directory.
If you do use files on disk, the other thing to make sure you do is find the executable's directory (e.g. via Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)) and then combine that with your expected relative path (e.g. just the file name, or the file name under whatever folder/subdirectory you gave it in the project, if you did) using the Path.Combine() method, and then using that absolute file name as the source. Otherwise, your code can be confused by changes in the current directory made elsewhere in your program (basically, don't ever rely on the current directory…global state like that is too easy to get mixed up, once you get into the habit of using it).
For example:
string exeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string imageFileName = Path.Combine(exeDirectory, "invader2.jpg");
Now, all that said, IMHO it is probably a better idea to add your images as resources in the executable itself, and then reference them from the Properties.Resources class. Then the images are always with the executable, because they are in the same file. The code is a lot easier too, because you're just referencing properties in the Resources class that return the actual Image objects you need.
As the previous comment stated, using resources outside of your exe is not advised however you can still do this by using the Path.GetDirectoryName Method.
I am left to question why your resources are based outside of your exe, why not embed it into your resources located in properties > resources.resx and simply call it with imgInvader.Image = Properties.Resources.FileNamehere; it is a lot safer than trusting the external environment.
I have searched and searched and can't find a solution to my specific problem. I am updating a console app that will now be used for more than one client. We have decided, over storing the info in a db at least for now, to store the clients info in config files. Each client will have their own configuration file. I need to know how to load a/any config file from an "unknown" location. All of the examples that I found want me to put in the path of the file. While using my computer, I will know the path, but once it gets pushed to other servers, the paths to the file will change.
Working under these conditions, how can I load a config file for any client without knowing the path to the file?
EDIT: The console app is only ran on one server, but it is used to go to different clients websites and crawl their site. This is why each client has their own config file. It contains the information needed to get and use their site. We have a task set up for the app to run each client on a timer.
Since everything was being read from the bin folder, I looked at the properties and changed from Do Not Copy to Copy Always for Copy to Output Directory. Now it WILL locate the config files in the bin folder. And the answer to this question put me in the direction to read my config files.
What about writing every piece of code with in mind that it is to be used in another file, say with an include statement. So, every file is used in another one until we reach a wrapper file, which only purpose is to define the location of the config file. The application would always be called through such a wrapper file. This wrapper file will do whatever necessary to determine the location of the config file and make it available to the included files. If it knows the user, it can look up in a table. The key point here is that, the wrapper files would not move when you move the code from one environment to another. I think that this is a useful feature, because we do not want edit the code each time that we move it from one environment to another. Another advantage of this approach is that it applies to all environments, even very limited environments. For example, let say you provide only a folder to a programmer as a sandbox to experiment with the code. This programmer does not have access to the /bin or the /etc directory. In contrast, the proposed approach will work fine in this case, because the programmer can set the config files wherever he wants in its local wrapper files. This issue is discussed here How to organize code so that we can move and update it without having to edit the location of the configuration file?
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.