I have a project that reads several text files into a List via StreamReader, I have the files added to my solution under Resources, when I try to reference the file using StreamReader, I get a "FileNotFound" exception.
The files are being copied over to bin\debug\Resources, and the error says it's trying to locate them under bin\debug.. How do I reference them without using the literal path? (e.g. C:\users\etc) since when I compile it won't run on another person's PC if I reference actual path.
Code that calls text file:
using (sr = new StreamReader("FileName.txt"))
{
while (!sr.EndOfStream)
Names.Add(sr.ReadLine());
}
Under the text files properties I have it set to "Copy Always" and under Build Action it's set to "Embedded Resource".
Basically my main goal is to compile the project into an exe with the text files being referenced internally (their contents aren't changed by the program), so my application will be portable.
Error is clear. Change code to:
using (sr = new StreamReader("Resources\FileName.txt"))
{
while (!sr.EndOfStream)
Names.Add(sr.ReadLine());
}
In your situation, the error will be removed by just replacing the path Resources\FileName.txt
In other case, as you mentioned that you want to make a portable .exe. Then you need to embed files in your application. Now see how to embed files in your .exe :
Expand Properties in Solution Explorer
Double click on Resources
On left top of Resources tab, there will be a combo box
Choose Files
Now just drag and drop your files there
To embed files, you can go to properties of every file by right
clicking on it. Choose Embedded in .resx from Persistence
property.
To use the file you can use Properties.Resources.YourFile.
For more details, follow the link http://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.80).aspx
Related
I added a pdf file ("myfile.pdf") with "Add Existing Item ..." to my wpf project.
Then I set the properties of it to "Resource" and "Do not Copy" (similar to the properties of other resources that I have, e.g flowdocuments).
Then I tried to execute
System.Diagnostics.Process.Start("myfile.pdf")
and obtained a 'file not found' error.
When I change the file properties to "build: content" and "copy if newer" everything works fine. However, I would prefer not to have this file in my output directory.
I work with VisualStudio Community 2013.
Is it maybe possible that VisualStudio cannot include a pdf file because it cannot compile it?
It's impossible. You can try to write the file from resources to %Temp% and open this File. But you can't control when an external program releases this file and deletes it.
I don't understand why I can read but cannot write to the file that is inside the project. When i selected release it appeared to write to the file, but on debugging mode it doesn't. When i use same function to write list into the file's lines to a different folder it worked always but not on the file that i want.
Example:
Function:
public void WriteLinesFromListToTextFile(List<string> listOfContent, string txtFileName)
{
StreamWriter writer = File.AppendText(txtFileName);
foreach (string Item in listOfContent)
{
writer.WriteLine(Item);
}
writer.Flush();
writer.Close();
}
and later
List<string> exampleList = new List<string>();
tmp.Add("line1");
tmp.Add("line2");
tmp.Add("line3");
WriteLinesFromListToTextFile(exampleList, "TextOnProjectRoot.txt")
In the file properties I selected "Copy Always" and also tried "Copy If Newer".
I ran VS as admin as well.
When I created the file it did copy it to the root folder but just didn't write to it.
I also want to state that there is no exception at all.
Thanks for any help
I'm a little unsure of what you are trying to archive, but I understand you this way:
You have a text file as part of you project. At runtime, you try to write some text to this file. When you application is closed, you expect to see the changes in the text file that's part of your project.
Am I right?
If so, I would guess the problem is as follow: When you first start your application, the text file that is part of your project is copied to the output folder together with your executable. The program runs, and the file is manipulated. But when the application closes, files are never copied back from the output folder to the project folder. That's just not how thing works...
If your program needs access to a file, and you don't specify a path, it uses the current location of the .exe. If this is good enough for your purposes then you just need to know that you can't add it to the solution; like Vegar said, it doesn't work that way. What you CAN do is compile your program, then browse to the folder where the .exe is (debug, release, or other) and run the .exe right from there, then open the text file and review your changes. If you need to create or ensure the file already exists, you can do that in the code as well. You won't be able to include it in your solution but you can still write to the file.
I added picture box to my form and import 2 pictures, from properties under image property i choose the first picture when the application starting and inside my start button event i want to change my picture to the other picture.
this is what i have try:
pbIndicator.Image = Image.FromFile(#"..\Resources\indicator_green.png");
but file not found exception error occurs.
You should be able to do something like this:
pbIndicator.Image = Resources.indicator_green;
Be sure that in the property window if the Build Action is on Content, and Copy to Output Directory is on Copy if newer.
If you want it to be content. Else use the answer Shadow Wizard gave.
As I wrote in the comment if indicator_green.jpg is an image included as resource via resource file (Resources.resx) then it won't be copied to output directory (it means it's in your project folder because it's used to build executable but it'll be embedded inside your assembly, not deployed standalone).
Resource files will (by default) place resources you add inside Resources folder (and then linked). You can always access them using generated code file for resources:
pbIndicator.Image = Properties.Resources.indicator_green;
You may change namespace Properties and property name according to what you have in your project (by default property name has the same name of the resource and then same name as original file).
Of course you're not forced to embed your resources in your assembly. If you want to deploy them as standalone files just right click Resources folder and add an existing file. In the properties window for that file select Copy always for Copy to output directory and et voila, you'll be able to read it with:
pbIndicator.Image = Image.FromFile(#"Resources\indicator_green.png");
Please note that Resources folder won't be a sub-directory of your output directory (do not forget that source files are not part of installation).
Anyway I suggest you do not build path like that, little bit better would be to do not rely on current folder:
pbIndicator.Image = Image.FromFile(
Path.Combine(Application.StartupFolder, #"Resources\indicator_green.png");
You're not limited to Resources folder, you can do that with any folder (and with any name).
I would like to embed a text file in an assembly so that I can load the text without having to read it from disk, and so that everything I need is contained within the exe. (So that it's more portable)
Is there a way to do this? I assume something with the resource files?
And if you can, how do you do it and how do you programaticaly load the text into a string?
Right-click the project file, select Properties.
In the window that opens, go to the Resources tab, and if it has just a blue link in the middle of the tab-page, click it, to create a new resource.
Then from the toolbar above the tab-page, select to add a new text file, give it a name, it will be added to your project and opened up.
If you get this far, then in your code you can type in Resources.TheNameYouGaveTheTextFileHere and you can access its contents. Note that the first time you use the Resources class in a class, you need to add a using directive (hit Ctrl+. after typing Resources to get the menu to get VS to do it for you).
If something was unclear about the above description, please leave a comment and I'll edit it until it is complete or makes sense :)
In Visual Studio 2003, Visual Studio 2005 and possibly earlier versions (this works in 2008 as well) you can include the text file in your project, then in the 'Properties' panel, set the action to 'Embedded Resource'. Then you can access the file as a stream using Assembly.GetManifestResourceStream(string).
Other answers here are more convenient. I include this for completeness.
Note that this approach will work for embedding other types of files such as images, icons, sounds, etc...
After embeding a text file, use that file any where in code like this...
global::packageName.Properties.Resources.ThatFileName
Here's what worked for me. (I needed to read contents of a file embedded into an executable .NET image file.)
Before doing anything, include your file into your solution in Visual Studio. (In my case VS 2017 Community.) I switched to the Solution Explorer, then right-clicked Properties folder, chose Add Existing Item and picked the file. (Say, FileName.txt.) Then while still in the Solution Explorer, right-click on the included file, select Properties, and pick Build Action as Embedded Resource.
Then use this code to read its bytes:
string strResourceName = "FileName.txt";
Assembly asm = Assembly.GetExecutingAssembly();
using( Stream rsrcStream = asm.GetManifestResourceStream(asm.GetName().Name + ".Properties." + strResourceName))
{
using (StreamReader sRdr = new StreamReader(rsrcStream))
{
//For instance, gets it as text
string strTxt = sRdr.ReadToEnd();
}
}
Note, that in this case you do not need to add that file as a resource as was proposed in the accepted answer.
Yes, you are correct - create a resource file. WHen you do that you don't need to "load" the string, it will be referenced as Resource.WhateverStringYouDefined.
Here is what I did:
Added my files (resources) in Visual Studio by right-clicking on the project.
Right click on every file you have added and change the "Build Type" to Embedded Resource.
In order to access the resource:
a. Got the current assembly using the function: GetExecutingAssembly()
b. The resource that I added was a text file so I read it into a stream using GetManifestResourceStream(fileName). The way I accessed the file names is by calling GetManifestResourceNames()
c. Now use a StreamReader() class to read to the end of file into a variable if that is what you want.
Adding to Pavan's answer, to get the current assembly (in general section):
Assembly _assembly;
GetManifestResourceStream(fileName)(in code, where the read from resource is required):
try
{
_assembly = Assembly.GetExecutingAssembly();
_textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("*Namespace*.*FileName*.txt"));
}
catch
{
Console.WritelLine("Error accessing resource!");
}
I'm trying to add images to my tree nodes (ImageList.Add()), but just can't figure out a nice way of doing it.
I've read from MSDN help I should use System.Drawing.Image.FromFile(path). But cannot just get a file somewhere.
I'm building a DLL, and want it to be a single file, no bitmaps being copied together with it.
So I've read I should add Image files to the project and mark them with Build Action as "Resource".
Ok, but where do I get them??? I saw people using it in XAML files, but I don't have that.
Saw people using Resources.SomeName, but can't find those Resources class.
So....How do I do it?? I've got the files marked as resources, just need to add them to the ImageList.
By the way, I'd love to use the path relative to the Code File that is adding the images to the ImageList. But if not possible, just relative to the assembly root.
If you want to use file paths, for items that are in your project, you must set the "Copy to Output Directory" property to "Copy Always" or "Copy if newer", otherwise it won't be in the bin folder, and then you'll be trying to pass a path to a file that doesn't exist. Build action isn't all that important in this scenario.
If you want to use compiled resources, and reference them via the Resources object, see the rest of my answer. I assume you are using Visual Studio, 2005 or later.
To add an image as a compiled resource to a clean Windows Forms project, so that you can access it via Resources.SomeName do the following:
In Solution Explorer, under the windows forms project (mine is called WinFormsApplication1), expand the "Properties" folder. By default this folder should contain: AssemblyInfo.cs, Resources.resx, Settings.settings.
Double-click on the Resources.resx file. This will open an editor for it. You'll probably see a table of strings, with columns "Name", "Value", "Comment".
Click the drop-down arrow on the "Add Resource" button, and select "Existing File", which will allow you to browse to the image you want to add.
You should now see the image appear in a gallery of sorts. Mine has the name TestImage
Now when you edit the code (mine is Fom1.cs), I can access the image as a System.Drawing.Bitmap as Properties.Resources.TestImage.
To my mind, this is the best way to do images that you want compiled into the application. If you want user-added images, you'll need to use OpenFileDialog, or something like that to get your file path. Then the Image.FormFile() will be what you want.