StreamReader Null Reference Exception - c#

Im trying to read SQL statement from .SQL files in a resource folder,
I have 2 .SQL files right now and it reads one correctly and the other returns a NullRefrenceException
Here is my calling of the sql files:
string sqlFailRecordNoMatch = EmbeddedResource.GetString("Resources.SQLScripts.RecordNumberFailQuery.sql");
Here is the GetString method:
public static string GetString(System.Reflection.Assembly assembly, string name)
{
System.IO.StreamReader sr = EmbeddedResource.GetStream(assembly, name);
string data = sr.ReadToEnd();
sr.Close();
return data;
}

The only reason you would get a NullReferenceException on one vs. the other is:
The one that's failing isn't set as an Embedded Resource. You can check that by clicking on the file in the Solution Explorer and hitting F4.
You're using the wrong fully qualified path.
I suspect it's #1.

It would be much easier if you simply use the resource editor from Visual Studio:
Within your project create a new folder (maybe called Queries)
Right click this folder and select Add - New Item
In the dialog just select Textfile and give it the name about what this query will do
Make sure you replace the file extension from .txt to .sql
Just put your statement right into this file
In the Resource Editor add this file as a resource (normally located in your project under the properties folder or simply also create it by Add - New Item - Resources File)
Now you can access this sql statement within your code just by using Properties.Resources.MySqlStatement

Related

Embedding Text File in Resources C#

I'm attempting to do two things. I want to embed a text file into my project so that I can utilise it and modify it, but at the same time I don't want to have to package it when I send the project out to users (I.E included in the exe file).
I've had a look around and there's been multiple questions already but I just cant seem to get any to work. Here's the steps I've taken so far;
Added the text file to my "Resources Folder"
Build action to "Content" and output directory to "Do not copy"
I then try to access the file in my code;
if (File.Exists(Properties.Resources.company_map_template))
{
MessageBox.Show("Test");
var objReader = new StreamReader(Properties.Resources.company_map_template);
string line = "";
line = objReader.ReadToEnd();
objReader.Close();
line = line.Replace("[latlong]", latitude + ", " + longitude);
mapWebBrowser.NavigateToString(line);
}
The MessageBox never appears which to me means that it cannot find the file and somewhere somehow I've done something wrong. How can I add the file into my project so I don't need to distribute with an exe whilst being able to access it in code?
I would use the following:
BuildAction to None (not needed)
and add your file to Resources.resx under files (using DragAndDrop from SolutionExplorer to opened Resources.resx)
Access to your Text:
using YOURNAMESPACE.Configuration.Properties;
string fileContent = Resources.company_map_template;
Then you're done. You don't need to access through StreamReader

avoid overwriting of file and content with each run or request with executable directory

Hello I’m trying to create directory folder with text document for my windows form application executable. Now I must make it available locally for other users.
I'm doing it this way:
string dir = "%ProgramData%\\MyAppName\\doc.txt";
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(Path.GetDirectoryName(dir));
var stream = File.CreateText(dir);
stream.Close();
}
and here is my access path from executable directory inside the code:
const string mypath = (#"%ProgramData%\MyAppName\doc.txt");
On the one stage of implementation I have also separate creation of document, but I almost sure that has no connection with problem, because creates it once and never overwrites if file exist, keeps content of text document with each new run of program, adding of data or request to it. Only if I delete it by hand, in this case creates new one:
if (File.Exists(mypath))
wordsTyped.AddRange(File.ReadAllLines(mypath));
and works perfect with local path to debug folder like this:
const string tetdb = ("doc.txt");
So code for executable must work same way, if directory, folder, file with content exist don't do nothing with it. But with code above, it rewrites everything with every request to it, not only with new run of program, with folder, text document and content inside.
but must be as follows: if folder is created once, if directory, file, document exist, no netter with code of executable, or with press enter, or it was already there. keep content inside the text document with every start of program or request to it of adding to it.
I've tried create only folder to executable path, to create text document separately as it shown above, but I got same result. So how to avoid this problem, what I'm doing wrong?
The test for !Directory.Exists is the cause of your problem.
You pass a filename to the method, thus the method returns false (a directory with that name doesn't exist).
This means that you always enter the if and calling File.Create over an existing file overwrite the content of the file
string file = "%ProgramData%\\MyAppName\\doc.txt";
if (!Directory.Exists(Path.GetDirectoryName(file)))
{
....
}

Argument Null Exception error when trying to create a Text File

Problem:
I am trying to create a text file from a web service (local host), but on creation it gets the null argument error for path location. Now I am still using 2012 and was under the impression the code I gave would return the path name, but just returns null.
Aim:
Create a new file if one doesn't exist.
Get the path of the file for future use.
Question:
What are the visual studio 2012 C# methods for creating a text file? I find allot of sources but the code doesn't seem to work with 2012.
My Code:
//Create a file name for the path
string path = System.IO.Path.Combine(CurrentDirectory, "textFile.txt");
//Check if it exist, if not then create the File
//This is the recommended code by Microsoft
if (!System.IO.File.Exists(path))
{
System.IO.File.Create(path);
}
Get the file path using Server.Map path
string FolderPath = Server.MapPath("~/App_Data");
string file = Path.Combine(FolderPath, "textFile.txt");
//Check if it exist, if not then create the File
//This is the recommended code by Microsoft
if (!System.IO.File.Exists(file))
{
System.IO.File.Create(file);
}
Also check if the IIS user have permission to write on that folder (Add permission to the application pool user)
If you are trying to write something on a txt file, these piece of code does. No need to create a file if it is not exist. These code will create a file automatically if it not exists.
public static void LogMessage(string sFilePath, string sMsg)
{
using (StreamWriter sw = File.AppendText(sFilePath))
{
sw.WriteLine(string.Format(#"{0} : {1}", DateTime.Now.ToLongTimeString(), sMsg));
}
}
Are you sure CurrentDirectory value is right?
If you want visit current Web Service root dir can use like AppDomain.CurrentDomain.BaseDirectory.

Access to Resources

I've C# project and it has Resources folder. This folder has some of txt files. This files have various file names.
I'm taking file names from any source as string variable. For example I have fileName string variable and test.txt file in Resources folder:
string fileName = "test.txt";
When I want to access this file as like below, I can:
WpfApplication.Properties.test.txt;
But, When I want to access it by this code, I can't.
WpfApplication.Properties.fileName;
I want to use fileName string variable and access this text file.
What can I do to access it?
Thanks in advance.
Edit :
I change form of this question:
I've string variable assigned any text file name. For example; I have a.txt, b.txt, c.txt, d.txt, etc.. I'm taking this file name as string variable (fileName) via some loops. So, I took "c.txt" string. And, I can access this file by code in below:
textName = "c.txt";
fileName = "../../Resources\\" + textName;
However, when I build this project as Setup Project and install .exe file to any PC, there is no "Resources" folder in application's folder. So,
../../Resources\
is unavailable.
How can I access Resources folder from exe file's folder?
You need to add a Resource File to your project wich has the extension .resx/.aspx.resx. You will then be able to double click on this file and edit the required resources/resource strings. To do this right click on Project node in Solution Explorer > Add > New Item > Resource File. Let us assume you have added a file called ResourceStrings.resx to the Properties folder and added a resource string with key name MyResourceString, to access these strings you would do
string s = Properties.ResourceStrings.MyResourceString;
I hope this helps.
I would strongly recommend you taking a look at: http://msdn.microsoft.com/en-us/library/aa970494.aspx
If your text files have build action set as Resource you can locate them in code like:
(assuming the file name is fileName and its located in Resources folder)
Uri uri = new Uri(string.Format("Resources/{0}", fileName), UriKind.Relative);
System.Windows.Resources.StreamResourceInfo info = Application.GetResourceStream(uri);
Then you can access info.Stream to get access to your file.

Bundle a folder with a .Net application

How can I bundle a folder with a one click application and reference those files/folders after?
Seems rather simple but I just can't figure out how.
As in, I had the file index.html in the folder UI and I wanted to package that with the application, then I want to get the stream for that file with the string "/UI/index.html" but instead of just index.html, an entire website.
Add the folder to your VS Project, right-click on it and select "embed as resource". That will make the files in the folder be embedded in the .NET assembly. To get the file contents in your program, you can use something like this:
public class ReadResource
{
public string ReadInEmbeddedFile (string filename) {
// assuming this class is in the same assembly as the resource folder
var assembly = typeof(ReadResource).Assembly;
// get the list of all embedded files as string array
string[] res = assembly.GetManifestResourceNames ();
var file = res.Where (r => r.EndsWith(filename)).FirstOrDefault ();
var stream = assembly.GetManifestResourceStream (file);
string file_content = new StreamReader(stream).ReadToEnd ();
return file_content;
}
}
In the above function I assume your files a text/html files; if not, you can change it not to return string but byte[], and use a binary stream reader for that.
I also select the files by file.EndsWith() which is enough for my needs; if your folder has a deep nested structure you need to modify that code to parse for folder levels.
Perhaps there is a better way, but given the content is not too large you can embed binaries directly into your program as a base64 string. In this case it would need to be an archive of the folder. You would also need to embed the dll used for unzipping that archive (If I understood correctly you want to have single .exe and nothing more).
Here is a short example
// create base64 strings prior to deployment
string unzipDll = Convert.ToBase64String(File.ReadAllBytes("Ionic.Zip.dll"));
string archive = Convert.ToBase64String(File.ReadAllBytes("archive.zip"));
string unzipDll = "base64string";
string archive = "probablyaverylongbase64string";
File.WriteAllBytes("Ionic.zip.dll", Convert.FromBase64String(unzipDll));
File.WriteAllBytes("archive.zip", Convert.FromBase64String(archive);
Ionic.Zip.ZipFile archive = new Ionic.Zip.ZipFile(archiveFile);
archive.ExtractAll("/destination");
The unzipping library is DotNetZip. It's nice because you need just a single dll. http://dotnetzip.codeplex.com/downloads/get/258012
Edit:
Come to think of it, as long as you write the Ionic.dll to the working directory of the .exe you shouldn't need to use the dynamic dll loading so I removed that part to simplify the answer (it would still need to be written before you reach the method it is in though).

Categories