I have a series of files in my program, which take user input and store them as a KeyValuePair some of them have names, most of them just have a numeric ID associated with them. This information needs to remain persistent across the application starting and stopping. I've tried several approaches but I can't get any of them to work quite right.
My approach was to simply have a Content folder, full of .json files I knew I could expect. When the program first launched, it reads the file using the Newtonsoft JSON Deserializer, and loads it into the appropriate place in memory as a List<KeyValuePair<int,string>. That all works fine, but getting the path to the File has proven exceedingly difficult.
I started with literals, but then realized I need to be able to have the program in any directory. So then I tried finding the absolute path of the file, given its relative name to the project. Still doesn't work because debugging and publish directories, as well as copy on compile stuff. As a minor issue, I also am annoyed that I still needed to use a string literal here.
SO, I resolved to make it a .resx file. This immediately failed, because you can't edit a .resx at runtime. So, referenced the external .json file from the .resx. The process of getting the URI or Path from the .resx proved excruciating if not impossible. I first tried
Assembly.GetExecutingAssembly().GetManifestResourceStream("MyJsonFile.Json") which I hoped would work but didn't.
So I had it print out String.Join(Assembly.GetExecutingAssembly().GetManifestResourceNames()) all I got out from the console wasMyNamespace.Properties.Resources.resources` and no indication of how to further extricate the location of any particular resource.
I even tried Assembly.GetExecutingAssembly().Location and couldn't do anything useful form there because it referred to my exe in the debug folder.
My last hope was an embeded content file, but I can't save those during the run time either. I can refer to the properly with URIs instead of literal strings, but I can't save them mid runtime, like I would need to in order to save on edit, or to even save from memory on close.
If anyone can give me clear information on how to extricate the URI or Path of a file in my solution without using literals, I would greatly appreciate it. Because I am getting nowhere with research I've done and the tools I have.
If you put it in your bin/debug folder, you do not need the path. You just need the names of the files.
Otherwise put the path in the .config file and then read it from there like this:
<appSettings>
<add key="Path" value="PathToFiles"/>
</appSettings>
Then get the setting like this:
using System.Configuration;
string path = ConfigurationManager.AppSettings["Path"];
Make sure to import
Related
I generated a help file (*.chm) using HTML Help Workshop.
But there is one line I need to change every time I compile my solution.
Imagine you do have a complete finished *.chm file, but if a server builds the version new, this build number won't get updated in the *.chm file. For now I always deleted this *.chm file and created it new afterwards.
Now I reached at a point where it annoys me every time I have to create it new only because the server makes a build. It would be comfortable if i could modify the existing *.chm file directly in my C#-Code.
Is there any possibility to modify a *.chm file with C# code?
Yes. .chm files are really just an archive of a bunch of HTML files and some other bits to hold it all together.
Download a universal zip/unzip program like 7-zip and you can right-click (in windows) your .chm, then choose 7-zip>>Open Archive and you'll see the contents.
Be careful about monkeying around too much in here though since broken links and changed file names will ruin your .chm.
I would agree though that modifying your source before running it up through html-help-workshop is a better option than monkeying with it afterwards.
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?
I'm reading the contents of an XML file and parsing that into an object model.
When I modify the values in the object model, then use the following code to save it back to the xml:
XElement optionXml = _panelElement.Elements("options").FirstOrDefault();
optionXml.SetAttributeValue("arming", value.ToString());
_document.Save(_fileName);
This works, as far as I can see, because when I close the application and restart it the values that I had saved are reflected in the object model next time I view it.
However, when I load the actual XML file, the values are still as they were originally.
Why is this? What do I need to do to save the actual XML file with the new values?
You are most likely experiencing file system virtualisation, which was introduced in Windows Vista.
Basically what this means is that you are saving your file, just not where you think you're saving it. For example, you might think that you are saving to C:\Program Files\Your App\yourFile.xml, but what is happening under the hood is that the OS is silently redirecting that to %APPDATA%\Your App\yourFile.xml. When you go to reload it, once again the OS silently redirects from that location.
This is a security measure designed to better encapsulate applications and their data and to prevent unauthorised writes to locations where damage can occur. You can still force a save to %PROGRAMFILES%\Your App, but to do that you either need to relax the ACLs applied to that folder, or you need to elevate the privilege level your application runs at.
I wasn't sure whether to put this as a comment or as an answer, but I think it could be a potential answer. It sounds like the XML file is being saved because the data is being persisted across instances of the application. It may be file system virtualization like slugster mentioned, but it might be a simple as the fact that you are looking at the wrong copy of the XML file. If you are using a relative path, the file may have been copied to the new location. I would suggest you do a quick file search for that file name and see what you get back.
It turns out the file was being copied to and read from the Output Directory. I can see that it's being updated as expected from there.
I need to get the temp file to see what happened because the actual file is never output. However, I can't seem to find where the temp file is created.
I need to find this out without writing code or building the application because there are too many dependencies scattered all over the place. I would not be able to deploy a debug version.
That method returns the path of a temporary file. The path will tell you where its pointing.
For example:
Console.WriteLine(Path.GetTempFileName());
produces:
C:\Users\will\AppData\Local\Temp\tmp9BD5.tmp
for me on this machine, because the TEMP environment variable is pointing to C:\Users\will\AppData\Local\Temp\
But the whole point of a method like GetTempFileName is that you shouldn't have to care where the file ends up. On the off-chance that you do, you can always get there at command prompts or file-open dialogs by using %TEMP%